09 §6.4 parts 2-3 SHIPPED. R-606, R-620, R-646 closed; R-647 (three leftovers) and R-648 (whole-box backup press in the harness) opened. Open rows 335 -> 334. Evidence: audits/undo-fleet-2026-09-23/. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
8.7 KiB
REPORT — the undo reaches the fleet, and the household is TOLD (controller v0.264.0, hub v0.120.0)
2026-09-23 (evening). Repos touched: felhom-controller (v0.264.0, bc27894), felhom.eu (hub
v0.120.0 d3b2848, manifest 7caa24f, docs, register, evidence), admin/app-catalog-drill (drill
commits, reset to live main at the end). felhom-agent, app-catalog-felhom.eu: untouched.
Architecture read and named: documentation/architecture/09-update-architecture.md (§3 decision 15,
§6.4). Evidence: documentation/audits/undo-fleet-2026-09-23/README.md. Method: endpoint-level
(the endpoints the UI invokes; mails read from the catch-all mailbox; no browser).
1. Not done, or changed
| item | state |
|---|---|
| Part 0 — floor 0.263.2 | done, read back (00-floor-0.263.2.txt) |
| Part 1 — R-646 startup pass | done; live: 3 recorded on 9202, 10 on 9201, 0 skipped |
| Part 2 — two events, hub v0.120.0 first | done; hub deployed 11:49Z, before any box ran v0.264.0 |
| Part 3 — R-606 | done, with leftovers → R-647 (a reader in the other language than the box sees a HELD sentence in the box's language; the English mail's raw Note: line keeps the Hungarian copy_holds phrase) |
| Part 4 — R-620 | done |
| Part 5 — live proof | done; all proofs passed → floor raised to 0.264.0 |
| "standing apps untouched" | NOT fully met. The harness's „Mentés most" is a whole-box backup: on 9201 it stopped and restarted 9 of the 10 standing apps for their volume dumps, twice (a few seconds each). All healthy afterwards, files byte-identical. R-648 filed. |
| the brief's Hungarian undone line | changed: it ends „semmi nem veszett el, nincs teendőd." — the brief's „teendője nincs" is the formal „ön" voice; the product speaks „te" everywhere and the voice gate ratchets the formal form (18). |
| the customer cooldown | changed shape: a NEW customer-side register (perAppCustomerCooldownEvents) instead of putting the customer leg of R-389's register to work — that would also have changed app_start_failed's household grain, which nobody asked for (pinned by a test). |
| a box-side seed + two page toggles | added, not in the brief: the box pushes its own EnabledEvents to the hub on every notifications-page save, so the hub migration alone would be undone by the next save. |
Claims in the brief, checked:
- "No app-update event exists today" — true for apps. The only near-misses:
controller_updatedis the controller's OWN self-update, andupdate_availableexists only as a debug-page test option — never emitted, and not in the hub's allow-list (it would 400). - "
enabled_eventsis the household's only mail gate" — wrong. Four more gates stand in the way: theoperatorOnlyEventsregister, a blocked customer, a missing e-mail address, and the cooldown — keyedcustomer:type, which would have merged two apps' mails into one. And the box OVERWRITES the hub's list on each page save (above). - "9201 can follow the drill catalog without disturbing its standing apps" — true for the catalog,
false for the harness. Measured: the 10 standing apps' compose +
.felhom.ymlwere byte-identical before, during and after (the drill differed from live only in the throwaway apps). The disturbance came from the harness's whole-box backup press (R-648), not from the catalog.
2. Floor raises, read back from the hub
| raise | read back | fleet |
|---|---|---|
| 0.263.2 / MinAgent 0.131.0 | min_controller_version=0.263.2, min_agent=0.131.0 |
00-floor-0.263.2.txt |
| 0.264.0 / MinAgent 0.131.0 (14:35:08) | min_controller_version=0.264.0, min_agent=0.131.0; hub log managed floor SERVED for demo-felhom: floor 0.264.0 … from declared |
demo-felhom 0.263.2 → 0.264.0 in 20 s; demo-hp 9201 already 0.264.0 (50-floor-0.264.0.txt) |
3. The hub migration — rows changed (one-time, add-only)
| customer | before | after |
|---|---|---|
demo-felhom |
10 types | the same 10 + app_update_undone, app_update_held |
demo-hp |
null (nothing on) |
["app_update_undone","app_update_held"] |
_resend-rotation-test |
[] |
["app_update_undone","app_update_held"] |
Guard row seed_app_update_events_v1 = 2026-09-23T11:49:03Z. E-mail column never selected.
4. The mails (9201, customer demo-hp) and their notification_log rows
| row | time (UTC) | type | leg | subject as received |
|---|---|---|---|---|
| 937 / 938 | 12:15 | undone | op / household | op ⚠️ demo-hp: app_update_undone · hh Figyelmeztetés: vikunja: a frissítés nem sikerült, az alkalmazás a korábbi változattal fut |
| 939 / 940 | 12:16 | held | op / household | op 🔴 demo-hp: app_update_held · hh Hiba: vikunja: az alkalmazás leállítva, visszaállítás szükséges |
| 942 / 943 | 12:29 | undone | op / household | hh Warning: glance: the update did not work; the app runs on its previous version |
| 944 / 946 | 12:31 | held | op / household | hh Error: glance: the app is stopped and needs a restore |
All 8 sent. The box language was switched to English once, between the two rounds (the hub had two
reports in English before the second round). Household bodies carry the box's own sentence (the undone
line / the hold sentence) in the household's language; the operator's carry the Hungarian wire text.
Verbatim bodies: 41-mails-as-received.md. Per-app cooldown, live: row 943 went out 14 minutes after
row 938, inside the 6-hour customer cooldown.
5. The pages in both languages (9202, then 9201)
- undone: hu „A(z) vikunja frissítése 2026-09-23 14:00-kor nem sikerült. A doboz automatikusan visszaállította az előző változatot és az adatokat — semmi nem veszett el." · en "The update of vikunja at 2026-09-23 14:00 did not succeed. The box put back the previous version and its data automatically — nothing was lost."
- held, box hu:
?lang=hu→ the Hungarian hold sentence;?lang=en→ "The update did not succeed, and the automatic undo did not either. … own drive, 2026-09-23 13:58 — this copy holds the settings, the database and the data volumes." — the whole sentence English now (before v0.264.0 only the prefix was). GET /api/stacks/vikunja?lang=en: label "The update did not succeed", error and hold in English.- Leftover (R-647): box en +
?lang=hushowed the English hold.
6. Red-proofs (each seen failing, then restored)
Controller (9): backfill stores nothing → TestR646_… "the current app must have its record";
dropped() not called → TestR620_… "want exactly TWO WARN lines, got 0"; undone event not emitted →
"exactly ONE app_update_undone event, got []"; held event not emitted → "…got []"; page
updateErrorText not localised → TestR606_UpdateSentencesFollowTheReader; hold sentence ignores the
language → undo_hold_test.go:62; UpdateErrorIn returns the Hungarian → "English = „A frissítés nem
indult el…""; box seed not run → "got [backup_failed offbox_enlarge_blocked]"; sink not wired in main →
"SetUpdateEventSink is never called" (first mutation did not compile; retried with a compiling one).
Hub (5): seed call does nothing → "c1: enabled_events = [backup_failed], want […]"; customer per-app
suffix removed → "want 3 household mails …, got 2"; allow-list entry removed → "must be in
allowedEventTypes"; app-named headline removed → subject "%s: a frissítés…"; seed default removed →
"defaultSeedEvents must include app_update_undone" (first attempt matched no test; retried with a new
test that names both types). Every -run was checked for === RUN.
Gates: controller go test ./... rc=0, controller_gates.py rc=0; hub go build/vet/test rc=0,
repo_gates.py rc=0. The R-389 fence test was widened on purpose, with its reason; the settings-page
parity fixture was regenerated (measured diff: exactly the two new toggles).
7. Rows
Closed (3, moved to CLOSED-ITEMS.md): R-606, R-620, R-646. Opened (2): R-647 (the three
leftovers), R-648 (the whole-box backup press). Open rows 335 → 334. 09 §6.4 parts 2 and 3 marked
SHIPPED; the capability map's undo row now carries the mail; STATUS rewritten.
8. Teardown — three layers
- machine: 9202 and 9201 — throwaway apps removed through the product (0 volumes, 0 undo copies),
test images removed,
controller.yamlidentical to the saved copy, catalog on livecfcfe52, 9201's language back tohu, standing apps deployed and healthy. Both on 0.264.0 (= the floor). - host: nothing provisioned on demo-hp.
- hub: v0.120.0 (planned); floor 0.264.0. Scratchpad password files deleted; hub DB copies deleted.
- drill repo: reset to live
main, read back from the remote.