# REPORT — R-379/R-380/R-381/R-382: the undo copy goes back (2026-08-22) Companion to `felhom-controller` **v0.220.0 → v0.220.1 → v0.220.2**. Full record: `documentation/audits/DRILL-r379-rollback-2026-08-22/`. ## What shipped **R-379 and R-380 were one failure with one fix.** Both ended with a half-restored database; the only difference was whether it looked broken. When the replay fails, the product now re-applies the customer's own pre-restore copy — the same `ImportDump` call a person ran by hand yesterday to recover both apps — and the app comes back with a message saying **both** that the restore failed and that the data is as it was. **The whole undo set, matched on the run's own stamp**, never on the `pre-restore-` prefix and never just the first file. **When the rollback also fails the app is held stopped** — the operator's ruling — with every start path refusing it, the app-stop marker ended so nothing auto-restarts it, and the row red rather than green. **R-381:** the failure message stopped pasting engine output (407→257 bytes on Postgres; the MariaDB one had been 615 bytes with rows out of the customer's own database). The full text now reaches the operator log, which never had it. **R-382:** the summary log prints the volume count it already held. **Also:** undo copies resolve to their own app and are capped at 3. ## Documents updated here - `documentation/architecture/07-backup-architecture.md` §6.3 — a dated **[DESIGN]** paragraph on the failure ladder **replay → rollback → hold**, and why an engine flag does not close it. - `STATUS.md` — the outcome in plain words; the deciding section says what happens if nothing is done. - `documentation/backlog/` — R-379…R-382 compressed into `CLOSED-ITEMS.md`, each keeping its title, shipping version, evidence path and every sentence that states a rule. Full text: `git show 4e488321bfd1:documentation/backlog/OPEN-ITEMS.md`. **Register size:** `OPEN-ITEMS.md` **330 683 → 325 236 bytes**; `CLOSED-ITEMS.md` **63 507 → 66 777**. ## The live walk found two defects in the fix itself **Both are recorded because the walk, not the tests, caught them.** 1. **The rollback used a dead container (fixed v0.220.1).** The DB-only start re-creates the DB container, so the id captured at dump time is dead by rollback time. Measured: captured `9adbc14f9af6`, re-created `309795897b82`, rollback timed out after 30 s — **the app was held for an infrastructure reason while its data was recoverable.** No unit test could see it: they all inject the import seam and never look at container identity. 2. **The operator route did not take effect (fixed v0.220.2).** `--clear-restore-hold` runs as a second process; it cleared the file and the running controller went on refusing. Found by using it. ## A red-proof that PASSED Of nine mutations, **one did not fail its test** and is reported rather than omitted: the R-381 behavioural test injected below `ImportDump`, so a leak reintroduced inside `ImportDump` was invisible to it. A guard now sits at that layer and the mutation convicts. ## What did not reproduce The undo copies rendering as app rows on the customer's backup page. The live page was read **before** any change: zero `pre-restore` strings while four such files sat on disk, with a positive control showing 8 real rows. The phantom name was real as a map **key**, never a row. Fixed as a naming defect; their visibility is unchanged and deliberate. ## The golden was baked in this session, and why The `golden-currency` gate refused this docs push: 0.220.2 was released with no golden. **That block is not circular** — a golden needs the controller image, which was already pushed, not this commit — so the gate was satisfied by doing the work it asked for rather than bypassed with `--no-verify`. **No push in this session used `--no-verify`.** Golden **0.220.2**, sha256 `cb439418c7005ce01bcb8126bb6385688c2f408c3c4649f6740001bc2c864ed5`, 657 271 965 B, round-trip verified. All five markers hit, both negative controls at zero, both token-leak greps proved able to convict before their zeros were accepted. Record: `documentation/tests/golden-0.220.2-2026-08-22/`. ## Operator follow-up **Vouch** the golden — Hub → Configuration → Day-0 artifacts, a **three-field** save: `golden_version` **0.220.2**, `agent_version` **0.130.0**, `min_agent` **0.129.0**. **Then** raise the floor to **0.220.2**, last, in its own save.