evening Part B: R-304 runbook + close, R-836 closed, R-528/R-435 dated, R-330 wire half closed; R-935 filed (core.bare flips)
gates / gates (push) Successful in 6m11s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
d
2026-10-12 16:45:24 +02:00
parent 225afa0f30
commit 186f3aa34e
3 changed files with 81 additions and 8 deletions
+9
View File
@@ -26,6 +26,15 @@
---
## 2026-10-12 (evening) — the evacuated disk, delivered rows, small fixes
The full text of the rows below: `git show 6c2c3dd574:documentation/backlog/OPEN-ITEMS.md`. Evidence: `documentation/audits/answers-2026-10-12/` unless a row names another place.
| Row | What | Closed | Evidence |
|---|---|---|---|
| **R-304** | **The retained escrow key works, and the customer is told their correct code is wrong.** (P2) | CLOSED 2026-10-12 — **done.** The operator mail (`recovery_older_package`, operator-only, decision 183) and the honesty fix are released: controller `a40729a` and `75b3b39` are in 0.308.0 (running on demo-hp, demo-felhom, Tester 1); agent `91b9405` is before the 0.154.0 release commit `24ea960` (running on the three boxes); the hub lists the event operator-only. The last slice, the runbook, is written: `runbooks/RUNBOOK-open-retained-package.md` (from the 2026-08-12 drill §3.5–3.6: the household types its code on its own box, the password checked by hash, restore into a new folder, clean-up). | git ancestry read 2026-10-12; `runbooks/RUNBOOK-open-retained-package.md` |
| **R-836** | **A new host kernel that hangs before userspace stays the GRUB default: `--next-boot` is not a one-shot on these hosts.** (P2) | CLOSED 2026-10-12 — **the harm is gone by design and by the nights since.** The kernel lane (agent 0.152.0+, hub 0.143.0+, `11` §5.11) pins the GRUB default to the RUNNING kernel before an install and boots the new kernel ONCE from an ESP flag cleared before the menu, with lockup→panic on that entry; so a hang or a power cycle comes back on the old kernel, and only a healthy boot moves the default. Read back: demo-felhom booted -22 then -23, demo-hp booted -23 on 2026-10-11 („kernel step — applied … healthy 1m58s"). Accepted by decision 172: a frozen new kernel that needs a person's power cycle. | `architecture/11-os-updates.md` §5.11; `audits/kernel-night-2026-10-08/readback/`; the 2026-10-11 read-back (STATUS) |
## 2026-10-12 (afternoon) — the operator's 38 answers (sheet S1–S38): the rows that need no code
The full text of the rows below: `git show 25ab47eeaa:documentation/backlog/OPEN-ITEMS.md`. Evidence: `documentation/audits/answers-2026-10-12/` unless a row names another place.
File diff suppressed because one or more lines are too long
@@ -0,0 +1,63 @@
# RUNBOOK — open a retained escrow package for a household (R-304, design option C, second slice)
> **When:** the hub mailed you `recovery_older_package` — a household's recovery code opens (422), or may open (424),
> an OLDER sealed package that the hub keeps as retained custody (R-222), and the household asked for data from that
> older off-site store. The product has no path to a retained package (R-312: reopening old history is
> operator-only). This is that path, written down from the drill that proved it end to end
> (`audits/DRILL-retained-key-2026-08-12.md` §3.5–3.6; memory note „opening an escrow blob by hand").
>
> **Promise:** none new. The household's dashboard says „contact support"; this is what support does.
## Rules for the whole procedure
- **The household types its recovery code, on its own box.** You never ask for it in a mail or chat, and it is never
on a command line or in a file outside the box's `/mnt/` work folder (deleted at the end).
- **Nothing is printed.** A recovered password is verified by its SHA-256 against the hub's record, never shown.
- **Restore into a NEW folder**, never over the household's live data. The household moves files afterwards.
- One package, one session; do it with the household present (phone or screen-share). Write what you did in the
household's support log.
## 1. Find the package (DooPlex, read only)
1. Snapshot the hub database **with its `-wal` and `-shm`** (a copy of `hub.db` alone can be hours stale).
2. In the copy: `SELECT id, host_id, length(identity_blob), restic_pw_sha256, superseded_at FROM host_escrow_superseded
WHERE host_id='<host>' ORDER BY superseded_at DESC;` — the mail names the box and the date; pick that row.
3. Write the blob out with `writefile` (never `SELECT` a BLOB to a terminal):
`SELECT writefile('/tmp/<host>-<id>.age', identity_blob) FROM host_escrow_superseded WHERE id=<id>;`
4. Note the row's `restic_pw_sha256` — the check value for step 3.
## 2. Bring it to the box
1. Copy the blob into the household's guest under **`/mnt/felhom-retained-<date>/`** (bind-mounted into the
controller container at the same path — `restic` lives INSIDE the `felhom-controller` container, and a path under
`/root` is invisible to it).
2. Copy the drill's pty wrapper (a ~30-line Python `pty.fork()` that runs `age -d -o <out> <blob>` and answers the
passphrase prompt) to the same folder. `age -d` will not read a passphrase from stdin; it needs the pty.
## 3. The household unseals it
1. The household types the recovery code (the ten words) into the wrapper's prompt on its box. A wrong code fails
closed at the scrypt step — no partial output.
2. The output is the identity bundle. Take `restic_repo_password` from it into a 0600 file in the same folder.
3. **Check it:** `sha256sum` of the trimmed password must equal the row's `restic_pw_sha256` (step 1.4). If not:
stop — wrong package or wrong code.
## 4. Read the old store
1. Mirror the controller's off-site arguments (`controller/internal/backup/offbox.go`, `offboxBaseArgs`): the sftp
backend with the box's own `known_hosts` and `ssh_key`, and `RESTIC_PASSWORD_FILE=/mnt/felhom-retained-<date>/pw`.
Run it as `docker exec felhom-controller restic …`.
2. `restic snapshots` — the household picks the snapshot (date, app tag).
3. `restic restore <snapshot> --target /mnt/felhom-retained-<date>/restore --include <what they need>`.
4. Show the household the restored files. They move what they want into place through the dashboard's file tools
or their share.
## 5. Clean up — always, also after a failure
1. `shred -u` the password file, the bundle and the blob copy; remove `/mnt/felhom-retained-<date>/` once the
household has its files.
2. Delete the hub DB copy on DooPlex.
3. Note in the household's support record: the date, the package id, the snapshot, what was restored. No secret.
**Negative control used in the drill:** the box's CURRENT password against the old store → `Fatal: wrong password or no
key found`. If you are unsure which store you are reading, run that first.