This commit is contained in:
@@ -1,3 +1,53 @@
|
||||
## v0.198.0 — the four steps a customer would have hit alone: two of them closed (2026-08-05, R-204 items 1 & 3)
|
||||
|
||||
The 2026-08-04 recovery drill (R-201) passed — and it only passed because a person was there. Four
|
||||
manual interventions stood between "the key is recoverable" and "the file is back". None of them is in
|
||||
any design document. Two of the three defects are in this repo.
|
||||
|
||||
### Item 1 — a freshly minted reset code now works on the first attempt
|
||||
|
||||
`--print-reset-code` runs as a **separate process** (`docker exec`): it loads settings itself, mints a
|
||||
code, persists it and exits. The running server's cache was never told, so it kept validating against
|
||||
the previous hash. **The code the customer was told to type was refused until the controller
|
||||
restarted, and nothing said so.** During the drill that cost two failed attempts with an operator
|
||||
present; a customer alone stops there.
|
||||
|
||||
`effectiveClaimCode` now READS THROUGH to the persisted state (`settings.ReloadClaimCode`) before
|
||||
applying the settings-vs-config precedence. **The precedence rule is unchanged and deliberate** — the
|
||||
defect was the freshness of the settings value, not which source wins.
|
||||
|
||||
- **Read-through, not a watcher, a signal handler or a TTL.** A TTL is worse than the bug being fixed:
|
||||
it opens a window in which a SUPERSEDED code still works. That is the mutation
|
||||
`TestClaimCode_SupersededByASecondMint_RefusedImmediately` exists to kill, and its red-proof is
|
||||
exactly that TTL — demonstrated failing with "the SUPERSEDED code was accepted".
|
||||
- **Fail closed.** An unreadable persisted state keeps the gate up, refuses the claim and logs why. An
|
||||
ABSENT file is not an error (a box before its first save falls back to the controller.yaml bake).
|
||||
- Cost: one small file read per request **only while the box carries no password** — `claimGateActive`
|
||||
returns on `authEnabled()` before touching it, so a claimed box never reads.
|
||||
|
||||
### Item 3 — a restore now says what it did NOT restore
|
||||
|
||||
The default restore (`mode=unit`) recovers the recovery unit: the app's definition, its configuration
|
||||
and its database dumps. It does **not** recover the customer's own files — `RestoreOffboxScratch`
|
||||
passes `--include <unit path>`, and the userdata that is in the same snapshot is excluded by it. The
|
||||
old outcome was one sentence for both modes and named neither scope, so on the last step of a disaster
|
||||
recovery the customer was told „visszaállítva" after the thing they were looking for had not been.
|
||||
|
||||
- `restoreScratchOutcomeMsg` (pure, unit-testable) now states, for a unit restore: what came back, that
|
||||
the customer's own files did NOT, and the next step that gets them. The full case says the files came
|
||||
with it — otherwise the absence of the warning would be the only difference, and an absence is not a
|
||||
statement.
|
||||
- The wizard's intent card 1 states its scope **before** the choice, not only in the outcome.
|
||||
- **The full-restore size gate is untouched** — still compute, reveal, confirm, re-check at execution.
|
||||
Pinned by `TestOffboxRestore_FullPathUnchanged`, which asserts no restore runs before the confirm.
|
||||
- **The default stays `unit`.** All three wizard forms set `mode` explicitly, so the `mode==""` fallback
|
||||
is reachable only by a hand-crafted POST: changing it would alter nothing the customer sees while
|
||||
silently changing that POST's behaviour. The defect was silence, and silence is what was fixed.
|
||||
`TestOffboxRestore_DefaultModeGetsTheScopedOutcome` pins the mode-less POST to the scoped wording.
|
||||
|
||||
Item 2 of R-204 (a re-issue marking a healthy escrow stale) is the hub's half — felhom.eu v0.95.0.
|
||||
Item 4 (a rebuilt box cannot obtain an off-site credential unaided) is R-193 and remains open.
|
||||
|
||||
## v0.197.0 — the app and its backup look in the same place, and "ok" means it (2026-08-04, R-203)
|
||||
|
||||
Found when the R-201 drill halted at its pre-wipe backup rather than wiping a machine: the run
|
||||
|
||||
Reference in New Issue
Block a user