diff --git a/CONTEXT.md b/CONTEXT.md index 2192e2c..358b631 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -7,7 +7,21 @@ > > Ask Claude Code: "Please update CONTEXT.md with what we did today" -Last updated: 2026-09-24 (v0.268.0 — the undo after a restore, option A, the ladder on the box) +Last updated: 2026-09-24 night (v0.269.1 — the whole restore from the second drive, the unhealthy stop, digests) + +> **2026-09-24 night — v0.269.0 + v0.269.1. Fleet floor 0.269.1 (MinAgent 0.131.0; needs hub v0.123.0).** +> `backup.RestoreTier2Whole` (`tier2_whole.go`, decision 26): `mergeRestoreFiles` by the four file rules +> (never delete; never an older file over a newer one; bring back missing; an older differing live file kept +> beside as `.felhom-`), then `RestoreFromRecoveryUnitAtWith(AcceptMissingFiles)` from the MIRROR; refuses +> before anything moves (not a file app / no proven openable mirror / < 2 GB). `sameDevice` fails CLOSED (R-668). +> Decision 27: `RemoveKeepsDataOnly` → 409 `err.stacks.remove_keep_data_while_support`; `keep_data_only` on +> hdd-data. Decision 28/29: `stacks.ObserveUnhealthy` (RestartCount delta ≥ 6 in 10 min, OOM ≥ 20 in 30 min) +> → `stopUnhealthyApps` → `HoldUnhealthy` (`unhealthy_stop`, trip 2 within 24 h) → `app_stopped_unhealthy`; +> Start lifts it. R-664/R-665: `entry.NewMeta` = the step's own `.felhom.yml`. §6.4 part 6 box half: +> `stacks/digest.go` — `RenderWithLadderDigests` for update + fresh install; **`CarryDigests` for an installed +> app's sync (v0.269.1, decision 30)**. Open next: R-669 (applied-meta after hold + restore), R-679/R-680 + +> part 7 (the update leg, `09` §6.4.2), R-681/R-682 (interrupted install/remove). Record: +> `felhom.eu/documentation/audits/DRILL-night-2026-09-24.md`. > **2026-09-24 — v0.268.0 (R-658, R-659, R-660, R-651; `09` §6.4 part 5). Fleet floor 0.268.0.** The undo > selects volumes with `DeclaredVolumeNames` (the compose definition), never the project label; the restore diff --git a/REPORT.md b/REPORT.md index 80a0de8..ef35c65 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,47 +1,31 @@ -# REPORT — controller v0.268.0 (2026-09-24) +# REPORT — controller v0.269.0 + v0.269.1 (2026-09-24 night shift, run in daytime) -Full record: `felhom.eu/documentation/audits/ladder-2026-09-24/README.md`. +Full record: `felhom.eu/documentation/audits/DRILL-night-2026-09-24.md` (evidence under `night-2026-09-24/`). +Architecture read: `09` §3 decisions 11–30, §6.4; `07` (the whole-copy table); `08` §6.2. -## Not done, or changed +## Shipped +- **v0.269.0** (`3c6b49b`): the second drive's whole restore for a file app (decision 26, R-661); the same-disk + check fails closed (R-668); keep-data-only Remove while support is informed (decision 27, R-666); the box stops a + crash loop / OOM storm, Start = one more try (decision 28, R-667, threshold decision 29); each step judged by its + own `.felhom.yml` (R-664, R-665); R-662 removed; digests rendered + the badge from the tested digest (§6.4 part 6). +- **v0.269.1** (`5b1b191`): `CarryDigests` — an installed app keeps its digest until a guarded Update (decision 30). + Found live in Part B; a second release in the session, on purpose. +- MinAgent 0.131.0 (unchanged). Needs hub v0.123.0. **Floor 0.269.1** set with the declared MinAgent; N100 + arrived (~16 s); demo-hp 9201 did not (read-only disks, R-672 — operator). -- The operator's English hold sentence lost „please" (house rule); Hungarian verbatim (R-516 ceiling 18 → 19). -- The hold names the newest whole copy, not a list of them (a list would need new copy). -- `TestR475_AdapterReadsEveryTier` asserted what R-659 changes on purpose; its assertion was replaced. -- `TestUndo_EveryPinWriterRecordsTheProbe` now checks `advancePinTo` (the writer moved there). +## Red-proofs (each seen failing, then passing; files in `night-2026-09-24/redproofs/`) +A1 file rules (three mutations: no newer-check → the newer copy overwritten; no keep-beside → the older copy gone; +no bring-back → the missing file not restored), R-668 (fail-open → the removed folder chosen), R-666 (the guard +removed → data deleted), decision 28 detector (the old clock → never trips) and its skips (a held/updating app +judged), hub routing, R-664 catalog gate + R-665 (the stack dir's file judged), digests (`B-digests.txt`), and +v0.269.1's carry (`B-sync-carry.txt`: "the sync MOVED the running digest"). -## Baselines +## Live (9202, endpoint level — no browser on DooPlex) +Whole restore: restored 1 / kept-newer 1 / unchanged 137, 3/3 volumes + 1/1 db, 38 s, account + files read +back; again from a hold naming the second drive; again in chaos rounds 3 (power cut) and 11 (disk + 1 GB). +Keep-data-only: 409 hu/en. Unhealthy stop: gokapi trip 1 → Start → trip 2 („support informed"), chaos rounds 1, +7, 8, 12. Digests: a floating tag's newer tested digest → badge → Update pulled it; on v0.269.1 the sync left the +running file alone. Full suite `go test ./...` rc=0 and `controller_gates.py` OK before each commit. -controller `80e6ad8c4772` (v0.267.0) → **`206b035`** (v0.268.0). MinAgent 0.131.0 (unchanged). Needs hub v0.122.0 -for `app_hold_no_whole_copy`. - -## What shipped - -- **R-658:** `DeclaredVolumeNames` + `appVolumes` (definition selects, label cross-checks); restore creates labelled - volumes (`composeVolumeLabelArgs`); `appVolumeSet` for the remove report. -- **R-659:** `backup.WholeOnTier`, `HoldCopies`, `HoldAfterFailedUpdateWhole`, `HoldNoWholeCopy`; `RestoreHold.NoWholeCopy` - + `CopiesSeen`; `hold.update.no_whole_copy` (hu + en); Mentések button gated on both pages; `NotifyAppHoldNoWholeCopy` - (critical) from the held-event sink; the held event's copy details now name the hold's copy. -- **R-660:** `backup.UpdateHeldStacks` + `updateHeldSet` unioned in `scanDeployedAppRunStates`. -- **R-651:** remove deletes `applied-compose.yml` and `applied-meta/`. -- **Ladder (`09` §6.4 part 5):** `stacks/ladder.go` (`LoadLadder`, `StepKey`, `StepFile`, `nextLadderStep`, - `ladderStepsLeft`); `advancePinTo(src)`; `Stack.LadderStepsLeft`; the app page's steps line - (`app_info.ladder_steps_left`, parity fixture `app_info_ladder_steps`). - -## Tests (new) and red-proofs - -`r658_undo_volumes_test.go` (3), `r658_restore_labels_test.go` (2), `r651_r658_remove_test.go` (2), -`r659_whole_copy_test.go` (9-case table + 2), `r659_held_page_test.go`, `r659_no_whole_copy_test.go`, -`r659_wiring_test.go`, `r660_held_not_down_test.go` (2), `r660_update_held_test.go`, `ladder_test.go` (6). Every -correctness test red-proofed — mutation and failing line in the audit's table. Green: `go build/vet/test` rc 0 -(31 packages); `controller_gates.py` all OK. - -## Deployed - -9202 (scratch) by hand at 06:16Z; fleet by floor 0.268.0 at 06:47:13Z — demo-felhom and demo-hp healthy at +30 s. - -## Live-validated (9202, endpoint-level) - -A (undo after a v0.267.0 restore: 2 volumes copied by name, A+B read back; v0.268.0 restore labels), B (round 11: -sentence hu/en, no button on either page, event line), C (no `app_start_failed` for the held app; control fired; -applied files gone), D (romm two presses, two steps). **Not live-validated:** the event's delivery through a real -hub (9202 has none — the R-620 line is the observable); an engine step that FAILS and is undone. +## Found (rows) +R-669, R-670, R-671, R-674, R-675, R-677, R-678, R-679, R-680, R-681, R-682, R-683 (controller); R-676 (watch).