docs: R-204 items 1 & 3 — CONTEXT, REPORT, README (controller v0.198.0)
gates / gates (push) Successful in 9s

This commit is contained in:
2026-08-05 07:37:25 +02:00
parent 33fcc502e4
commit 68f195676b
3 changed files with 199 additions and 42 deletions
+22
View File
@@ -456,6 +456,17 @@ Each app can define rich metadata in `.felhom.yml`:
+ `dumps_at`; a manifest without them is a pre-v0.148 pair of unknown skew, surfaced at restore
time. The periodic refresh carries the prior stamp forward and never invents one. A dump-leg
failure is a loud WARN that does NOT abort the push (data-first: a degraded backup beats none).
- **A scratch restore NAMES ITS SCOPE (v0.198.0, R-204 item 3 — `restoreScratchOutcomeMsg`).**
`mode=unit` (the default) restores the recovery unit only — the app's definition, configuration
and DB dumps — because `RestoreOffboxScratch` passes `--include <unit path>`; the userdata that is
in the SAME snapshot is excluded by it. The outcome flash used to be one sentence for both modes
and named neither scope, so on the last step of a disaster recovery the customer was told
„visszaállítva" after the thing they were looking for had not been. The unit outcome now states
what came back, that the customer's own files did NOT, and the step that gets them; the full
outcome states that the files came with it (an absence is not a statement). The wizard's intent
card 1 carries the same scope BEFORE the choice. **The `mode=full` two-step size gate is
untouched**, and the default stays `unit` — all three wizard forms set `mode` explicitly, so
changing it would alter nothing the customer sees while silently changing a mode-less POST.
- **Offsite reconstitution (v0.148.0, R-43 — `offbox_reconstitute.go`):** the leg that was missing.
`ReconstituteFromOffsite` (`/backup/offbox/reconstitute`, „Teljes visszaállítás (fájlok +
adatbázis)") makes the live app equal to the chosen snapshot: **safety dump → stop → files
@@ -2241,6 +2252,17 @@ race where a new `felhom.<domain>` cert appears in CT logs minutes before any pa
never rewrites, a hub outage never clears). The report carries `claimed` (hub ingests set-only).
- **Escape hatch**: `felhom-controller --print-reset-code` prints a one-time local code (generation
above cached/baked/consumed); the same gate consumes it. Root-gated by `docker exec` reachability.
**It runs as a SEPARATE PROCESS, which is why `effectiveClaimCode` READS THROUGH to the persisted
state (v0.198.0, R-204 item 1).** Until then the hatch persisted a new code while the running
server kept the old one cached, so the minted code was refused until the controller was restarted —
and nothing said so. The read-through (`settings.ReloadClaimCode`) is on the claim path only, and
only while the box carries no password (`claimGateActive` returns on `authEnabled()` first).
**Deliberately not a watcher, a signal handler or a TTL:** a TTL would leave a window in which a
SUPERSEDED code still works, which is worse than the bug. Refreshes hash/generation/issuedAt only —
never `ClaimConsumedGeneration`, which this process alone writes and must stay monotonic.
`effectiveClaimCode` returns an error and **every caller fails closed** (the gate stays UP, the claim
is refused); an ABSENT settings file is not an error, since a pre-first-save box falls back to the
controller.yaml bake.
#### Session Auth (`internal/web/auth.go`)