Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-24 — the fleet to 0.267.0 and 0.268.0; the undo after a restore; option A; the ladder on the box
Architecture read first and named: architecture/09-update-architecture.md (§3 decisions 13–25, §6.1, §6.1a,
§6.4 parts 4–5), 07-backup-architecture.md §6, 08-alarm-ladder.md §5. Method: endpoint-level — every
product act is the endpoint the UI invokes; pages fetched as HTML in both languages (?lang=); no browser.
Scratch guest 9202 on demo-hp (Tier 0), drill catalog for every failing edge; the live catalog carried only
the step files and gates.
Not done, or changed
- Nothing not done. Parts 0, A, B, C, D and E all ran; the interim "one step per app per day" gate was not needed (Part D shipped).
- The operator's English sentence lost one word, „please" — the house rule (
i18n_missing_gate.py,EN_FORBIDDEN) refuses it. The Hungarian is verbatim; its formal register raised the R-516 ceiling 18 → 19 with the reason written beside it. - The hold names ONE copy (the newest whole one), not a list. A list would need new sentence copy; the existing sentence names one copy with what it holds.
- Part A's second failing update (g) did not fail: right after a restore the stack dir's
.felhom.ymlwas the restored one (real probe port), so that press was a good update. The proof the brief asks for is (e) — an app restored under v0.267.0, then a failing update on v0.268.0 — and it passed. (g) still shows the v0.268.0 restore's volumes copied with no "unlabelled" warning. Filed as R-665 (not diagnosed). - R-653 and R-656 are unit-tested and red-proofed, not run on a bench — no bench was provisioned this session.
- Two catalog test suites were already red at the start (
test_gate_decoys.py,test_ladder_writer.py— last night's pin moves under literals). Fixed and filed as R-663 (closed). - One of the first R-660 control's two alarm events is not attributable (the dropped-event line names no app); the repeat control produced exactly one. Likely gokapi (R-667), stated as inference.
- An older wiring test (
TestR475_AdapterReadsEveryTier) asserted the adapter hands the hold the precondition copy — the thing R-659 changes on purpose. Its assertion was replaced, with the reason in the test.
Claims in the brief, checked
| the brief's claim | what was found |
|---|---|
compose resolves volume names as <project>_<volume> for every template (some set name:) |
No template sets name:, top-level or per volume (all 53 read). Supported anyway, and tested. |
the syncer can carry a steps/ folder |
It does not need to. The syncer copies two files into the stack dir; the box reads steps/ from its catalog CLONE, which (depth 1) holds the whole tree. Measured on 9202: steps/spike-B.yml present in the clone after one sync (partD/01). |
„saját meghajtó" never holds files for a file-leg app (from 07 §6) |
Held, and it goes further: read from source, the SECOND-DRIVE unit restore refuses such an app too (the R-538 guard is in the shared function), and the second drive's file restore brings back no database. So only off-site brings a file app back whole (R-661). An app with only OPTIONAL legs (romm, komga, audiobookshelf) is accepted by the unit restore. |
| one press = one step is safe for an engine step whose datadir converts | Held for MariaDB, measured once: romm press 2 ran mariadb-upgrade 11.4.13 → 11.8.9 and the account read back. The undo copy covers the pre-conversion volume if the step fails (not exercised on an engine step this session). PostgreSQL majors stay refused (part 10). |
| today's press jumps A → C | Held on v0.267.0: vikunja 2.4.0 → 2.6.0 in one press, 2.5.0 never ran (partD/00-spike.json). |
Part 0 / Part E — the floor
| save (UTC) | floor / MinAgent | read back | demo-felhom | demo-hp |
|---|---|---|---|---|
| 05:12:14 | 0.267.0 / 0.131.0 | min_controller_version=0.267.0, min_agent=0.131.0; hub SERVED … from declared |
0.267.0 healthy at +28 s | same |
| 06:47:13 | 0.268.0 / 0.131.0 | same shape | 0.268.0 healthy at +30 s | same |
Hub 0.122.0 rolled out first (ArgoCD, manifest 500488c, pod image read back). Stays below: drill-r50
(DOWN, agent 0.129.0 — held by MinAgent, a Tier-0 leftover). Evidence part0/.
Red-proofs (each seen failing, then restored)
| row | mutation | failed at | file |
|---|---|---|---|
| R-658 undo | appVolumes returns the label selector |
copied 0 of 2 declared volumes |
redproofs/A-r658-undo.txt |
| R-658 restore | create without labels | created vikunja_files WITHOUT the project label |
A-r658-restore.txt |
| R-658 remove report | appVolumeSet = labelled only |
volumes_removed = [] |
C-r651-and-A-remove-report.txt |
| R-651 | skip deleting the applied files | both files survive; undo would probe the REMOVED install's file | same |
| R-659 hold | WholeOnTier always true |
round-11 case names „saját meghajtó" | B-r659-hold.txt |
| R-659 page | gate dropped from stacks.html |
Mentések button beside a no-whole-copy hold | B-r659-page.txt |
| R-659 hub | dropped from operatorOnlyEvents |
"must be operator-only" | B-hub-operator-only.txt |
| R-660 | updateHeldSet returns nil / union line removed |
"held app reported DOWN" / wiring | C-r660.txt |
| ladder (box) | nextLadderStep always the template |
press 1 pinned C; C brought up after B failed; missing step file → done |
D-ladder.txt |
| ladder (catalog gate) | rule 4 removed | 3 decoys pass wrongly | D-catalog-gate.txt |
| ladder (writer) | STEP block off | "has no definition" / file absent | D-catalog-writer.txt |
| R-653 / R-656 | load_verdict always reached / no removal |
ghost's all-err watch reads reached; last run's config survives |
C-r653-r656.txt |
Green: controller go build/vet/test rc 0 (31 packages); controller_gates.py all OK; hub go test OK +
repo_gates.py OK; catalog catalog_gates.py OK, decoys 84 OK, writer 6 OK, bench 5 OK.
Live proofs on 9202
- A (R-658) — v0.267.0: vikunja installed, a pull-failing update took its own backup, restore from „helyi" →
both volumes' labels
null(partA/01). v0.268.0: failing update (2.5.0 → 2.6.0, probe 8999) → log „carry no compose label … copied by name", „will hold 2 named volume(s)", undone in 7 s, seeds A (before) and B (after the restore) read back. v0.268.0 restore → labelsproject/volume/version, no compose warning (partA/02). Remove →volumes_removednames both. - B (R-659) — nextcloud installed at ladder step 1, seeded; failing update with the undo copy's marker removed
during
verifying→ HELD,hold_no_whole_copy: true; the sentence in hu and en exactly as ruled (ASCII fragments, positive and negative control); no Mentések button on the app page or the list, both languages; log „NO copy on this box brings it back whole (seen: tier 2 …, tier 1 …; drive files declared: true)" and „DROPPED event app_hold_no_whole_copy (severity critical)" (R-620's line). Steps line „… lépések: 1" (partB/01). - C (R-660, R-651) — dead-app heartbeat 2 s after the hold: „0 currently down"; no
app_start_failedfor the held app in ~12 min; a throwaway stopped out of band raised one (partB/03,06). Remove:applied-compose.ymlandapplied-meta/present before, gone after; every undo copy gone (partB/07). - D (the ladder) — romm installed at 5.3.0/11.4, seeded; the page read „Hátralévő frissítési lépések: 2" /
"Update steps remaining: 2". Press 1 → „ladder — step 2 of 3 … from 90dd9d68258286ef.yml", pin 5.3.1/11.4,
applied == that step file, MariaDB „upgrade not required", account read back, count 1. Press 2 → „the last step
(3 of 3)", pin 5.3.1/11.8,
mariadb-upgrade11.4.13 → 11.8.9, account read back, count gone (partD/10). A second seed after press 1 was refused by RomM (403 for a non-admin) — the readback rests on seed A.
Teardown — three layers
- Machine (9202): vikunja, nextcloud, romm, actualbudget ×2 removed THROUGH THE PRODUCT; 0 volumes, 0 undo
copies; drive folders nextcloud/romm removed by name (R-442 keeps them on 9202); 11 test images removed by name
(
/var/lib/docker27 % → 18 %), no prune.controller.yamlrestored fromcontroller.yaml.pre-ladder0924, git URL read back as the live catalog, cache at live5ed599c. 9202 stays on v0.268.0. Standing apps as found (gokapi was crash-looping before the session — R-644/R-667). - Host (demo-hp): no guest created; nothing else touched.
- Hub: no customer or appliance record created. Floor 0.268.0 is the intended end state.
- Drill repo: reset to live
main5ed599c,has_actions: False, private — read back.
Rows
Closed: R-658, R-659, R-660, R-651, R-653, R-656, R-40 (superseded), R-663 (filed and fixed). Opened: R-661, R-662, R-664, R-665, R-666, R-667. Narrowed: R-450 (part 5 shipped). Register 336 → 335 rows, 683,233 → 679,393 bytes.