Files
felhom-controller/REPORT.md
T
2026-09-16 21:20:31 +02:00

64 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.