c1b123c649
gates / gates (push) Successful in 25s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
41 lines
2.7 KiB
Markdown
41 lines
2.7 KiB
Markdown
# REPORT — v0.285.0: a box keeps two controller versions (decision 56); the update clean-up's crash (R-751) — 2026-10-01
|
|
|
|
Full session report: `felhom.eu/REPORT-rulings-2026-10-01.md`. Evidence: `felhom.eu/documentation/audits/rulings-2026-10-01/B/`.
|
|
Architecture read: `09` §3 decisions 30, 45, 52, 53, 56; `03-host-agent.md` (the controller swap); agent
|
|
`internal/localapi/controllerswap.go`.
|
|
|
|
## What changed
|
|
|
|
- `internal/stacks/controller_image_retention.go` — `RetainControllerImages(ControllerImageRecord)`: keeps every image a
|
|
container uses, the running version's tag, the previous one (the swap record, `selfupdate.UpdateState.RecordedPrevious`;
|
|
version order only when the record names none present), every version above the running one and every non-version tag;
|
|
deletes older and untagged controller images by exact name/ID; nothing while the controller swaps itself. Called 3
|
|
minutes after every start (`cmd/controller/main.go`).
|
|
- `internal/stacks/image_retention.go` — R-751: `RetainImagesAfterUpdate` returns when the app is gone after its rescan
|
|
(it dereferenced a nil stack in a goroutine; a panic there ends the process).
|
|
- `internal/stacks/r650_main_test.go` — both retention seams are no-ops in the package's tests.
|
|
|
|
## Measured before building
|
|
|
|
The agent's swap rolls back to what `/etc/felhom-controller-image` named when the swap began — the running image. The
|
|
controller never hands it a previous image (`SwapController(ctx, target)`). So the self-update's own roll-back needs only
|
|
the running image; "the previous" is kept for a roll-back by hand, as ruled.
|
|
|
|
## Tests and red-proofs
|
|
|
|
`TestControllerRetention_*` (6), `TestRecordedPrevious`, `TestRetainImagesAfterUpdate_AppGoneDoesNotPanic`. Each guard was
|
|
broken on purpose and its test failed with the wrong value visible: the previous dropped from the keep switch (0.284.2
|
|
deleted), the record ignored (0.283.1 deleted), the swap check removed (deleted while swapping), the in-use check removed
|
|
(an image a container uses deleted), the success check removed (a failed swap's image named as previous), the nil-stack
|
|
check removed (panic). Full suite `go build/vet/test ./...` green; `controller_gates.py --fast` OK.
|
|
|
|
## Live
|
|
|
|
| box | controller images before → after | Docker images (`system df`) | how |
|
|
|---|---|---|---|
|
|
| 9202 | 5 → 2 | 3.17 → 3.10 GB | bootstrap deploy (self-update is off there); previous by version order |
|
|
| demo-hp 9201 | 84 → 2 | 15.2 → 11.65 GB | floor 0.285.0; previous from the swap record |
|
|
| N100 9201 | 76 → 2 | 6.07 → 1.11 GB | floor 0.285.0; previous from the swap record |
|
|
|
|
Each kept 0.285.0 (running) and 0.284.2 (previous). Every app container stayed up. Golden 0.285.0 baked and vouched.
|