# 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=pending` with 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.