Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
12 KiB
CONTEXT — felhom.eu working state
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 inREPORT.md.
-
2026-07-05 — TASK G1 SHIPPED: management-plane break-glass (hub v0.34.1 + installer; agent v0.71.0) — prereq for felhom-sshd (H1). Hub:
store.host_recoveryvault (per-host root@pam console password;PUT /hosts/{id}/recovery-credentialself-scoped +GET /admin/hosts/{id}/ recovery-credentialglobal-only, secret never logged) +host_mgmtplanemonitor raisingmgmt_plane_healed. Installer:step_break_glass(generate+set+vault root@pam,--rotate-recovery)install_mgmt_watchdog(the 3 host artifacts, RuntimeDirectory-guarded). Live-validated: agent-independent/run/sshdauto-heal in 30.0s; warning fired end-to-end; break-glass vault→retrieve→PVE-ticket(200). felhom-pve root@pam is now the vaulted value.
-
2026-07-04 — S3 SHIPPED: agent WG tunnel (felhom-agent v0.64.0; docs-only here) — the doc-06 §3.3 handshake is now END-TO-END LIVE on demo: agent keygen →
POST /hosts/{id}/wg→ desired-statewireguardblock → agent-managedwg-quick@wg-felhom→ PBS page over 10.77.0.1:8007 in 3 s.wg_tunnel.enableddefaults FALSE agent-side (rollouts to other boxes are no-ops until the production endpoint exists). Revocation semantics completed (§3.5): removed peer → agent disables + keeps its marker + NEVER re-registers; operator re-adds via the pubkey the heartbeat report now carries. Escrow:IdentityBundle.WGPrivateKeyauto-injected on new escrow-create runs (pre-S3 blobs can't be retrofitted — honest fallback = fresh-key re-register, /32 kept). OPEN: CGNAT/mobile-hotspot smoke (operator-assisted appendix, deferred non-blocking); S4 = PBS over the tunnel; hub-side S6 = tunnel-health alerting on the new report stanza. Detail: felhom-agent CHANGELOG v0.64.0 + REPORT. -
2026-07-04 — S2 SHIPPED: box-facing WG registration + wireguard desired-state block + /offsite UI (hub v0.33.0) — doc-06 row S2. DECISIONS: the WG assignment is hub-owned state, merged into served desired-state at READ time — stored
desired_jsonstays a pure operator blob; admin PUT with a top-levelwireguardkey → 400 (no copy-paste clobber); re-key-in-place keeps the /32 (stable tunnel addressing across rotation/DR); one bound peer per host (partial unique index); generation bumps ONLY on real change (register/re-key/adopt/bound-delete — idempotent paths move nothing).POST /hosts/{id}/wgself-scoped per-host key; NEW goldendesired-state-wireguard.golden.json= the S3 cross-repo contract (byte-identical agent copy rule). peersync v1.0.1 (strip out of process substitution — the S1 exit-swallow finding; sandbox red-proofed) redeployed to the dev endpoint. Live-proven on the REAL demo-felhom-01 record via the real per-host key: gen 2→3, served block = golden shape, endpointwg showcarried the peer, v0.63.0 agent tolerated the unknown key (fetch clean, guests untouched), then removed → gen 4, all baselines restored./offsitepage unit-proven (live view is operator-password-gated — eyeball after next login). Next: S3 (agent keygen + registration +wg-felhomservice + escrow join + CGNAT smoke — risky/supervised). -
2026-07-04 — S1 SHIPPED: offsite endpoint live + hub peer-sync (hub v0.32.1) — the doc-06 roadmap's first slice, done-criterion met live. Peer-sync design point RESOLVED: hub pushes over SSH to a forced-command
felhom-peersyncscript (pull rejected: weakens immediate revocation; HTTPS API rejected: new binary + third public port). Endpoint = the devfelhom-hetznerbox, provisioned by the NEW runbookdocumentation/runbooks/offsite-endpoint.md(WG on 443/udp, subnet 10.77.0.0/24, PBS datastorefelhom-offsiteat/srv/pbs-felhom, nftables drop-all + wg0-only 8007,ep0.felhom.eugrey-cloud). Hub:wg_endpoints/wg_peers+ /32 allocator +/admin/wg/*(global-key, pubkey-in-body) +internal/wgsync(FixedHostKey pin- pinned-type HostKeyAlgorithms — live-caught bug: multi-hostkey sshd presented ECDSA vs the
ed25519 pin; fixed v0.32.1 + regression test) + full-list declarative reconciler (5-min drift
repair). Live: add/remove→wg show, malformed→state-untouched, reboot→persist+converge, client
tunnel via ep0:443→PBS login page, public 8007 closed. INCIDENT handled: first WG server key
leaked via
wg show dumpinto the session log → rotated immediately (warning now in the runbook). OPERATOR follow-up: fix the AAAA record (currently…7aa1::, must be…7aa1::1). Next: S2 (hub schema host-join +wireguardblock on WireDesiredState + box-facing registration + UI).
- pinned-type HostKeyAlgorithms — live-caught bug: multi-hostkey sshd presented ECDSA vs the
ed25519 pin; fixed v0.32.1 + regression test) + full-list declarative reconciler (5-min drift
repair). Live: add/remove→wg show, malformed→state-untouched, reboot→persist+converge, client
tunnel via ep0:443→PBS login page, public 8007 closed. INCIDENT handled: first WG server key
leaked via
-
2026-07-03 — OFFSITE-CONNECTIVITY DESIGN-OF-RECORD WRITTEN (architecture Part 06) —
documentation/architecture/06-offsite-connectivity.md: records the six settled decisions (plain WG / host-side agent-managedwg-felhomas the agent-managed-unit PILOT / one shared hub-driven endpoint VM running WG+PBS, NO agent on it / hub = source of truth,wireguardblock ridesWireDesiredStateon the existing DesiredGeneration channel / one datastore + per-customer namespaces / PBS ON the VM, relay-through-DooPlex REJECTED as non-scaling), the Day-0 join handshake, robustness set (WG-roaming-not-DynDNS, DNS re-resolve watchdog, MTU 1420, per-/32 isolation, tunnel-health via storage-target model), trust conformance (outbound only; operator-inbound + game-ingress out of scope), the honest ledger (CGNAT still unmeasured — mobile-hotspot smoke closure; peer-sync push-vs-pull = slice-1 design point), and the S1–S6 slice roadmap (MVP = S1 endpoint + S2 hub schema/desired-state + S3 agent WG service, then S4 PBS-over-tunnel; S5 merges with DR-completeness). day0-install backlog line now cites spike + design doc. Docs-only; slices are separate future tasks. -
2026-07-03 — OFFSITE-BACKUP TRANSPORT DECIDED (connectivity spike, GO at the lowest rung) — plain WireGuard, host-side, box-dials-out to a small public endpoint; no Headscale/DERP needed for backup (separable fleet layer, adoptable later). Live-proven on demo-felhom → throwaway Hetzner: 11.4-min idle hold, PBS API through the tunnel with the exact-cert pin intact (positive + negative), real 2 GiB worst-case backup at 4.26 MiB/s (= the home uplink; tunnel overhead ~5%), UDP 51820 and 443 both pass. P0 honesty: the operator's line is plain-NAT (fixed public IP, One Hungary), NOT CGNAT, and has zero IPv6 — CGNAT confirmation deferred to Peti's VM 110 (second ISP). P7 surprise: kernel WG works inside the unprivileged guest (no TUN needed) — host placement stands on architecture (backups originate host-side; cloudflared precedent), not infeasibility. Evidence + architecture recommendation (endpoint VM shapes, key custody via IdentityBundle escrow, per-peer /32 isolation):
documentation/audits/SPIKE-connectivity-wireguard-2026-07-03.md. This unblocks the DR-completeness work: next task = production connectivity spec (endpoint VM, agent-managed WG service, hub peer registry, escrow join). Throwaway Hetzner box parked powered-off (secrets shredded); demo-felhom verified residue-free. -
2026-07-03 — 4th skill:
felhom-app-catalog(catalog authoring workflow; points at app-catalog REUSE.md §1–2, no duplicated tables; auto-discovered byinstall_skills.py, 4/4 found fresh-session). Proven by finalizing SparkyFitness live on demo (image-inspected healthchecks, probe-container naming rule discovered + REUSE row added, UI-applied, controller probe healthy). App-count drift recorded: website says "45+", per-category spans sum 49, real catalog 53 — website fix is a separate task. -
2026-07-03 — GOLDEN 0.98.3 LIVE + VOUCHED; guide D.1b RETIRED (drill B1+B5 FIXED) —
build-golden.shv2.0.0 (mandatory controller tag + baked bootstrap.pathunit); golden baked with controller 0.98.3, clean-room validated (drill VM) through all four scenarios incl. the published-artifact--force-gitea-goldenpath, published + operator-vouched (Day-0 manifest now: agent 0.63.0 + golden 0.98.3). Fresh installs land CURRENT and self-manage — D.1b is a one-line check; the prior "vouch agent 0.63.0" operator follow-up is DONE. Evidence:documentation/audits/DRILL-golden-098-2026-07-03.md. NEW operator follow-ups: (1) SECURITY — the customer-configgit.tokenis a Gitea admin token with package-WRITE (proven during the bake); scope down + rotate. (2) optionally raise the global controller floor to 0.98.3. -
2026-07-03 — drill findings B2+B3 FIXED (agent v0.63.0, live on felhom-pve + published) — token reload-on-miss (no more fresh-install 401/manual restart) + guesthook snippets-dir mkdir. Guide D.1b restart step narrowed to "agent < v0.63.0"; drill ledger updated. OPERATOR: vouch agent 0.63.0 in the Day-0 manifest UI (until then fresh installs fetch 0.62.0).
-
2026-07-03 — GO-LIVE PACKAGE SHIPPED (host-install v1.9.1 + day0-install runbook + clean-room drill) —
documentation/runbooks/day0-install.mdis the operator Day-0 guide, every command executed verbatim on a throwaway nested PVE 9.2.2 (build server): install → verify → app deploy → uninstall → zero-residue diff → reinstall. v1.9.1 = residue-free uninstall (agent config w/ hub api_key, shared-parent unit/script/mount, mkfs wrapper, hook snippet, dnsmasq snippets) + post-provision guest reboot (without it the controller never deploys on slower hardware) + header sync. Evidence + go/no-go for Peti (GO, 3 install-day items):documentation/audits/DRILL-day0-cleanroom-2026-07-03.md. Key OQ-2 finding: golden bakes a pre-floor controller 0.85.1 → fresh installs need the one-time D.1b update (agent restart → update button → 0.98.3); follow-ups recorded: rebuild golden ≥0.86.0 + re-vouch (operator), agentmkdir -pfor the guesthook snippet dir, fresh-install local-API 401 (pre-existing), hub has no host-delete path. Drill VM parked virgin-snapshotted on 180 (~/drill/). -
2026-07-03 — A1 CLOSED (host-install v1.9.0 + agent v0.62.0) —
Pool.Auditadded toFelhomAgentGuest; the agent's stale-lock reaper now intersects its scan withGET /pools/felhommembership (fail-safe skip on read failure). Spike:documentation/audits/SPIKE-a1-pool-membership-read-2026-07-03.md. Deploy order on any box: rescope ACL first, then the agent. STILL PENDING (operator): rotate + de-git the 3 committed secrets inmanifests/felhom.secret.yaml(spike appendix; REUSE §2 errata added). -
2026-07-03 — hub v0.31.0 LIVE (critical-severity ingest fix + UI badges; ArgoCD Synced/Healthy; live probe: critical event stored + operator email delivered).
-
2026-07-03 — Felhom skills exist:
skills/{felhom-build-deploy,felhom-ui-design,felhom-testing}, installed viascripts/install_skills.py— junction mode (repo edits live immediately; no re-install needed after editing). Fresh-session discovery verified. -
2026-07-03 — CLAUDE.md refreshed (all four repos): no version-pinned state in CLAUDE.md — current state lives here / CHANGELOG / REUSE.md.
-
2026-07-03 —
REUSE.mdexists at the repo root (hub helpers / website conventions / gate scripts / manifest patterns, code-verified); maintenance rule active: update it in the same commit that changes a shared helper.scripts/reuse_refs_check.pymachine-checks its citations across all four felhom repos.