86c4b9a0d8
gates / gates (push) Successful in 27s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
107 lines
8.9 KiB
Markdown
107 lines
8.9 KiB
Markdown
# 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.yml` was 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 → labels `project`/`volume`/`version`, no compose warning
|
||
(`partA/02`). Remove → `volumes_removed` names 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_failed` for
|
||
the held app in ~12 min; a throwaway stopped out of band raised one (`partB/03`, `06`). Remove: `applied-compose.yml`
|
||
and `applied-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-upgrade` 11.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/docker` 27 % → 18 %), no prune. `controller.yaml` restored from `controller.yaml.pre-ladder0924`, git
|
||
URL read back as the live catalog, cache at live `5ed599c`. **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 `main` `5ed599c`, `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**.
|