docs: R-193 CLOSED (the recovery screen); R-213 minted for the put-back
gates / gates (push) Successful in 7s

- OPEN-ITEMS: R-193 CLOSED with both 2026-08-05 rulings (unlocking and restoring
  are separate; 'I do not want the old data' moves the store aside after a double
  confirmation), and the shape-(b) reasoning — WriteOffboxSecrets auto-generates a
  repository password on re-apply, so the literal 'fresh data area' trigger would
  have opened a window that closes by itself.
- R-213 MINTED (R-212 was and still is the highest, re-checked for the second
  writer): putting files back in place, with the live-versus-backup comparison
  named as its requirement. Not started, deliberately.
- capability map: the 'needs someone who knows to look' qualifier is GONE; what
  remains is stated narrowly — no correct-code run through the page, the put-back
  is out of scope, and the journey has not been re-walked end to end.
- 07-backup-architecture 7.0: a fifth row, and where the screen deliberately stops.
- CONTEXT: standing ruling S-34.
- STATUS: the headline change and the two things still owed as proof.

No hub change and no hub bump.
This commit is contained in:
2026-08-05 12:56:55 +02:00
parent 63e0ac01f2
commit f45b1f6761
6 changed files with 85 additions and 19 deletions
+42
View File
@@ -17,6 +17,48 @@
## Standing rulings
**S-34 — UNLOCKING AND RESTORING ARE SEPARATE. The recovery screen shipped (2026-08-05, controller
v0.200.0, R-193 CLOSED). Read with S-32 and S-33; together they close the whole customer journey up to
the listing.**
**THE RULINGS (operator, 2026-08-05), recorded as given:**
1. **Unlocking and restoring are separate.** This screen unlocks only. Restore stays per-app, in the
backups area. **A screen that unlocks and then offers to overwrite is two decisions wearing one
button.** Putting files back is its own item (→ **R-213**), and its stated requirement is a
live-versus-backup comparison — the customer must see what would change before anything is
overwritten.
2. **"I do not want the old data" MOVES THE STORE ASIDE**, after double-checking with the customer.
*Mechanism facts a future session needs:*
- **ONE CORE, TWO CALLERS.** `backup.RecoverInstallCore` is the only fetch→unseal→compare→install path.
`RecoverAndInstall` is now a thin CLI wrapper (exit codes and printed lines byte-identical — every
pre-existing CLI test passed unchanged) and the web handler calls the same function. **Asserted from
source by AST on BOTH sides**, plus a third test that the routes and the landing-page interception
exist. Two implementations of the one operation that can permanently lose a customer's data would
drift, and only one would be tested.
- **THE TRIGGER HAS TWO SHAPES, and the second is the one that matters in practice.**
`backup.OffsiteRecoveryOffer` = the hub holds a package **AND** (no repository password **OR** the
tier is orphaned). The literal "no repository password" alone is a window that CLOSES BY ITSELF:
`WriteOffboxSecrets` auto-generates a password on re-apply — R-193's own orphaning mechanism — and
since hub v0.96.0's credential self-heal the re-apply happens within ~1530 minutes. Shape (b) is
also the state the shipped move-aside requires, which is what lets the discard choice reach the
existing handler instead of needing a new one.
- **CLAIMED IS PART OF THE PREDICATE.** A legacy-open box (no password anywhere) reaches `ServeHTTP`
through `RequireAuth`'s pass-through, so without an explicit `authEnabled()` check the interception
fires for an unauthenticated visitor. Caught by a test, not by review.
- **"Most nem" suppresses the FULL PAGE ONLY.** The backups-area entry point is bound to
`recoveryOffer`, never to the postpone flag. A one-shot notice a flustered person clicks past is a
notice that never happened.
- **The code is handled no more loosely than on the CLI:** POST body only (`PostFormValue`), never
logged, never persisted, never echoed, cleared on every path, `no-store`, `autocomplete="off"`.
**NO LOCKOUT, deliberately** — the code is a ten-word phrase and locking a customer out of their own
data for a typo is worse than anything a lockout prevents; failures are logged locally without the code.
- **NOT YET PROVEN LIVE: a CORRECT code through the page.** No recovery code was kept for demo-felhom's
orphaned history (`RECON-offsite-dr-chain-2026-08-04.md` §12.3) and demo-hp's is operator-held. The
live run exercised handler → agent → hub fetch → age KDF and stopped at the unseal.
**S-33 — THE BOX DECLARES, THE HUB ANSWERS. R-204 item 4 / R-193's credential half closed
(2026-08-05, controller v0.199.0 + hub v0.96.0). Read with S-32; together they close all four of the
drill's manual interventions.**