# REPORT — controller v0.195.0: prove the offsite key comes back (2026-08-04, R-200 plumbing half) **Deployed:** `gitea.dooplex.hu/admin/felhom-controller:0.195.0` on guest 9201 (demo-felhom), `Up (healthy)`. **Requires agent >= v0.125.0** (declared MinAgent) and hub >= v0.94.0. ## What shipped `--recover-offsite-check` — a `docker exec` diagnostic in the shape of `--print-reset-code`. It reads the customer's recovery code from **STDIN**, asks the agent to fetch this host's hub-held sealed bundle and open it, and reports whether the recovered offsite repository password matches the one on disk **by sha256**. Two hashes and a verdict; never a password, never the recovery code, never a blob. - `internal/backup/offbox_recovery_check.go` — `CheckOffsiteKeyRecoverable`, hashes only. - `internal/backup/offbox_recovery_cli.go` — the entry point, R from stdin. - `internal/agentapi/escrow.go` — `RecoverOffsiteRepoPassword` (the only place R crosses outbound). - `cmd/controller/main.go` — the flag, alongside `--print-reset-code`. **R from stdin and not a flag** because a flag value is visible in `ps`, in shell history, in a container's command line and in any session transcript. **It compares and never installs** (§8.5): the recovered password is not written to `offbox/repo_password`, and link 9 — placing it so the existing repository opens — is next session's work, with the drill around it. ## THE RESULT On demo-felhom, 2026-08-04 13:49 CEST: ``` on-disk sha256: c60c8bc737a6b7c6647c7849283f52087f650a885babedb4ef5fdf9a5c9543cb recovered sha256: c60c8bc737a6b7c6647c7849283f52087f650a885babedb4ef5fdf9a5c9543cb [MATCH] the offsite repository password IS recoverable from the sealed escrow. ``` Both equal the hash the hub independently stores as `restic_pw_sha256` — three sources agree. Confirmed non-write: `offbox/repo_password` mtime is still `2026-08-03 07:18:02` afterwards. Five minutes earlier the same path with a deliberately wrong code returned `[FAIL] … the recovery code did not open the sealed bundle … nothing was written`, exit 1. ## Tests `go build ./... && go vet ./... && go test ./...` — rc=0; `controller_gates.py --fast` — all OK. New: `offbox_recovery_check_test.go` — match/mismatch verdicts, the no-local-password shape, R passed through verbatim, agent-failure-is-not-a-mismatch, and the four exit codes with a check that no printed stream carries a secret. **Red-proof observed:** adding `InjectOffboxPassword` to the check fails `TestCheckOffsiteKeyRecoverable_WritesNothing` with *"the check INSTALLED the recovered password"*. ## Not in this release No card, no form, no preview, no customer-facing text — building an interface on a chain nobody had walked is how the preceding three weeks went wrong. The customer-facing shape the operator ruled on (yell → recovery-code form → preview → proceed) is R-200's remaining half, now priced against a chain that exists. **R-201 stays open:** no recovered password has been installed, no repository reopened, no file restored. ## Observation The controller binary is at `/usr/local/bin/felhom-controller`, not `/app/…` — a guessed path cost the first diagnostic invocation. Worth a line in the runbook when one is written.