diff --git a/CONTEXT.md b/CONTEXT.md index 8f574be..2192e2c 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -7,7 +7,19 @@ > > Ask Claude Code: "Please update CONTEXT.md with what we did today" -Last updated: 2026-09-23 (v0.267.0 — tests off DooPlex's Docker, cut-off copies refused) +Last updated: 2026-09-24 (v0.268.0 — the undo after a restore, option A, the ladder on the box) + +> **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 +> labels volumes (project/volume/version, no config-hash). The hold names the newest WHOLE copy +> (`backup.WholeOnTier` = the restores' refusal predicate `DeclaredDriveFileLegs`; off-site only for file apps) +> or, with none, `hold.update.no_whole_copy` + no Mentések button + `app_hold_no_whole_copy` (needs hub +> v0.122.0). `UpdateHeldStacks` is the fourth app-down suppression. Remove deletes `applied-compose.yml` + +> `applied-meta/`. The ladder: `stacks/ladder.go` — `nextLadderStep` picks the NEWEST entry whose `from` is +> the pin; a non-head step pins `catalog-cache/templates//steps/.yml`; missing/wrong → +> `update.error.pin_failed` before anything moves; no match → template, logged. `LadderStepsLeft` on the +> page. Open next to it: R-661 (Tier-2 no whole action), R-664 (a step has no .felhom.yml), R-665, R-666, +> R-667 (crash-loop clock resets on a flapping container). > **2026-09-23 (night) — v0.267.0 (R-650, R-640, R-499, R-518).** Every docker exec goes through > `internal/dockerexec`; under `go test` a real docker is refused (opt-in `FELHOM_TEST_REAL_DOCKER=1`; a diff --git a/REPORT.md b/REPORT.md index 77b3cb0..80a0de8 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,43 +1,47 @@ -# REPORT — controller v0.267.0: tests off DooPlex's Docker, cut-off copies refused, two pages true (2026-09-23) +# REPORT — controller v0.268.0 (2026-09-24) -Night shift 2026-09-23, Part A. R-650, R-640, R-499, R-518; R-626 measured. MinAgent 0.131.0 (unchanged). -No hub change. Full night record: `felhom.eu/documentation/audits/DRILL-night-2026-09-23.md`; evidence -`felhom.eu/documentation/audits/night-2026-09-23/A*`. +Full record: `felhom.eu/documentation/audits/ladder-2026-09-24/README.md`. ## Not done, or changed -- **R-518:** the brief said the page promises „csak néhány másodpercre". It does not — v0.243.0 removed - that. The remaining vague „általában néhány perc" is replaced by the measured ~8 minutes. -- **R-626:** not reproduced, so not "fixed" — closed by measurement (below). -- R-640's "narrowed" scope held: the undo copies folders; only the three restore paths load dumps. + +- 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). + +## Baselines + +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-650:** `internal/dockerexec` (`Command`/`CommandContext`/`RunWithStub`). 77 docker exec sites routed - through it. The sweep (trace of the guard's refusals, `A1-r650-sweep.txt`): `web` 67× `docker compose - version`, 19× `docker ps`, 19× `docker info`, 10× `docker inspect felhom-samba`, 2× `docker exec - felhom-samba`; `backup` 46× `docker ps`; `stacks` 11× `compose ps`, 4× `docker ps`, **1× `docker-compose - down`**; `appexport` 7× `docker ps`; `system` 1× `docker info`; 8 `api` tests FAILED on the refusal - (they built a real Manager). `api`/`stacks`/`web` → `TestMain` + `RunWithStub`; the rest pass on the refusal. -- **R-640:** `appbackup.CheckDumpComplete`; `incompleteDumps` gate in `RestoreFromRecoveryUnit` and - `ReconstituteFromOffsite` before the first mutation; a second check in `reimportDBDumpsFrom` before any - load. Test fixtures' fake dumps now end with the real markers (they did not — 38 tests red first). -- **R-499:** `systemBackupFact(resolveBackupTargetState)` → four branches on the Tier-2 page. -- **R-518:** two bundle strings, both languages, state the measured stop. -## Red-proofs (8, each seen failing, then restored; `git diff` clean on the reverted file) -1. R-650 guard disabled → `TestR650_RealDockerIsRefusedUnderGoTest`: `got `. -2. R-650 one bare `exec.CommandContext(ctx, "docker"…)` put back in dbdump.go → the sweep names `dbdump.go:140`. -3. R-640 replay check removed → `a cut-off copy was LOADED`. -4. R-640 unit gate removed → `stopped=true calls=[stop recreate startsvc:immich-postgres start]`. -5. R-640 off-site gate removed → the replay check still caught it, then a rollback — not the clean refusal. -6. R-499 handler not passing the fact → three branches missing on the page. -7. R-499 old sentence in the same-disk branch → `promises the backup protects this app`. -8. R-518 bundles back to v0.243.0 → measured downtime appears 0 times, old wording present. +- **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`). -## R-626, measured on 9202 (v0.266.0) -navidrome deployed and removed through the product; `docker events` for its compose project 390 s: -kill/stop/die/destroy seen (the positive observable), **no create**. Controller restarted at +150 s; -guest rebooted after. 0 containers, 0 volumes at every check. Leftover: `applied-compose.yml` + -`applied-meta/` stay in the stack dir after a remove (row filed). +## Tests (new) and red-proofs -## Gates -`go build/vet` rc 0; `go test -count=1 ./...` rc 0; `controller_gates.py` all OK (golden-notice advisory). +`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.