Files
felhom-controller/REPORT.md
T

2.5 KiB

REPORT — controller v0.196.0 (R-200 Part 0) + the R-203 finding (2026-08-04)

Deployed: felhom-controller:0.196.0 on demo-hp guest 9201 and demo-felhom guest 9201. Requires agent >= v0.125.0.

Part 0 — --recover-offsite-install

The sibling of --recover-offsite-check: same fetch → unseal → extract path through the agent, same STDIN discipline for R, but it places the recovered repository password via InjectOffboxPassword so a rebuilt box reopens the off-site history it inherited.

  • The confirmation is a second invocation. Without --confirm-install both hashes print and nothing is written; the operator sees the comparison before a write is possible.
  • Three outcomes, named distinctly: installed (no local password — the rebuilt-box shape), unchanged (identical key present, nothing written), refused (a DIFFERENT key present — exit 2, no force offered, because which history to keep is not this command's decision).
  • It re-reads the file after writing rather than trusting the call's return.

go build && go vet && go test ./... rc=0; controller_gates.py --fast OK. Red-proof observed: removing the confirmation gate makes the dry run write the password. The R-persistence test carries a positive control (a planted copy found, then removed and not found) because an absence check is worth only what its sensitivity is.

NOT exercised against a live recovery — the R-201 drill halted before step 9. Unit-proven only.

The R-203 finding — see CONTEXT.md

A customer-declared mandatory data directory was silently absent from the off-site snapshot while the run reported ok, because the deploy-time ${USERDATA_PATH} root and the backup-time NamespaceRoot disagree for an app on the system drive. It halted the drill: the sentinel file was not in the snapshot, so a wipe would have destroyed it and proven nothing.

Full record: felhom.eu/documentation/audits/DRILL-r201-offsite-recovery-2026-08-04.md.

Observations

  • The CSRF form field is _csrf, not csrf_token — the login page uses one name and the protected forms another. Cost real time; worth a line in the headless-access memory.
  • /api/stacks/<name>/deploy accepted HDD_PATH=/mnt/sys_drive one call after refusing a NAS path with a clear error. If the system drive is not a valid app namespace, that refusal is missing.
  • demo-hp has no registered drive usable as an app namespace (its only drive is a NAS), which is why the drill's file-leg app had to go on the system drive at all.