--- paths: ["controller/internal/backup/**", "controller/internal/appbackup/**", "controller/internal/recovery/**", "controller/internal/appexport/**", "controller/internal/quiesce/**"] --- # Backup, recovery units and export — felhom-controller ## Assert the consequence across the whole run, not the mechanism inside one function The R-181 recovery-unit refusal claimed *"the previous unit is untouched and NOTHING was deleted"*. *Nothing deleted* held; **untouched was measured false** — the floor was checked ONLY in `captureAllRecoveryUnits`, while the two dump legs wrote the bulk into the same tree first and unguarded, so a 182,272 B tar became 2,147,666,432 B under a manifest that had not moved. A full green suite plus three of its own red-proofs missed it, because every one asserted the mechanism inside `captureAllRecoveryUnits`. **The test that catches this class: fingerprint the tree before and after the whole backup run, and compare.** Full doctrine and the other eight instances: the `felhom-testing` skill. ## Presence is not success A timestamp recording an **attempt** must never be read as evidence of a **result**. Where a status field travels alongside a timestamp, the verdict consults both — or the timestamp records only successes. Ask of any timestamp: *what exactly must have happened for this to be set?* If the answer is "we tried", it cannot answer "did it work". **Corollary:** when a verdict changes which field it counts from, the alarm text has to change with it. `last run 8h ago` while alarming on a six-day-old success turns a true alarm into one the operator dismisses. ## Storage keys and paths - Never guess a persisted key — it is `offbox`, not `offbox_target` (R-7b). - `.fab` export/import uses strict segment validation; bundles from controller ≤0.124.0 are hollow. - Recovery-unit restore and tier-2 copies share `appbackup`'s path primitives — change them there, once, not per caller.