Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
4.1 KiB
REPORT — controller v0.245.0: the household is asked for the recovery code
2026-09-16. R-543. Off-site backup is ON by default and does not RUN until the household creates its recovery code. The pause is the design and is untouched here — the escrow is zero-knowledge, their code is the only key, and a run without one would write a copy nobody could ever open. What was missing is that nothing asked them, while the page promised the very copy that had never run.
What shipped
The reminder bar. While the off-site tier is configured and its escrow state is not escrowed,
every authenticated page carries „A távoli mentés szünetel, amíg nem hozod létre a helyreállítási
kódot." linking /backup/escrow. It is the R-241 bar, second instance — same session-cookie
dismissal („Most nem"), back at the next visit, gone for good when escrowed. No second banner system
was built.
Where it hangs, and why it matters: executeTemplate (server.go), the single render choke point,
not the three addRecoveryBanner call sites. A per-handler helper would have covered the pages
someone remembered — the seam-built-but-never-wired shape this repo has shipped four times. The
login and claim pages render through ExecuteTemplate directly and never pass through it; a session
check (hasAdminSession) additionally keeps it off the public guest share page.
The tier-1 sentence renders by state. v0.244.0 fixed the label (R-537) and put a new promise in
its place: „a távoli másolat … védi", printed from the app's shape alone. driveFilesNoteFor now
takes tier3State's own vocabulary — active → „védi"; escrow_pending → „védené — a távoli
mentés a helyreállítási kód létrehozásáig szünetel" + the route; no off-site and no second drive →
„nincs másolat" + both ways out. One source of state, so the row and the sentence cannot disagree.
Red-proofs — each seen failing, then passing
| fix | break | what failed |
|---|---|---|
| the bar | delete the one addEscrowBanner line from executeTemplate |
„/dashboard does not tell the household the off-site copy is PAUSED" — and the same on /launcher |
| the sentence | compute it from the app's shape, as v0.244.0 did | „the sentence claims the files ARE protected while the copy is paused", quoting the exact v0.244.0 wording |
Negative controls: an escrowed box is not nagged; an unconfigured box is not nagged; an app with no
drive-side files gets no sentence in any state. The banner fixture asserts OffboxConfigured()
itself, so it cannot pass by silently losing its precondition.
Live validation (endpoint-level; no browser on DooPlex)
Both boxes ran 0.245.0. Requests ran inside the guests (the controller answers on the container
address with the mandatory Host header; neither guest is reachable from DooPlex).
- Escrowed (9201): bar absent on /dashboard, /launcher, /backups/apps; the row reads „védi" (×2).
- Paused (9202): off-site configured through
POST /backup/offbox/config→escrow_state=pendingwith both secret files on disk. Bar present on /dashboard, /launcher, /backups/apps and /settings.POST /backup/offbox/run→ „A távoli mentés a kulcs letétbe helyezésére vár.",last_run=None,snapshot_count=None— refused by the fork-4 gate, not by an unreachable target. A throwaway class-A app's row rendered „…védené … szünetel" with „védi"=0. Dismissal sets a cookie with no Max-Age and no Expires; same visit 0 hits, next visit 1 hit. - Teardown, three layers: app removed with data and backups (0 containers, 0 drive folders); the
off-site target cleared and its three secrets
shred -u'd (verified by re-reading); temp files gone on guest and host; the hub provisioned nothing (9202 does not report).
Gates
go build ./... && go vet ./... && go test ./... — green. controller_gates.py --fast — 15/15 OK.
CI run 671 for the previous push (ad398b60) — success, matched by head_sha.
Requires
Hub v0.116.0 (unchanged from v0.244.0). MinAgent unchanged at 0.131.0. No agent change, no hub change, no installer change, no golden.