docs: R-203 contract + report (controller v0.197.0, proven live)
gates / gates (push) Successful in 10s
gates / gates (push) Successful in 10s
This commit is contained in:
+29
@@ -1672,6 +1672,35 @@ Last updated: 2026-06-13 (v0.60.0 backlog-Medium cleanup)
|
||||
|
||||
---
|
||||
|
||||
## R-203 (v0.197.0) — the namespace-root contract, and what `ok` now means
|
||||
|
||||
**The contract, in one line:** `appbackup`'s path helpers (`UserdataDir`, `PrimaryBackupPath`,
|
||||
`RecoveryUnitPath`, `AppDataDir`) take a **NAMESPACE ROOT**. Anything that came out of `HDD_PATH` or a
|
||||
`StoragePath` is a **DRIVE path** — put it through `appbackup.NamespaceRootFor(drive, systemDataPath)`
|
||||
first. `UserdataDir(bareDrivePath)` still compiles and is still wrong; five callers proved it.
|
||||
|
||||
**The rule now has ONE expression.** `NamespaceRootFor` / `IsEnrolledDrive` in `appbackup`;
|
||||
`backup.Manager.namespaceRoot` and `stacks.Manager.inGuest` delegate. There were two copies before and
|
||||
**they differed** — one compared without `filepath.Clean`, the other with it.
|
||||
|
||||
**Why it was invisible:** on an enrolled drive the namespace root IS the drive path. The two diverge
|
||||
only on the system-data fallback, which `paths.go:26` names as a supported arrangement.
|
||||
|
||||
**`last_status` gains `incomplete`.** A run that could not capture a directory an app declares
|
||||
MANDATORY is not a successful run. **Not `error`** — the rest of the run worked, so `SnapshotCount`
|
||||
and `LastSuccess` still record what WAS captured. It reaches the operator via the existing
|
||||
`backup_run_failures` digest (a new event type is a two-repo change; the hub drops unlisted types).
|
||||
The Hungarian customer warning is unchanged; the page renders `! Hiányos`.
|
||||
|
||||
**Still open, and NOT fixed here:** `resolveAbs` resolves `RootHDD` and `RootUserdata` against the same
|
||||
root. Both callers now pass the namespace root so the export and the backup agree with each other, but
|
||||
whether `${HDD_PATH}` should mean the namespace root on the system drive touches every deployed app's
|
||||
binds and needs a decision, not a patch.
|
||||
|
||||
**Blast radius, measured before changing anything:** exactly one app in the fleet had
|
||||
`HDD_PATH == system_data_path` (`calibre-web` on demo-hp, the R-201 drill fixture). Its data was
|
||||
migrated and its sentinel re-verified byte-identical.
|
||||
|
||||
## R-203 (2026-08-04) — a MANDATORY userdata directory can be absent from the off-site snapshot while the run says `ok`
|
||||
|
||||
Found live on demo-hp while staging the R-201 drill, and it **halted that drill**.
|
||||
|
||||
Reference in New Issue
Block a user