Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
6.9 KiB
REPORT — OS updates build step 1: the guest's Debian fast lane; decision 78; the infrastructure images — 2026-10-04
Architecture read: 11-os-updates.md (with C1–C12, §5.4.1, §7.1 — the design; it won wherever it differed from the
brief, see below), 03-host-agent.md, 07 §6.1, 09 §3 decisions 11/12/15/18, 08. Baselines (re-verified):
felhom.eu 1b74ddc0c9 (hub 0.129.0), agent 596238cc2e (0.139.0), controller 99a1497560 (0.290.0), catalog
917a779cca. Register 331, highest R-839. Rulings recorded first: 09 §3 decisions 78–80 (6ed79cd). Evidence: documentation/audits/os-guest-lane-2026-10-04/ (parts A–G).
The Part table
| Part | Result | Notes |
|---|---|---|
| A — the snapshot undo first (R-837) | done — and it FAILED: no snapshot is possible | PVE refuses any snapshot not named vzdump of a guest with host-path binds (mp8/mp9), as the agent's token (which has VM.Snapshot + VM.Snapshot.Rollback) and as root. By the brief's rule: no automatic undo built; the decision is in STATUS (R-842). Steps 2–5 (apply, roll back, re-apply) had nothing to roll back to; 9201 was brought current by the product's own leg in Part G. Thin pool unchanged. |
| B — the wrapper | done | felhom-os-apply (Python 3 stdlib), R1–R13, repair first, snapshot.debian.org fallback, log lines; host layer and slow lane refused. 35 tests; every refusal red-proved (13/13). visudo -cf OK. Changed: Python not shell (a JSON plan cannot be parsed safely in sh — so "shellcheck clean" became ast/compile-checked + the suite); one sudoers entry with a plan mode instead of a separate --repair-only. The route for existing boxes: none exists (R-840, with a proposal). |
| C — the agent's leg | done | After a successful primary whole-guest backup, under the heavy-op gate (red-proved: the gate is held), once per 20 h, 90 s settle. Health rule written and pinned (HealthVerdict). Report: full installed set with origins, pending, not covered, restart-needed. Debug action --selftest=os-update. 7 leg red-proofs + 2 hook red-proofs. |
| D — the hub | done — hub v0.130.0 | Rings, per-box switch (default ON), the candidate/approval rule (24 h + 1 night, config), approve-now, events, fleet JSON. 5 approval red-proofs; the os_update wire golden byte-identical in both repos. |
| E — household line + decision 78 | done | Line = hub customer event os_update_applied (info: on the household's timeline, not mailed; hu/en in the bundle). Changed: there is no box-side event surface, so the hub event is it (R-844). Decision 78 built in controller v0.291.0, red-proved both ways. |
| F — infrastructure images (R-838) | done | traefik v3.7.13, cloudflared 2026.9.3, filebrowser 1.5.6-stable; breaking changes named (none we use). A release moves all three (9202: ≤ 1.9 s / ≤ 1.5 s; demo boxes: public gap ≤ 19.6 s / ≤ 14.7 s incl. the controller restart). scripts/check-infra-pins.py + runbook section. Changed: the standing brief claude/MONTHLY-security-retest.md lives in the claude.ai project, not the repo — the repo half is the runbook; the project file is the operator's to update. 03 corrected (3 lines). |
| G — live proof | done, one part changed | Ring 0 on both boxes (53 packages each, healthy); approval with a 2-minute TEST wait (272 packages, auto), then the ruled values back; ring 1 on demo-felhom (exactly the 3 approved versions, nothing newer); a failed health check → health_failed, operator mail, household line. Changed: "show the rollback" — there is none (Part A). Teardown: no snapshot, no plan files, test config gone, demo-felhom back to ring 0. |
| H — release, golden, records | done (see Teardown for the golden) | Agent 0.140.0 (signed per box, both demo boxes on it), hub 0.130.0, controller 0.291.0 (floor 0.291.0, MinAgent 0.131.0 declared), installer 1.29.0. 11 §8.1, 00, 07 §6.1, 03 updated. |
Claims in the brief that turned out wrong (named)
- "The agent's token can snapshot and roll back" — it HAS the rights, but no snapshot of a customer guest is possible at all (bind mounts). Neither the token nor root can.
- "A snapshot rollback leaves the thin pool clean" — unmeasurable: there was no snapshot.
- "A new sudoers line can reach an installed box through the product" — false. Only the installer writes it; the signed agent update replaces the binary only (R-840). The demo boxes got the wrapper + sudoers BY HAND.
- "A controller release moves the infrastructure containers" — TRUE for all three. (I first wrote the opposite for the file browser and corrected it the same hour: its start-up mount sync renders the new image.)
- "An agent event can reach the household's timeline" — only through the hub (a hub customer event); the box has no timeline of its own (R-844).
- "Before each guest update, the box takes a snapshot" (the one-page summary) — impossible (Part A).
11vs the brief:11§5.4.1's--repair-onlyflag was folded into the plan;11's "a missed night waits" holds.
Found and fixed live (before the release)
--selftest=os-updatewas refused by the flag's allow-list — and so was--selftest=wgtunnel, since S3 (R-843, opened and closed; a new test pins every dispatched mode).- The wrapper logged an UPDATED conffile as "kept" (dpkg's two message shapes; fixed + tested).
- An app stopped between the inventory and the apply escaped the health check; the baseline is now the start of the leg (fixed + red-proved).
- My stopped-app test also made the box mail one
app_start_failed(a second one was held by the cooldown).
Rows
Closed: R-837 (measured), R-838, R-726, R-843 (opened and closed). Opened: R-840 (no product route to installed boxes, P2), R-841 (the agent's cloudflared probe reads a host unit that does not exist, P3), R-842 (the undo decision, waiting on the operator), R-844 (household line only on the hub, P4), R-845 (a pass takes 3–4 min, P4). Narrowed: R-812. Register 331 → 333.
Teardown, three layers
- Machines: no snapshot on either 9201; no plan files; privatebin restarted and healthy; demo-felhom back to ring 0;
both 9201s fully Debian-current (openssl at the approved u3). 9202 runs controller 0.291.0 (from Part F).
Kept on purpose: the wrapper + sudoers on both demo hosts (installed by hand; the old sudoers saved as
/root/felhom-agent.sudoers.bak-pre-osapply); agent 0.140.0 (signed update). - Host (DooPlex): helper scripts in the scratchpad only; the hub password copy shredded at the end.
- Hub: v0.130.0 at the ruled 24 h + 1 night (the TEST override reverted and the start log shows no override);
both demo boxes ring 0, ON; release
os-20261004-091417approved (it was approved under the TEST wait — ring 1 boxes will install it; every version in it already runs on both demo boxes). Floor 0.291.0.