Commit Graph

102 Commits

Author SHA1 Message Date
admin 0771d58b58 SPIKE restic snapshot shape (SP-1/SP-2/SP-3): stats mode, forget grouping, restore shape
SP-1: quota must use stats --mode raw-data (default restore-size multiplies N x).
SP-2: default forget grouping (host,paths) strands old-shape snapshots forever;
      --group-by host,tags ages them out, keeps apps separate.
SP-3: multi-path restore reconstructs abs paths under --target; --include <abs-unit>
      = unit-only; uid/gid/setgid preserved; snapshots paths field is the shape record.
ARCHITECTURE IMPACT: restic 0.14.0 does NOT error on a missing source path (exit 0,
      silent partial snapshot) -- contradicts §2.5 premise; stat-filter still required.
restic 0.14.0 in felhom-controller:0.132.0 container; scratch on demo 9201, cleaned up.
2026-07-14 21:18:11 +02:00
admin deacee1164 CAMPAIGN-6C: v0.131.0 F-S2/F-S3 live acceptance (4P-1..4P-5 all PASS) + F-6C-1
Unattended pass via the controller API (Campaign-4 credential, real dashboard
endpoints). Closes the v0.131.0 REPORT's "NOT live-validated" list:
- 4P-2 F-S2 tier-2 appdata mirror byte-identical
- 4P-3 F-S2 marker restore (resolved dir, additive-only)
- 4P-4 storage page non-empty size
- 4P-5 F-S3 scope=app migration round-trip, no ghost dir, no WARN

New finding F-6C-1 (MEDIUM): tier-2 to an NFS target fails (rsync -a chown).
PHASE 3 (browser) + 4-deep + Accept #1 deferred to a supervised/deep-budget
6D pass. No code shipped; paperless torn down; no credential/R/blob committed.
2026-07-14 20:01:13 +02:00
admin 790ec845f7 docs(audit): backup-classification spike — coupling model VALIDATED (Immich DB-only restore broken-not-empty); offsite=unit-only live-proven; NEW F-S1 (tier-2 copies no userdata) + F-S2 (paperless-ngx appdata skipped); round-trip verdict: exclusion scoping 2026-07-14 16:39:55 +02:00
admin 671bd3fd91 CAMPAIGN-6B: note credential fully reverted at cleanup
Break-glass credential undone — original customer-claimed hash restored on the
demo controller; box back to pre-6B credential state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A45Qop8YY8tS94bz63LFne
2026-07-14 13:32:14 +02:00
admin 3335f2c02d 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
2026-07-14 13:29:13 +02:00
admin eb6b3bba56 @
CAMPAIGN-6A (Phase 1: reboot-driven NAS re-arm matrix) + 6B unattended continuation prompt

Supervised run, operator authorized unattended reboots mid-run. Phase 1 COMPLETE:
1A idle-remediate 3/3, 1B active skip-active+heal 2/2 (F13 absent), 1C F10 guest-reboot
boot-safety, 1D host-reboot re-arm survival (0 cycles, USB retirement-proof), 1E unit
drift self-repair. F8 confirmed. Findings C6-1 (skip-active no-op on pct reboot),
C6-2 (NAS-outage-across-reboot strands share until agent restart), C6-3 (fresh
all_squash export blocks docker chown). Phases 2-5 -> CAMPAIGN-6B (unattended prompt).
No credential/R/blob committed.

Claude-Session: https://claude.ai/code/session_01LbMm4T7Ayzs1unB9pN6Uqd
@
2026-07-14 12:17:26 +02:00
admin ffba9eb395 @
CAMPAIGN-5 findings doc (2026-07-14): NAS re-arm ring core + v0.129.0 fix live-proof

Findings-only. v0.129.0 F-A/F-B/F-C all CONFIRMED FIXED live on the fleet. NAS
re-arm ring core PASS on a fresh campaign NFS share: F10 start-limit clear +
reset-failed+rearmed, F9 per-share verdict (no empty sweep), F1/F2 clean removal,
F12 unit cycle-free. F8 improved (stub/mounted:false during outage) but reachable:true
still server-level. Reboot half of the matrix + upload/browser planes deferred with
procedures. No credential/R/blob committed.

Claude-Session: https://claude.ai/code/session_01LbMm4T7Ayzs1unB9pN6Uqd
@
2026-07-14 10:12:21 +02:00
admin 0d1b0494b7 @
CAMPAIGN-4: demo host reboot + drive cycle (operator-authorized risky steps)

Demo HOST reboot PASS: 0 ordering cycles (even with active nas-media nfs4),
retirement reboot-proof PASS (3 USB drives re-establish from agent units despite
device-letter reshuffle), cards registry-sourced, nas-media nfs4 0 rbind/rc255
(F13 did not manifest). teszt_enroll drive cycle: eject/reattach work, wipe-gate
+ mount-guard + confirm-gate all correctly refuse unsafe format (no wipe); O-1/O-2
LOW observations. No credential/R/blob committed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LbMm4T7Ayzs1unB9pN6Uqd
@
2026-07-14 00:45:20 +02:00
admin d306d2a5aa @
CAMPAIGN-4 findings doc (2026-07-13 night run, active block)

Findings-only. Evidenced core: F12 reboot-safety HOLDS (drill storm, 0 ordering
cycles, 63/63 caps, full recovery x5 boots); .fab export->download byte-integrity
PASS. Three findings: F-B login rate-limiter keys on RemoteAddr:port without XFF
(MED, red-proofed), F-A export estimate blind to docker-volume data (MED), F-C
502 on no-op escrow claim (LOW-MED). Remaining phases deferred with procedures.
No credential/R/blob committed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LbMm4T7Ayzs1unB9pN6Uqd
@
2026-07-13 23:52:48 +02:00
admin ac305fe57f audits: SPIKE controller-driven escrow ceremony — daemon-context mechanics ALL GO (drill VM, agent 0.87.0): PTY re-key no-TTY 3/3, sudoers refusal matrix 5/5, R pipe round-trip proven, env_reset clean, --upload hub-verified ~2.4s; premise correction: capability probes are list-mode 2026-07-13 17:15:52 +02:00
admin 3efb1b1af1 docs: hub v0.53.0 closing bundle - CHANGELOG + CONTEXT (both operator rulings verbatim) + take-two F-14 disposition (SHIPPED, gated on escrow-acked deletion provenance) 2026-07-13 15:02:44 +02:00
admin 74fa61c7bc audits: disposition — backups-IA finding 2 (legacy-boot SystemDisks dead wizard) RESOLVED by felhom-agent v0.87.0 (slaves-walk, operator ruling 2026-07-13); live evidence drill replay + felhom-pve byte-identical regression; remaining: supervised wizard leg + Day-0 manifest vouch 2026-07-13 13:21:14 +02:00
admin a92e18b21f docs: hub v0.52.0 polish batch — CHANGELOG + REPORT + CONTEXT + REUSE (inline_confirm partial); take-two §4 dispositions: F-15/F-16/zero-toggle SHIPPED
Claude-Session: https://claude.ai/code/session_01GzammAMzsJTgpQHqxwM2bC
2026-07-13 08:48:17 +02:00
admin 11d0f55303 take-two re-drill record: zero-stop Day-0 on v1.15.0/0.86.0/0.51.0 — 1h22m, hands-free DR cascade, floor-update first proof, offsite round-trip; new findings F-14/F-15/F-16
Claude-Session: https://claude.ai/code/session_01NptTCFtu7dz2Ru89qHRagN
2026-07-12 23:13:29 +02:00
admin fda783bdaf docs: DR-tier-by-default batch — decisions 1-5 in CONTEXT, day0 ACL advice reversed, ceremony decision-4 policy block, WG disclosure (tester agreement + GO-LIVE D3), drill F-disposition table, REPORT
Claude-Session: https://claude.ai/code/session_01NptTCFtu7dz2Ru89qHRagN
2026-07-12 20:43:25 +02:00
admin 6040c7b93d drill report: customer-claim arc resolution + post-claim-arc snapshot + follow-up observations
Claude-Session: https://claude.ai/code/session_01NptTCFtu7dz2Ru89qHRagN
2026-07-12 19:20:39 +02:00
admin 8ded485a58 docs: customer-claim arc — REPORT/CONTEXT, G9 supersede, tester-agreement claim step, day0 D.3/D.4 gate, drill F-4/F-5 RESOLVED
Claude-Session: https://claude.ai/code/session_01NptTCFtu7dz2Ru89qHRagN
2026-07-12 18:56:46 +02:00
admin 3e949bc513 DRILL-day0-vm 2026-07-12: full report + runbook corrections (F-4/F-6 headline findings)
Audit doc for the Day-0 VM drill: appliance install, floor-at-first-report,
escrow ceremony + auto-confirm FIRST LIVE FIRING (~7.5 min, zero clicks),
offsite backup + restore round-trip, PBS-DR/WG fork (Peti-sequence rehearsal).
Corrects day0-install.md A.2 (git creds optional since v1.11.2, anonymous
fetch is the normal shape) and RUNBOOK-escrow-ceremony.md (identity-only mode
does NOT exist — F-6; age prereq — F-10). REPORT.md overwritten; CONTEXT.md
one-liner added.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptTCFtu7dz2Ru89qHRagN
2026-07-12 17:16:25 +02:00
admin f97f7803c7 CAMPAIGN-3: morning RCA — host loss = F12 CRITICAL automount ordering cycle (hardware exonerated); box recovered to defined state
journalctl proved boot -1 came up at 23:31 WITHOUT networking: the agent automount
template's After/Wants=network-online.target cycles with local-fs.target and systemd
deleted networking.service to break it; the 06:45 power-cycle boot hit the same cycle
and deleted the automount instead. Every boot with an enrolled share is a coin flip
until the template drops that ordering. Recovery executed: automount started, apps
healed, privatebin removed via real flow, verification backup green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017CDMFpFx84pfviCTVuGGhf
2026-07-12 06:55:40 +02:00
admin bed9bd2c5a CAMPAIGN-3 audit: unattended night run — data plane solid; NAS automount re-arm plane broken (F10 CRITICAL, F9/F11/F7 HIGH); demo host DOWN after 4e reboot (HUMAN)
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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017CDMFpFx84pfviCTVuGGhf
2026-07-12 04:29:48 +02:00
admin 146d165c26 docs: Q1c GREEN — reboot survival automatic since agent 0.84.0 (feature doc + audit §7 + CONTEXT + REPORT)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-11 21:25:14 +02:00
admin 8e1a3f0d82 AUDIT §6: remediation PERFORMED — automount restart heals running guest (fix-1 pre-test PASS), CWA healthy, health ok
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-11 20:19:37 +02:00
admin 0f37e647e3 AUDIT: NAS/CWA RCA 2026-07-11 — stub after 2nd reboot; deploy correct; display bug; hub WARN correct
Diagnostic only (no fixes). Full evidence + 6 prioritized fix tasks in
documentation/audits/AUDIT-nas-cwa-rca-2026-07-11.md; remediation deferred (operator-gated).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-11 19:55:46 +02:00
admin 9b95f88e8c audit(Q1c): NAS automount trigger does NOT survive a guest reboot (empty-dir FAIL) + follow-up
Supervised live proof on the demo (agent 0.82.0 + controller 0.115.0): after pct reboot 9201 the
autofs trigger does not re-propagate into the guest; an in-guest access sees an empty dir and does
not trigger the host mount. Root cause: shared->slave propagation + no agent network-mount reassert
on guest reboot. FAIL protocol honored (nothing repaired live); fix spec'd in backlog.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-11 15:43:26 +02:00
admin 37e60b46d2 docs(audit): DSM spike — consumer recipes validated on real DSM 7.2, hardlink caveat closed, taxonomy identical
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-11 14:47:48 +02:00
admin e80e14d674 docs(audit): record SPIKE-nas-verify findings-doc commit hash (b57f6c1)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-11 08:20:22 +02:00
admin b57f6c1509 docs(audit): SPIKE NAS verify mechanisms + squash matrix — Q1-Q5 answered, Route A accepted-with-caveats
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-11 08:20:00 +02:00
admin 00afadc1fe spike: PBS DR tier provisioning SLICE 0 — all 3 mechanisms settled (token-create impossible -> pinned sudoers; ep0 tenancy op-set + stdout secret transport proven; encryption-key autogen births K, pvesm remove deletes it)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-10 20:12:26 +02:00
admin c8d36b07e4 validation: new-box restore round-trip PASS (9/9 sha-identical) + old-archive retirement decision
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-10 09:29:22 +02:00
admin 292a23bf39 campaign: offsite overnight soak 2026-07-10 — PASS + 1 HIGH finding (crash-mid-prune stale lock)
Unattended live soak of the build-complete offsite arc. F4 re-issue + restore
round-trip proved live (9/9 byte-identical, immich db-dump exact). Crash
recovery surfaced a HIGH resilience gap: crash mid-prune leaves a stale restic
exclusive lock the controller can't self-heal → subsequent runs fail until
manual unlock. Demo restored to start-state. Track B (quota) + hub-orchestrated
A blocked by session-gating → Peti runbook.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-10 04:32:32 +02:00
admin ecf9185605 validation record: offsite provisioning live e2e PASS (2026-07-09) + CONTEXT/REPORT
Full hub->Hetzner->controller loop validated on demo-felhom against the new
dedicated-project pool box; 2 snapshots on the new box, key-only. F1/F3 fixed
mid-run (hub v0.38.1, controller v0.106.1); F2/F4/F5/F6 recorded open.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-09 22:04:44 +02:00
admin 996d403248 docs(audit): Hetzner API provisioning spike — both offsite models FIT
KEY: Storage Box API is api.hetzner.com/v1 (NOT api.hetzner.cloud/v1). Proven
live on spike-* (torn down): sub-account create/reset/readonly/delete + billable
bx11 box create/change_type/delete. Create takes a password (no ssh-key param) →
transient-pw→ssh-copy-id -s -f→restic reach→reset_subaccount_password (key-only
steady state). RepoPath /home/<repo>; quota levers (dedicated=box type, shared=
readonly+soft-quota); idempotency via label_selector. SECURITY: token is
project-wide unscopeable — can touch ep0 + SSH keys → move customer boxes to a
dedicated Hetzner project. No prod code; spike torn down clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-09 17:46:43 +02:00
admin c1cfbe817b docs(audit): fork-4 custody VALIDATED end-to-end live (supervised)
Full cycle on the demo: enable→stage→real escrow-create (K+restic-pw under a
fresh R, uploaded to hub, staged wiped, K byte-unchanged)→atomicity proof (run
skipped before confirm, proceeded after — gate opens exactly on confirm). DR
money shot: restic password recovered from the PRODUCTION hub blob (via
identity-consume with R) is byte-identical to the live pw (sha 24c44f49) and
decrypted the real box repo; inject→restore endpoints reproduced a 45MB db-dump
byte-perfect. Demo left escrowed (un-paused); R held out-of-band; no secret in
logs; repo_password unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-09 16:31:58 +02:00
admin febdc560f4 docs(audit): fork-4 restic-password custody spike — VALIDATED (escrow-under-R)
Money shot (Probe 3): a password recovered from an age-under-R escrow of the
real repo password DECRYPTED the real Storage-Box repo (listed immich +
audiobookshelf snapshots) — working key, not just byte-match. Probe 1:
round-trip byte-perfect + wrong-R fails closed (0 plaintext). Probe 2:
controller→agent POST-body transport already proven (withGuest) — stage
endpoint is additive. Probe 4: WriteOffboxSecrets honors a pre-placed password
(DR re-injection), but config endpoint carries no password → explicit inject
step needed. All probes throwaway/discarded; live password + repo untouched.
Impl blueprint for the fork-4 spec inside.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-09 14:15:01 +02:00
admin 463ea369c4 docs(audit): offbox v0.104.0 VALIDATED live against the Storage Box (supervised)
Real endpoints, fresh box sub-account. Discovery proof: immich (undeployed,
USB-only unit — the v0.103.0 mis-resolution case) → ok/1 snapshot on the USB
path; 45MB db-dump restore sha256-matched. No-silent-success on the live box:
0/N → error + backup_failed alert; partial → ok + LastWarning. Persists across
restart. Forks 1+2 confirmed (direct; sub-account /home/<name>, ssh-copy-id -s
-f, console key field still broken F3); fork-4 custody surface recorded, escrow
design OPEN (repo pw + key not independently recoverable). Kept as standing
demo-offsite.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-09 13:17:52 +02:00
admin 9b250b97c9 docs(audit): restic→Storage Box direct-from-residential spike (FIT/IPv4)
Validated the controller offbox restic-SFTP tier direct from the residential
demo box (IPv4-only egress) end-to-end through the real endpoints: reach on
:23 (PASS), chown-immune restic init (works where PBS-direct failed),
config→run→restore green, sub-account isolation confirmed. Residential upload
~4.3 MB/s. Concentrator NOT needed. KEY BLOCKER F1: offbox reads recovery unit
from the app data-drive namespace root, not the actual backup-drive location →
silently backs up 0 apps (ok status) on multi-drive setups. Spike only,
synthetic data, torn down.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-09 11:05:36 +02:00
admin 3472b90368 docs(audit): ep0 Hetzner Storage Box SSHFS + PBS-datastore feasibility spike
Wired the 1TB BX11 Storage Box to ep0 as a durable key-auth SSHFS mount
(/mnt/pbs-storagebox, reboot-proven). Findings: direct PBS datastore UNFIT
(box rejects chown -> ChunkStore::create fails); loopback-ext4-on-SSHFS FIT
with caveats (GC 7s/verify 12s/restore 11s all green, no GC hang). Raw mount
~327MB/s write, ~69MB/s read. Spike only, synthetic data, torn down.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-09 09:48:57 +02:00
admin 1a1e42addb docs: campaign-2 R1/R2 root-cause correction + DR bind-mount source spike
Correction: campaign-2's "R1" (bind-mount restore needs root) was a SYMPTOM of an
empty felhom pool -> agent lacked VM.Audit on 9201 -> restore-test's existing,
correct bindMountOverrides never ran. Live-proven: pool healed (Part A) ->
restore-test PASSES (neutralizes 2 binds, boot+running, clean teardown, 4m35s).
Report rec #1 (make pct restore work on bind mounts) superseded. Fixes shipped:
agent v0.74.0 (pool re-assertion), controller v0.103.0 (F-C2-1).

Spike (SPIKE-dr-bindmount-source-2026-07-07): DR bring-up source options — PBS
pct.conf.blob blocked by encryption under the non-root token; DR recipe lacks mpN;
mp8/mp9 are STRUCTURAL CONSTANTS -> recommend a small known-constant override
reusing bindMountOverrides.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-07 19:08:03 +02:00
admin 8e26cdc3a5 docs(audit): closure appendix — F2 closed, F4-UX fixed, healthcheck class fixed
Pilot-blockers bundle shipped + live-validated: agent v0.73.0 (F2 mount-role
fallback), controller v0.102.0 (async restore family, F4 re-adjudicated as a UX
bug not a restore bug), catalog healthcheck sweep. All three accepted live on the
demo node.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-06 20:43:52 +02:00
admin 66b955d054 docs(audit): P1-P3 re-run — accurate end-state + healthcheck-robustness observation
Correct the end-state: uptime-kuma redeployed healthy, notifications restored;
vaultwarden serves (127.0.0.1 /alive 200) but reads docker-unhealthy due to a
localhost->IPv6 healthcheck probe quirk (reproduced on fresh redeploy);
bookstack unhealthy at app level (HTTP 500, pre-existing). Recommend catalog
healthchecks use 127.0.0.1 not localhost. Neither is a P1-P3 defect.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-06 19:28:15 +02:00
admin 1b19377f84 docs(audit): targeted P1-P3 backup/restore acceptance re-run (2026-07-06)
Pilot-gap CLOSED: F3 volume-tar backup (incl. volume-only apps, bit-identical),
vaultwarden restore drill (bit-identical), Tier-2 additive-only restore, off-box
SFTP round-trip — all proven on v0.101.0 + F1-fixed template with real data on a
healthy app set. Full F1-fix acceptance. F4 resolved as NON-bug (restore is a
long synchronous op; traefik proxy read-timeout returns 000/502 while the
controller completes it). ZERO product bugs in P1-P3; ~18 throwaway-harness bugs
fixed (path/sha/DB-client/proxy-timeout/test-ordering). No production code changed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-06 19:21:58 +02:00
admin 3eb31f50d6 docs(audit): findings triage addendum — F1 corrected root cause + F2 verdict + F3 fixed
F1: original "shim sets SMTP_FROM w/o SMTP_HOST" hypothesis was WRONG (shim
injects nothing when off) — real cause is defined-empty SMTP vars + upstream
_enable_smtp default true → crash; fixed via _ENABLE_SMTP gate (catalog),
live-validated. F2 verdict: REAL finding — roleForMountPath resolves an enrolled
user-data drive that isn't a PVE storage to system (fail-safe over-refusal)
while /disks calls it user-data; agent-side fix deferred. F3: fixed in
controller v0.101.0 (git subprocess deadline).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-06 14:25:34 +02:00
admin 658e78d495 docs(audit): no-mercy full-system campaign report (2026-07-06)
Overnight unattended stress/regression on the demo node (9201). Platform
resilience + safety strong: all fault-recovery + reboot/hard-reset recovery
passed (58-126s; sysrq hard reset 103s), 2.5h soak 0 breaks, DR restore proven
sound. Raw 25 FAIL triaged: ~10 collateral of one app finding (F1 vaultwarden
SMTP crash-loop), ~8 harness mis-scores of correct product refusals
(single-flight 409, needs-confirmation), rest harness-calibration incl. the P9
volid-format bug (DR mechanism itself works - recovered 9201 manually from R1).
Genuine findings: F1 vaultwarden SMTP_HOST (HIGH), F2 decommission agent-403
(MED), F3 gitea-outage sync recovery (MED). No production code changed; demo
left running+healthy at R1, notifications restored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-06 12:23:12 +02:00
admin 2f97ce31dd docs(audit): dedicated felhom-sshd instance spike (2026-07-05) — GO
Validates a second sshd (own port/config/host-key/AuthorizedKeysFile/unit) as
Felhom's OOB entry point, coexisting with the customer's stock sshd on :22:
robust port probe-and-claim (skip/idempotent/loud-exhaustion), four-axis
coexistence independence, tunnel-scoped nft, reload-gate robustness, operator
identity isolated via AuthorizedKeysFile location, clean uninstall.

#1 TASK constraint (caught live): a second sshd unit must NEVER declare
RuntimeDirectory=sshd — it removes the SHARED /run/sshd privsep dir on stop and
takes the stock sshd down (LAN SSH lockout; recovered via PVE console + mkdir
/run/sshd). Use a tmpfiles.d entry instead. All spike artifacts removed; baseline
re-verified.

Docs-only; no code/hub/agent/manifest change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-05 18:18:37 +02:00
admin 2db92c8837 docs(audit): OOB-over-WG operator-peer spike (2026-07-05) — GO
Validates operator-inbound access over the existing offsite WG arc (doc 06):
operator peer forwarded operator->box only, box sshd gated to the operator /32,
§4.5 box<->box isolation intact (both negatives counter-proven), mutual repair
real (agent self-healed a stopped tunnel in ~15s unaided). One TASK-shaping gap:
the operator /32 must be a RENDERED conf field — a runtime `wg set` is wiped by
the agent's own self-heal. All live-arc changes reverted + baseline re-verified.

Docs-only; no code/hub/agent/manifest change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-05 17:01:35 +02:00
admin 582917d12d docs(audit): SPIKE — agent self-update rollback mechanics (systemd 257 semantics on felhom-pve)
GO with two design-reshaping surprises: OnFailure= fires on EVERY crash on
systemd 257 (rollback triggers at first post-apply crash; marker-guard +
idempotency mandatory), and deliberate restarts consume start-limit budget.
S1 trap confirmed (default shape never reaches failed — 35 starts/180s);
tuned [Unit] StartLimitIntervalSec=120 + Burst=4 → failed in ~20s;
[Service] placement is an asymmetric half-applied trap; reset-failed required.
S2: all restart variants reliable, detached systemd-run wins. S3: A/B flip
atomic under kill -9, all verbs + guards pass. S4: StateDir + sudoers shapes OK.
Dummy artifacts only; real agent uptime unchanged (verified).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-05 14:45:58 +02:00
admin cf1a9402f2 docs(audit): app-data restore drill 2026-07-04 (guest 9201)
Keep-side restore validated live: class-A DB replay, fail-closed data-key
gate + proven non-destruction, resettable-secret discrimination, Tier-2
class-C copy, and guardrails (traversal/missing/single-flight/restart).

Findings: F1 (HIGH) UI restore dead — /api/backup/snapshots has no handler;
F2 no one-click in-place class-C restore; F3 named-volume data never backed
up (DumpAppVolumes* has no caller).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-04 22:53:07 +02:00
admin bf099f6a10 docs: SPIKE — offsite-backup connectivity: plain WireGuard wins the ladder (transport decision made)
P0-P7 probe ladder on real ends (demo-felhom PVE host <-> throwaway Hetzner).
Verdict: GO at H1 — plain host-side WG, box-dials-out to a small public endpoint;
Headscale is a separable fleet layer, not a traversal necessity. Line is plain-NAT
(not CGNAT) with zero IPv6 — recorded honestly; CGNAT vantage deferred to Peti VM 110.
Real 2 GiB worst-case PBS backup over the tunnel at the full home uplink, pin intact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-03 22:04:51 +02:00
admin 7ad111cfb5 docs: golden 0.98.3 live — D.1b retired, drill B1/B5 fixed, backlog note resolved + evidence doc
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-03 18:38:28 +02:00
admin 2e33a8b86b docs: D.1b narrowed + drill B2/B3 marked FIXED (agent v0.63.0)
Restart-the-agent step in day0-install.md is now conditional on agent <
v0.63.0 (reload-on-miss shipped; Day-0 manifest still vouches 0.62.0).
Troubleshooting row + drill ledger + go/no-go item 8 updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-03 17:27:39 +02:00