docs: REPORT — §13 all 6 live legs PASS (credential was quote-stripping bug, not stale)

This commit is contained in:
2026-07-15 09:15:05 +02:00
parent 483b2186cb
commit 1245a6c46e
+46 -34
View File
@@ -80,44 +80,50 @@ All reverted; post-revert both suites green; no mutation residue.
- **Controller:** built + pushed `felhom-controller:0.134.1` on 180; deployed to guest 9201 →
`Up (healthy)`. Commit `0cfcc42`.
## §13 live validation
## §13 live validation — ALL LEGS PASS
**Credential blocker (honest):** the sanctioned credential `180:~/.config/credentials` `C4_PASSWORD`
(len 14) is **stale** the demo customer changed their dashboard password after the one-time claim
(login returns `Hibás jelszó`, no session). So the dashboard-session legs (manual run trigger, the two
scratch-restore legs, the UI prefs round-trip, the synthetic delivery event) could NOT be driven. I
did **not** reset the customer's password or extract the controller's hub API key to force a session
(both would alter demo state / overreach). What was validated read-only / organically instead:
The dashboard session was established with `180:~/.config/credentials` `C4_PASSWORD` (the value is
**single-quoted** in the file — stripping the quotes is required; an earlier run that kept the quotes
produced a false `Hibás jelszó`, since corrected). Login → 302 + `felhom_session` cookie; the flow ran
entirely on 180 (LAN → dashboard) so the password was never transferred or echoed.
- **Leg 2aenlarged snapshot shape (LIVE, organic):** the daily 04:15 CEST scheduled run (2026-07-15
02:15 UTC, v0.134.0) produced the multi-path shape. `restic snapshots --no-lock --json` newest per
tag: **calibre-web** = `["…/nas-media/backups/primary/calibre-web", "…/nas-media/userdata/media/books"]`
(unit + MANDATORY userdata); the 2026-07-14 calibre-web snapshot was unit-only — the shape change is
visible across runs. immich / audiobookshelf newest = unit-only (no resolvable mandatory HDD bind).
- **Leg 2b — raw-data quota (LIVE):** stored `repo_size_bytes = 280,932,901` (267.9 MB) == live
`stats --mode raw-data` (280,932,901) exactly — the raw-data switch refreshed the stored value (was
744,763,144 / 710 MB modeless before 3a). 15 snapshots retained.
- **Leg 2c — forget grouping:** in the deployed code (both call sites) + unit-tested; the live log line
was not capturable (the container restarted at the v0.134.1 deploy, rotating the 04:15 run's logs).
- **Delivery chain (partial, read-only):** hub v0.55.0 allowlist entry is LIVE (deployed Synced/Healthy
+ the hub acceptance test). Controller notifier enabled (`Notifier enabled (hub: https://hub.felhom.eu)`).
The prefs migration is confirmed getter-only (stored `enabled_events` does NOT persist
`offbox_enlarge_blocked` — matches the design; surfaced at read).
- **Hygiene:** no scratch dirs were created (legs 34 did not run); the login-attempt temp files on 180
were removed; read-only inspection scripts removed from the container.
- **Leg 2 — manual run (LIVE):** POST `/backup/offbox/run` → 302; run log:
`backed up calibre-web (…, 1 mandatory path(s))` (enlarged shape), `audiobookshelf`/`immich`
`not deployed — offsite push is unit-only` (the §2.4 undeployed WARN firing live), `backup OK: 3
app(s) backed up, 15 snapshot(s), 49s`. **Leg 2a** confirmed by `snapshots --no-lock --json`:
calibre-web newest = `[…/backups/primary/calibre-web, …/userdata/media/books]` (unit + mandatory).
- **Leg 2b — raw-data quota (LIVE):** stored `repo_size_bytes = 280,932,890` (267.9 MB) == live
`stats --mode raw-data` — down from 744 MB modeless pre-3a.
- **Leg 2c — forget grouping:** both call sites carry `--group-by host,tags` (deployed + unit-tested);
a successful forget is logged SILENTLY by design (only failures log), so no live line — the ~40s gap
before "backup OK" + the stable 15-snapshot retention evidence it ran.
- **Leg 3 — unit-only scratch restore (LIVE):** POST `mode=unit` → scratch landed on the DATA DRIVE
`/mnt/felhom-drives/nas-media/backups/offsite-restore/calibre-web` (NOT the rootfs — F-A1); the
reconstructed tree contains ONLY `…/backups/primary/calibre-web/{compose,volume-dumps}` (unit-only
scope, `--include` working); rootfs `DataDir/offbox-restore` absent.
- **Leg 4 — full restore two-step (LIVE):** step 1 `mode=full` → 302 to
`/backups/restore?full_prep=calibre-web&full_size=258.3+MB` (size shown BEFORE start); step 2
`mode=full&confirm=1` → the scratch now also holds `…/userdata/media/books/.calnotes/…` (whole
snapshot, SP-3.1 abs-path reconstruction).
- **Leg 5 — prefs round-trip (LIVE):** `/settings/notifications` renders `event_offbox_enlarge_blocked`
**checked** (migration surfaced it enabled); a save round-trip → the type **survived** (F3
checkbox-drop trap avoided); the hub logged `Notification preferences updated for demo-felhom:
events=[… offbox_enlarge_blocked …]` — the migrated type reached the hub whitelist end-to-end.
- **Leg 6 — delivery (LIVE, one synthetic event):** pushed `offbox_enlarge_blocked`/warning through the
real controller→hub path → **hub_status 200** (was 400 before v0.55.0); hub logged
`Event from demo-felhom: offbox_enlarge_blocked (warning)` + `Operator email sent for
demo-felhom/offbox_enlarge_blocked`. The message was the debug endpoint's generic text (it fixes the
body); the dynamic two-number message survival is unit-proven (`templates_offbox_test.go`) — no
`customerMessages` entry, so `FormatCustomerEmail` falls back to the raw message.
- **Leg 7 — hygiene:** the calibre-web scratch (legs 34) removed; 180 session temp files removed;
read-only inspection scripts removed from the container. `PlaceOffsiteRestore` was NOT run (6D).
## NOT yet live-validated — awaiting a supervised session with the CURRENT customer password / 6D
## NOT yet live-validated — awaiting CAMPAIGN-6D (supervised)
- Manual run trigger via the UI endpoint (organically covered by the scheduled run for shape + size).
- Unit-only + full scratch restore via the real endpoints (legs 34).
- The prefs checkbox round-trip in the live UI (leg 5) — migration + sync are unit-tested + getter
confirmed live; the checked-render + save-survives round-trip needs the session.
- The synthetic `offbox_enlarge_blocked` delivery event + customer email (leg 6) — hub ingestion is
live; end-to-end delivery needs a session or the demo API key.
- `PlaceOffsiteRestore` against live data; organic enlarge-block firing (demo repo 268 MB / quota 50 GB);
the SQ3 immich offsite-only full circle.
- **Follow-up flagged:** refresh `C4_PASSWORD` in `180:~/.config/credentials` (the demo customer's
current dashboard password) so future in-session live legs aren't blocked.
- `PlaceOffsiteRestore` against live data (the STOP boundary — merges into live app data).
- Organic enlarge-block firing (demo repo 268 MB / quota 50 GB won't trip; unit-tested + the delivery
chain proven live via the synthetic event).
- The SQ3 immich offsite-only full-circle restore-and-boot.
## Observations (documented, not acted on)
@@ -129,3 +135,9 @@ did **not** reset the customer's password or extract the controller's hub API ke
migration would honor a deliberate opt-out. Noted, not changed (the task specified the getter).
- The stale `documentation/controller/backup-architecture.md` ("restic is gone from the controller")
remains — flagged in the v0.134.0 report; still its own task.
- **Demo-state touches during §13 (benign, noted):** the leg-5 prefs save persisted the demo
customer's `enabled_events` to explicitly include `offbox_enlarge_blocked` (previously getter-migrated
— idempotent, no behavior change); leg 6 sent one operator test email. Legs 34 scratch dirs were
removed (leg 7). No live app data was modified (`PlaceOffsiteRestore` not run).
- **Credential note:** `C4_PASSWORD` in `180:~/.config/credentials` is **single-quoted** — strip the
quotes before use (an unstripped value yields a false `Hibás jelszó`). The credential is valid.