Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
D39 = B — the security-fix lane, built and proven (2026-10-23)
Decision: architecture/09-update-architecture.md §3 decision 255 (the operator started the D39 brief ~12:00; R-1239
closed). Read before the work: 09 §3 decisions 13–17, 22, 25–26, 52 and §6.4 parts 4–7; 00-capability-map.md (the
B rows); 13-threat-model.md; runbooks/target-selection.md; runbooks/publish-train-rules.md.
Baselines at start: catalog cde26ab, controller 32e61d5 (0.340.0, global floor 06:41 UTC — read from the hub before
the first controller commit), felhom.eu 4b9b0af3. Machines: DooPlex (builds, the writer), demo-hp (9202 scratch; the
release on 9201), Tester 1, demo-felhom (release only). Not touched: ep0, any household box.
Venue
9202 was pointed at the drill catalog through its LOCAL mirror (tools/repoint.py, copied from
audits/burndown-3-2026-10-17/tools/, R-992 — no catalog credential on the box): repoint-drill.txt. The drill was
reset to live main (cde26ab) first. 9202's dashboard password is its own (REHEARSAL_2026_10_20_9202_PW; the
demo-hp one was refused — five failed logins hit the one-minute limit; operations/nodes.md corrected).
Part 2 — the lane on the old controller (9202 on 0.340.0)
| Step | Result | File |
|---|---|---|
| First try of the negative control | inconclusive — the install was refused before anything was made (Plex wants the drive itself as HDD_PATH); the walk gained --value |
P2-negative-try1-install-refused/ |
Negative control: FROM Plex 1.43.4.10903, TO busybox:1.36.1 (exits at once) |
failed — backing-up → … → verifying → undoing → undone after 335 s; Plex 1.43.4 back |
P2-negative/walk.txt, box-verdict-plex.json |
| The writer on that walk | refused: „the box walk is 'security' with verdict 'failed' — only a PROVEN box_walk.py --security walk is written" |
P2-negative/writer-refusal.txt |
| The walk: Plex 1.43.4.10903-e5521bd8c → 1.43.5.11029-6bf8af3f0 | proven — done in 36.9 s, no undo, no hold; pinned = installed = catalog = live compose = running = TO; digest sha256:01bdf0ad6d53198da4331540c1e73ab65db7a72e961fff97ecb0847d46055c5f (the registry's, re-read by the writer); soak 600 s, 60 samples, anon peak 10.7 % of 2 GiB (cgroup peak 11.5 %), 0 OOM kills, 0 restarts; seed: none (Plex's fixture is a NoRoute stub) |
P2-walk/ |
| Setup gate (unclaimed Plex) | a browser (Accept: text/html) → 302 to felhom.<domain>/__gate/start; a script → 401; the same after the update |
P2-walk/box-verdict-plex.json |
| The writer, into the DRILL only | wrote the security_fix entry: ids CVE-2026-96652/-96654/-96655/-96656; advisory Plex's notice https://forums.plex.tv/t/important-security-update-for-plex-media-server-v1-43-2-and-earlier/942319 (the one CISA KEV cites, all four added 2026-10-20 — cisa-kev-plex2shell.json, from CISA's own feed); fixed_in 1.43.3.10861; the gate accepts it with its WARN |
P2-walk/writer.txt; drill f46e1bc |
Old controller, night (POST /api/debug/backup/night-chain) |
[update-leg] plex: skipped — not_proven; Plex stays 1.43.4 (control: the same leg judged privatebin) |
P2-oldctl/2-night-chain-0.340.0.txt |
| Old controller, hand press | done in 25.7 s; Plex 1.43.5 at the step's digest; /identity 200 with 1.43.5 |
P2-oldctl/3-hand-press-0.340.0.txt |
How Plex was put back at 1.43.4 for Part 3: removed through the product (with its data); drill commit 42945c9
moved ONLY the compose's image line back to 1.43.4 (the ladder line untouched); a fresh install pinned 1.43.4; 17e0da0
reverted that commit, so the step is the head again and the badge read „Frissítés elérhető" (P3-newctl/0-…).
Part 3 — the new controller (0.341.0-rc.1 on 9202)
Controller 63dcccf (CI run 2264 / #471 success), image 0.341.0-rc.1 set by hand (9202's self-update is off). The
night chain: [update-leg] plex: step pressed …, [update-leg] plex: security fix CVE-2026-96652,CVE-2026-96654,CVE-2026-96655,CVE-2026-96656 taken (plex=…1.43.4… → plex=…1.43.5…), step ended done after 30.1 s; the summary line ends [security fix plex: … done]. Backup first: the update's precondition met by a
second-drive copy 0 s old, the undo copy of 2 named volumes (2.8 MiB), then the pin. /identity 200 with 1.43.5
(P3-newctl/1-…, 2-…).
Part 4 — release 0.341.0
Image 0.341.0 (sha256:8aa4ce60…c0bc) from 63dcccf; per-box floors on tester-1, demo-hp, demo-felhom (303
floor_set); all three ran 0.341.0 by 11:15:31 UTC. Box walk: 0 unhealthy, 0 restarting, 0 exited, 0 [ERROR] lines since
the start (126 / 135 / 141 [INFO] lines — the control); selfupdate „0.341.0 is up to date"; the https-only check passes
on every public name; the dashboard login works on demo-hp and Tester 1 (/api/stacks 200), the N100's /api/health
200 (P4-release/). The operator said yes in chat; the global floor 0.341.0 / MinAgent 0.158.1 was set at 11:24:47
UTC (303 floor_set; the running hub's page reads „Effective floor: v0.341.0 — source: DB"); the per-box floors
cleared.
Teardown (three layers)
- Machine (9202): Plex removed through the product (no plex container or volume left);
controller.yamlrestored byte-identical (cmp) and the catalog cache re-cloned from the live catalog (R-615); this run's saved copy deleted after thecmp; image0.341.0. 34 older saved copies from earlier sessions stay — filed R-1240. The drill repository keeps this run's commits as the record. - Host (demo-hp): nothing provisioned.
- Hub: the global floor 0.341.0 (the operator's yes); per-box floors cleared.
Observations
- FILED: R-1240 — 9202 holds 34 saved
controller.yamlcopies with the catalog token. - FIXED without a row: drill commits never reached a box pointed at the drill's local mirror (
box_walk.refresh_box_mirror); two stale catalog tests (9202 address, gate count + missing sibling in the shallow clone); Tester 1's guest moved.101→.148and the box walk had it typed (now read from the guest);operations/nodes.md(9202's password, Tester 1's address). - NOT-A-FINDING: the writer's own engine-major check is redundant with
check_entry(two layers on purpose; the test asserts the refusal);/opt/docker/stacks/plexkeeps the catalog's template files after a removal, as every catalog app's folder does (72); the demo-hp start WARNs „new field … requires manual configuration" come from code 0.341.0 did not change; a waiter of mine matched its own command line (a known trap, memorypgrep-waiter-matches-itself) and was stopped.