Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
5.4 KiB
RUNBOOK — Peti PBS DR tier enable (the epic's payoff) — 2026-07-11
State when written: agent 0.80.0 published (sha
f2ba62ca6aca6e24a8d08706ea0dc3ae43940a63e9bdf57d4606ad1756cf06d2, anon round-trip verified; the demo runs the IDENTICAL bytes, adoption-proven). Hub v0.44.0 live; ep0 tenantsync surface live. Peti's box:peti-felhom-86d37d, agent 0.79.0, wg_tunnel DISABLED (no WG peer registered), OOB DISABLED — the box-side steps below need root ON the box (Peti's hands, supervised, per the tester agreement; there is no OOB path to it today).Roles: [PETI-root] = paste-block run as root on his box (Viktor supervising), [VIKTOR] = operator secrets (opsign key, hub global key, hub UI), [CC] = watches/asserts.
1. [PETI-root] Box prep: new sudoers + wrapper + tunnel enable (BEFORE the self-update)
The self-update ships ONLY the binary — the slice-2 sudoers alias (FELHOM_PBSDR) + the
felhom-pbs-apply wrapper must land beside it. Order sudoers/wrapper FIRST (inert under 0.79.0).
# 1a. fetch the two files from the felhom-agent repo at main (raw), install guarded:
cd /root
for f in configs/felhom-agent.sudoers configs/felhom-pbs-apply; do
curl -fsSL "https://gitea.dooplex.hu/admin/felhom-agent/raw/branch/main/$f" -o "/root/$(basename $f).staged" \
|| echo "FETCH FAILED — repo not public; use the paste-block Viktor provides instead"
done
tr -d '\r' < /root/felhom-pbs-apply.staged > /root/felhom-pbs-apply.clean
bash -n /root/felhom-pbs-apply.clean
install -o root -g root -m 0755 /root/felhom-pbs-apply.clean /usr/local/sbin/felhom-pbs-apply
tr -d '\r' < /root/felhom-agent.sudoers.staged > /root/felhom-agent.sudoers.clean
visudo -cf /root/felhom-agent.sudoers.clean # MUST print "parsed OK" before install
install -o root -g root -m 0440 /root/felhom-agent.sudoers.clean /etc/sudoers.d/felhom-agent
rm -f /root/felhom-pbs-apply.* /root/felhom-agent.sudoers.*
# 1b. enable the offsite tunnel (wgtunnel is default-off; the bridge needs it):
python3 - <<'EOF'
import json
p="/etc/felhom-agent/agent.json"; c=json.load(open(p))
c.setdefault("wg_tunnel",{})["enabled"]=True
json.dump(c,open(p,"w"),indent=2)
EOF
chown felhom-agent:felhom-agent /etc/felhom-agent/agent.json && chmod 0600 /etc/felhom-agent/agent.json
systemctl restart felhom-agent
[CC] asserts after 1: hub wg_peers gains a row bound to peti-felhom-86d37d (the agent
self-registers); peersync pushes it to ep0 (wg show wg0 there lists the new peer); the box's
report grows the wireguard stanza; wg-handshake-read capability goes green once
wireguard-tools is installed by the bring-up (this is the degradation the tier clears).
2. [VIKTOR] Signed self-update 0.79.0 → 0.80.0 (the GL-6-proven one-command shape)
felhom-opsign -op agent_update -host peti-felhom-86d37d -key-id felhom-op-1 \
-agent-version 0.80.0 \
-sha256 f2ba62ca6aca6e24a8d08706ea0dc3ae43940a63e9bdf57d4606ad1756cf06d2 \
-key <operational private key> -upload https://hub.felhom.eu -hub-key <report_api_key>
(-hub-key = the hub's report_api_key — the global/operator key, NOT the web login; GL-6 note.)
[CC] asserts after 2: box journal: gate allowed=true → anon Gitea download → sha re-verify →
A/B flip → dwell → update committed version=0.80.0; report shows agent 0.80.0 and the pbsdr
capabilities (62 total expected) green; pbsdr: bridge enabled in the journal.
3. [VIKTOR, hub UI] Enable the tier: Customers → peti-felhom → PBS DR tier (ep0)
Enable checkbox ON, storage id felhom-pbs (the default — his box has no prior entry). Save.
What must happen, in order (the fresh path — [CC] watches every link):
- hub:
tenantsync: provision ok for peti-felhom (ns=peti-felhom, …)— ep0 namespace + token born over the SSH surface; secret staged consume-once forpeti-felhom-86d37d; generation bump. - box (≤60s after its next envelope): bridge fetches the descriptor → verify-pin BEFORE
consume (PBS fingerprint over the tunnel, 10.77.0.1:8007) → consume (hub marks
consumed_at) →felhom-pbs-apply create(secret on stdin) → K born at /etc/pve/priv/storage/felhom-pbs.enc → dual-grant → post-probe active →escrow.pbs_storage_id=felhom-pbsseeded →pbsdr: converged state=applied. - report stanza
pbs_dr: {state: applied};pvesm status --storage felhom-pbsactive on his box.
4. [PETI-root] THE CEREMONY (RUNBOOK-escrow-ceremony; the bare one-liner — no flags needed)
felhom-agent --selftest=escrow-create --upload
Fresh R printed EXACTLY ONCE — Peti keeps it (paper; it supersedes his go-live R). The
upload triggers the hub's auto-confirm chain (slice 3 precedent): offsite pending → escrowed,
then the first offsite run.
[CC] asserts after 4: hub host_escrow row updated for peti-felhom-86d37d (fresh
key_fingerprint + created_at); escrow/auto-confirm state green; first offsite/DR-tier artifacts
visible. Nobody but Peti sees or stores R.
Abort/rollback notes
- Any failure BEFORE step-3's consume: retry-safe (nothing burned). A
consumed_failedreport state after it = the hub "Re-issue PBS credentials" button (fresh secret; the bridge recovers). - The self-update has crash-rollback armed (
.prevretained; GL-6 proven both directions). - NO deletion path exists anywhere in the new surface (set-only law) — a misconfigured entry is
pvesm set-corrected, never removed.