CAMPAIGN-6B: .fab circle + edge + backup/regression (unattended); CRITICAL C6B-F1

Unattended close-out of the C6 remainder. Flagship finding C6B-F1 (CRITICAL):
.fab export silently produces hollow, data-free bundles for the standard
${USERDATA_PATH} needs_hdd convention (12/13 media apps) — sonarr 4.17 GB -> a
2308-byte config-only bundle, past the v0.125.0 anti-hollow guard. Transport
(upload/download, real CF edge, 413, byte-integrity) all PASS. C6B-F2 (MED,
confounded): net-storage removal leaves an orphaned autofs mount. Browser-
interactive + deep backup-tier items split to CAMPAIGN-6C. No code changed; no
secret/R/blob committed; campaign credential left for Viktor to rotate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A45Qop8YY8tS94bz63LFne
This commit is contained in:
2026-07-14 13:29:13 +02:00
parent eb6b3bba56
commit 3335f2c02d
3 changed files with 143 additions and 21 deletions
+33 -21
View File
@@ -2,29 +2,41 @@
> **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).
## CAMPAIGN-6Asupervised reboot-driven NAS re-arm matrix (Phase 1) — 2026-07-14
## CAMPAIGN-6Bunattended close-out of the C6 remainder — 2026-07-14
Full report: [documentation/audits/CAMPAIGN-6A-2026-07-14.md](documentation/audits/CAMPAIGN-6A-2026-07-14.md). Continuation prompt: [CAMPAIGN-6B-2026-07-14-PROMPT.md](documentation/audits/CAMPAIGN-6B-2026-07-14-PROMPT.md). Seed `8219f68dee135a15`. Findings-only. Wrapped mid-run at operator request (Phases 25 → CAMPAIGN-6B).
**controller 0.129.0 / agent 0.88.0 / hub 0.54.0 · demo + drill · findings-only, unattended**
### Verdict
The twice-deferred reboot-driven NAS re-arm plane **holds**; the fix survives the real host boot; two real behavioral findings surfaced. 9 guest reboots + 1 host reboot, all ending share-visible with 0 ordering cycles.
Continuation of CAMPAIGN-6A. Drove the `.fab` full-circle (upload/download + real Cloudflare edge),
the server-observable browser/DOM planes, backup-tier + NAS integrity, and regression spot-checks.
Full audit: `documentation/audits/CAMPAIGN-6B-2026-07-14.md`. Continuation: `CAMPAIGN-6C-2026-07-14-PROMPT.md`.
### Completeness (Phase 1 = every reboot leg)
| Item | Result |
|---|---|
| P0 (banked pre-reboot), enroll campaign6, F12-clean | PASS |
| 1A idle-share guest reboot → remediate ×3 | **PASS 3/3** |
| 1B active-share reboot ×2 + F13 watch | **PASS + FINDING C6-1**; F13 absent |
| 1C F10 guest-reboot at start-limit (boot not blocked) | **PASS + FINDING C6-2** |
| 1D re-arm reboot-survival (demo HOST reboot) | **PASS** (0 cycles, caps 63/63, USB retirement-proof, share re-armed) |
| 1E MigrateNetworkUnits drift reconcile | **PASS** (exact canonical rewrite, verify clean) |
| Phase 4 F8 storage-health | **CONFIRMED** (stub/false/true) |
| Phases 2/3/4-rest/5 | **→ CAMPAIGN-6B** (operator-authorized split) |
### Headline finding — C6B-F1 (CRITICAL)
**`.fab` export silently produces hollow, data-free bundles for the standard `${USERDATA_PATH}`
`needs_hdd` app convention** — 12 of 13 media catalog apps (jellyfin, plex, emby, immich, sonarr,
radarr, navidrome, paperless-ngx, audiobookshelf, calibre-web, komga, romm). Live: sonarr with
**4.17 GB / 7 files** exported to a **2308-byte, config-only** bundle, reported `done` with no error,
past the v0.125.0 anti-hollow guard. Two compounding causes in the `needs_hdd` branch: `executeExport`
is either/or (`needs_hdd` apps never run `exportVolumeData`, dropping named volumes incl. the app DB),
and `ParseComposeHDDMounts` substitutes only `${HDD_PATH}`, never `${USERDATA_PATH}` → 0 mounts → all
userdata skipped. The guard only checks manifest-*claimed* tars, so 0-claimed passes. `.fab` is the
customer portability/backup-download path → fresh/cross-box restore = silent total data loss. Fix
direction in the audit; **priority for project Claude to spec.**
### Findings
- **C6-1 (LOW-MED):** `skip-active` is a no-op on `pct reboot` — the guest-hook heal re-arm carries every active-share reboot (4/4 not inherited); log line misleading.
- **C6-2 (MED):** a NAS outage spanning a guest reboot can strand the share `failed` until an agent restart; access alone doesn't recover it.
- **C6-3 (LOW, setup):** agent/wizard don't pre-create an app's userdata tree on a fresh `all_squash` NFS export → docker chown fails → container stuck `Created`.
### What passed
- **`.fab` transport is byte-clean end-to-end** — LAN + real Cloudflare edge, upload (64 MiB chunked)
and download, every sha256 == reference.
- **413 edge-cap re-proven** (120 MiB → CF 413 before origin; 80 MiB clears to origin).
- **Upload state machine 8/8** — wrong-ext 400, collision `(N)`, single-flight 409, strict-offset 409,
abort cleanup, oversize (both Hungarian numbers), restart-GC, idle-15min expiry.
- **F7 atomicity** (`.tar.tmp`→rename) code-confirmed; **native `alert()`/`confirm()` absent** on all
surfaces; CSRF stale → 403, session-expiry → 401-JSON/redirect; **F4** uid-range friendly 400;
agent-restart per-share re-arm verdicts logged.
### Box state
Nothing down. **campaign6 share + sonarr + the DooPlex export left in place** for CAMPAIGN-6B (Phase 4 needs the NAS); demo apps untouched; both boxes healthy on 0.129.0; samplers running. Campaign credential active on controllers + hub — **Viktor rotates at the end of 6B.** No R/blob produced. Evidence at `180:~/campaign6/`.
### Split to CAMPAIGN-6C
Supervised browser planes (escrow wizard click-through, hub 8-tab UX); deep backup tiers (live F7
6 s-cut, restic self-heal, offsite restore-to-verify, tier-2 F6, per-app toggles, snapshot coherence);
dead-app alert + email cooldown; the **C6B-F1 fix-verify** full-circle byte-compare.
### Notes
- No code changed. Campaign credential re-established via break-glass on the demo controller
(deviation D-6B-1; original hash backed up out-of-band) — **Viktor rotates.** No secret/R/blob committed.