docs: R-193 CLOSED — CONTEXT + REPORT (controller v0.200.0)
gates / gates (push) Successful in 10s

This commit is contained in:
2026-08-05 12:56:43 +02:00
parent 62b85ecf13
commit a315d623b8
2 changed files with 236 additions and 71 deletions
+39 -1
View File
@@ -7,7 +7,45 @@
>
> Ask Claude Code: "Please update CONTEXT.md with what we did today"
Last updated: 2026-08-05 (v0.199.0 — R-204 item 4: a rebuilt box declares it needs a credential)
Last updated: 2026-08-05 (v0.200.0 — R-193: the recovery screen, unlocking only)
> **2026-08-05 — v0.200.0 (R-193 CLOSED).** The customer-facing recovery screen. Until now a customer
> whose machine was rebuilt had everything needed to get their data back and no way to find out — the
> only route was a command line.
>
> **IT UNLOCKS AND ONLY UNLOCKS** (operator ruling). Explains, takes the recovery code, opens the
> repository, lists what is in it (apps, dates, sizes). **Restores nothing** — restore is per-app and
> lives in the backups area; the put-back is **R-213** and its stated requirement is a
> live-versus-backup comparison.
>
> **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 handler calls the same function. Asserted from
> source by AST on BOTH sides, plus a test that the routes and the landing-page interception exist.
>
> **THE TRIGGER HAS TWO SHAPES and the second is the one that matters.** `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 one on
> re-apply (R-193's own orphaning mechanism) and hub v0.96.0's self-heal re-applies within ~1530 min.
> Shape (b) is also what the shipped move-aside requires, which is why the discard choice can reach it.
>
> **CLAIMED is part of the predicate** — a legacy-open box passes through `RequireAuth`, so without an
> explicit `authEnabled()` check the interception fired for an unauthenticated visitor. A test caught it.
>
> **„Most nem" suppresses the FULL PAGE ONLY.** The backups-area entry point is bound to
> `recoveryOffer`, never to the postpone flag.
>
> **The code:** POST body only, never logged/persisted/echoed, cleared on every path, `no-store`,
> `autocomplete=off`. **No lockout** — a ten-word phrase is not guessable and locking a customer out of
> their own data for a typo is worse; failures are logged locally without the code, and NO operator
> alert is raised (reasoning in REPORT.md §4).
>
> *Live:* demo-felhom is genuinely in shape (b), so validation needed no arrangement — `/launcher` →
> 302 `/recovery`, both mandatory sentences rendered, three wrong codes refused with the `offbox/`
> listing byte-identical and no lockout, and the code found in no file, log or ring **with a
> planted-copy positive control that first exposed a mis-aimed sweep**. **NOT proven live: a CORRECT
> code** — none was kept for demo-felhom's orphaned history and demo-hp's is operator-held.
> **2026-08-05 — v0.199.0 (R-204 item 4 / R-193).** The last of the four manual interventions the
> 2026-08-04 drill needed. **Operator ruling: automate it, and the trigger is a state the BOX