From bed9bd2c5a1be7ccef9f7933c793b0e68b07b4d1 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sun, 12 Jul 2026 04:29:48 +0200 Subject: [PATCH] =?UTF-8?q?CAMPAIGN-3=20audit:=20unattended=20night=20run?= =?UTF-8?q?=20=E2=80=94=20data=20plane=20solid;=20NAS=20automount=20re-arm?= =?UTF-8?q?=20plane=20broken=20(F10=20CRITICAL,=20F9/F11/F7=20HIGH);=20dem?= =?UTF-8?q?o=20host=20DOWN=20after=204e=20reboot=20(HUMAN)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 30 PASS / 17 FAIL / 11 FINDING / 1 DISCREPANCY. Fix-6 ring numbers (6.5min horizon under load, wiped per restart), backup-vs-NAS policy discovery, morning recovery runbook. Evidence: 180:~/campaign3/. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_017CDMFpFx84pfviCTVuGGhf --- CONTEXT.md | 10 ++ REPORT.md | 105 ++---------------- documentation/audits/CAMPAIGN-3-2026-07-11.md | 96 ++++++++++++++++ 3 files changed, 117 insertions(+), 94 deletions(-) create mode 100644 documentation/audits/CAMPAIGN-3-2026-07-11.md diff --git a/CONTEXT.md b/CONTEXT.md index 5038811..cc9e3e9 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -3,6 +3,16 @@ > Created with the REUSE.md rollout (2026-07-03). Authoritative history: `hub/CHANGELOG.md` (hub), > `website/CHANGELOG.md`, `scripts/CHANGELOG.md`; end-of-task detail in `REPORT.md`. +- **2026-07-12 — CAMPAIGN-3 NIGHT RUN DONE; ⚠ DEMO HOST DOWN (HUMAN).** Unattended chaos campaign + 22:09→04:27 vs demo box (ctrl 0.117.0/agent 0.84.0): data plane solid (refusals/verify/rollback/ + restore byte-identical/EIO instant/stub badge + deploy-409 live-validated), but **felhom-pve never + returned from the planned host reboot** (physical power/console needed; recovery runbook in the + audit) and the **NAS automount re-arm plane failed**: F10 CRITICAL (start-limit never re-armed, + once blocked guest start), F11/F9 HIGH (post-start reassert "skip-active" skips the healing + automount restart; agent-restart sweep silent) → 4 NAS apps dead-at-boot on 3/3 guest reboots; + F7 HIGH (in-place dump write → 0-byte tar replaced last good backup during outage window). + Fix-6 numbers: ring horizon 55min idle / **6.5min under load**, wiped on every restart. + Full ledger/evidence: `documentation/audits/CAMPAIGN-3-2026-07-11.md` + `180:~/campaign3/`. - **2026-07-11 — HUB v0.47.0 UI REORGANIZATION SHIPPED** (CHANGELOG v0.47.0; commits `9f29bf3` → `0daddcd` + docs). Five deliverables: **(1)** `.data-table td a:not(.btn)` button-contrast fix; **(2)** customer page = **8 hash tabs** (`#tab=…`, sticky summary strip, Events error badge, diff --git a/REPORT.md b/REPORT.md index 3172ae4..f0068b4 100644 --- a/REPORT.md +++ b/REPORT.md @@ -2,102 +2,19 @@ > **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md). -## Hub v0.47.0 — UI reorganization (customer tabs, Host tab, stale-host removal, offsite multi-endpoint UI, button contrast) — 2026-07-11 +## CAMPAIGN-3 — unattended "no mercy" night run (NAS · deploy · backup · chaos · observability) — 2026-07-11/12 -### 1. Baseline +**Full report: [`documentation/audits/CAMPAIGN-3-2026-07-11.md`](documentation/audits/CAMPAIGN-3-2026-07-11.md).** Run 22:09 → 04:27 CEST against the demo box (controller 0.117.0 / agent 0.84.0), operator-unattended, real surfaces only, no code changes. Ledger: **30 PASS · 17 FAIL · 11 FINDING · 1 DISCREPANCY** (66+ scenario entries, evidence at `180:~/campaign3/`). -felhom.eu `main` @ `8e1a3f0d82b62ac84835ddf0aa5a6fd523afb034`, hub v0.46.0 (CHANGELOG top + -running footer + `manifests/hub.yaml` all agreed). Spec: the "Hub UI reorganization" TASK. +### Headlines -### 2. Files created / modified +- **⚠ HUMAN, first thing:** felhom-pve **did not return** from the planned 4e host reboot (23:30) — polled every 5 min until 04:27; no ping, no SSH (22/8822), controller 530. Needs physical power/console. Morning recovery runbook is in the report (§Box state) — after boot expect F10/F11 and heal with `reset-failed` + automount restart + `docker start` of the 4 NAS apps. +- **CRITICAL F10 + HIGH F11/F9 — the reboot/recovery plane around NAS automounts is broken:** `mount-start-limit-hit` is never re-armed by any heal path (once even blocked guest start → guest DOWN); guest reboot with an idle share leaves the autofs trigger unpropagated into the container — the post-start reassert **logs its own WARNING and then skips** the automount restart that provably heals ("skip-active" branch). Every such reboot = 4 NAS apps dead-at-boot. Reproduced on 3 of 3 guest reboots. +- **HIGH F7 — backup dumps are written in place (no tmp+rename):** a mid-backup NAS cut left a 0-byte tar *replacing* the last good 247M dump; in that window restore = empty volume. Next run self-heals; run-level `success:false` is the only signal. +- **The data plane held:** all 5 refusal categories ×2 correct + fast (2–5 s, retry=0), verify/rollback/single-flight/orphan flows clean, deploy-view truth holds, restore round-trips **byte-identical**, EIO same-second under outage, organic stub → badge + deploy-409 live-validated, hardlinks work on NFSv4.1. +- **Fix-6 answered with numbers:** ring cap horizon = ~55 min idle but **~6.5 min under load**; every restart/reboot wipes both rings — persistence, not just size, is the gap. +- **Policy discovery (docs):** tier-1 = volumes+config only (NAS media userdata excluded by design); NAS apps' tier-1 lands *on the NAS*, tier-2 is what gets it off; volume-only apps back up to sys_drive with blank drive label and **no tier-2 copy**. -- `hub/internal/web/templates/style.css` — `.data-table td a:not(.btn)` contrast fix + tab/summary-strip/badge CSS -- `hub/internal/web/templates/customer_unified.html` — 8 hash-tab panels + sticky summary strip + Events badge + Host tab (all sections preserved; hiding = JS-added body class only) -- `hub/internal/web/templates/host_detail_body.html` — NEW: shared `{{define "host_detail_body"}}` (identity/vitals/guests/storage/diagnostics/DR + the Deletable-gated danger zone) -- `hub/internal/web/templates/host_detail.html` — reduced to chrome + sub-template call -- `hub/internal/web/templates/offsite.html` — endpoint cards + add/edit/delete forms + Endpoint peer column + deferral note -- `hub/internal/web/hosts.go` — `hostDetailData` builder; `handleHostDeleteImpact` + `handleHostDelete` -- `hub/internal/web/configs.go` — `Hosts` view models on the customer page (via `ListHostsByCustomer`) -- `hub/internal/web/offsite.go` — multi-endpoint render + save/delete handlers + subnet/peer guards -- `hub/internal/web/server.go` — routes: `/hosts/{id}/delete-impact|/delete` (above the catch-all), `/offsite/endpoints[...]` -- `hub/internal/store/store.go` — `ListHostsByCustomer`, `HostArtifacts`/`CountHostArtifacts`, `DeleteHost` (one-tx cascade), `ErrHostEscrowPresent` -- `hub/internal/store/wg.go` — `ListWGEndpoints`, `DeleteWGEndpoint`; `SetWGEndpoint` comment updated (behavior untouched) -- Tests: `hub/internal/web/customer_tabs_test.go` (new), `hosts_delete_test.go` (new), `offsite_test.go` (amended deliberately), `hosts_test.go` (pin comment), `hub/internal/store/host_delete_test.go` (new), `wg_endpoints_test.go` (new), `host_test.go` (+`TestListHostsByCustomer`) -- Docs: `hub/CHANGELOG.md` (v0.47.0), `hub/README.md` (tab map, host lifecycle, offsite mgmt), `CONTEXT.md`, `REUSE.md` (new §2 table), `manifests/hub.yaml` (tag 0.47.0) +### Box state / cleanup -### 3. Commits on `main` - -| Commit | Content | -|---|---| -| `9f29bf3` | Part 1+2: CSS contrast fix + customer hash tabs + tab render tests | -| `ae950e5` | Part 3: `host_detail_body` sub-template + Host tab + `ListHostsByCustomer` | -| `146d165` | ⚠ NOT mine — the parallel NFS session's docs commit whose `git add -A` swept my Part-4 WIP **mid-red-proof** (hosts.go landed with the RED-PROOF-2 mutation, escrow ack bypassed; everything else was in final correct state) | -| `068427a` | Part 4 completion: restored the escrow-ack gate line (the only delta vs. the intended state) | -| `0daddcd` | Part 5: offsite multi-endpoint UI + guards + tests | -| `95d71fe` | Part 6: CHANGELOG/README/CONTEXT/REUSE docs + `manifests/hub.yaml` → 0.47.0 | -| `77247f9` | this REPORT.md | - -### 4. Red-proofs (all five ran: mutation → FAIL with the wrong value visible → revert → green) - -1. **Online gate removed** (`handleHostDelete`) → `TestHostDelete_OnlineRefused` FAILED: `online delete = 303, want 409` (live host deleted). Reverted. -2. **Escrow-ack check dropped** (`deleteEscrow := true`) → `TestHostDelete_EscrowAckRequired` FAILED: `escrow-unacked delete = 303, want 409`. Reverted. (This exact mutation is what `146d165` accidentally shipped; `068427a` is the revert on main.) -3. **Endpoint-delete peers-in-subnet guard removed** → `TestOffsiteEndpointDelete_Guard` FAILED: `delete with peers = 303, want 409`. Reverted. -4. **Subnet-change guard removed** → `TestOffsiteEndpointSave_SubnetChangeGuard` FAILED: `subnet change with peers = 303, want 409`. Reverted. -5. **log_bundles scope widened** (`WHERE scope_id = ? OR 1=1`) → `TestDeleteHost_CascadeAndIsolation` FAILED: `customer-scoped log bundle count = 0, want 1` + unrelated-host rows deleted. Reverted. - -### 5. Tests - -`cd hub && go build ./... && go vet ./... && go test ./...` — **all green** at every commit. -Test functions in `hub/`: **259 → 280** (+21). Pinned invariants kept green UNMODIFIED: -hosts-list zero-`