diff --git a/documentation/pilot/RUNBOOK-publish-0.79-0.110-2026-07-10.md b/documentation/pilot/RUNBOOK-publish-0.79-0.110-2026-07-10.md index 003ca96..baa54aa 100644 --- a/documentation/pilot/RUNBOOK-publish-0.79-0.110-2026-07-10.md +++ b/documentation/pilot/RUNBOOK-publish-0.79-0.110-2026-07-10.md @@ -1,17 +1,17 @@ -# RUNBOOK — publish train agent 0.79.0 + golden 0.110.0 + floor (2026-07-10) — PARTIAL (B done, C blocked) +# RUNBOOK — publish train agent 0.79.0 + golden 0.110.0 + floor (2026-07-10) — A/B/C DONE, D/E operator-gated -**Class:** publish/signing runbook (GL-1 pattern). **Status:** Phase A shipped; **Phase B COMPLETE**; -**Phase C BLOCKED** on the un-captured drill-VM launch command; Phases D/E pending C + operator saves. -No credential/signature-key material in this record. +**Class:** publish/signing runbook (GL-1 pattern). **Status:** Phases A, B, **C COMPLETE** (agent + golden +both published + verified; drill VM restored to virgin); **Phase D = the operator handoff** (one UI save + +the floor bump); Phase E qualified (demo already on 0.110.0). No credential/signature-key material here. -## The operator values so far (for the hub Day-0 manifest, GL-1 style) +## The four operator values (hub Day-0 manifest → Configs → Day-0 artifacts) — READY ``` AGENT_VERSION=0.79.0 AGENT_SHA256=35a162547646737ebef265f5ad69d042e897914f6ca799c007872d1c3cd27561 -GOLDEN_VERSION=0.110.0 (pending Phase C bake) -GOLDEN_SHA256= -FLOOR=0.110.0 (pending Phase D) +GOLDEN_VERSION=0.110.0 +GOLDEN_SHA256=1593597d98af61d94c4923cfd526e444e038aa21bd63ddc4e89067f5f010f3d4 +FLOOR=0.110.0 ``` ## Gate outcomes @@ -26,9 +26,23 @@ FLOOR=0.110.0 (pending Phase D) | C-0b drill VM | **PASS** | `~/drill/drill.qcow2` on 180, internal snapshot `virgin` (2026-07-03) intact | | C-0c controller image | **PASS** | `docker manifest inspect …/felhom-controller:0.110.0` OK on 180 | | C-0d headroom | **PASS** | 196 G free on 180 (golden ≈ 0.6 G); virgin snapshot 0 B | -| **C-2a boot drill VM** | **BLOCKED** | the canonical `qemu-system` launch command is NOT captured anywhere (not in ~/drill, no launcher/unit/history; audits give only parameters — 4 vCPU/8 GiB/150 G qcow2, /dev/kvm, slirp `dhcpstart=10.0.2.30`, hostfwd 2222→10.0.2.15:22). Reconstructing it = improvising the bake (runbook-forbidden) + risks the virgin snapshot. **Needs the operator's launch one-liner OR explicit go-ahead to reconstruct as a recorded deviation.** | -| D — manifest + floor | **PENDING** | 🛑 two hub UI saves (needs C's golden sha) | -| E — demo self-update proof | **PENDING** | downstream of D | +| C-2a boot drill VM | **PASS (reconstructed — DEVIATION)** | operator authorized reconstruction; `qemu-img snapshot -a virgin` then `qemu-system-x86_64 -enable-kvm -cpu host -smp 4 -m 8192 -drive …drill.qcow2,if=virtio -netdev user,…dhcpstart=10.0.2.30,hostfwd=tcp::2222-10.0.2.15:22 -display none -daemonize`; PVE 9.2.2 up + SSH on :2222 in ~10 s (virtio bus correct); gitea 200 from inside; debian-13 template absent on virgin → `pveam download` (checksum OK) | +| C-2b bake + publish | **PASS** | `build-golden.sh` v2.0.0 as root@pam in-VM (transient `systemd-run --unit=golden-bake`), baking `felhom-controller:0.110.0`: `docker OK (overlay2; data-root /var/lib/docker)`, all 3 mounts included (rootfs+mp0+mp1, NO exclusions/FATAL), archive 583 MB, upload **HTTP 201**, `GOLDEN_VERSION=0.110.0` + sha printed; in-VM token-leak grep 0 | +| C-3b golden fetch | **PASS** | **anonymous** GET → 200, **611 696 157 bytes**, sha256 == GOLDEN_SHA256; off-LAN HEAD 200 | +| C-teardown | **PASS** | build guest 9100 `--purge`d; `/root/.gitea-token`+script+log shredded; VM powered off; qcow2 reverted to `virgin` (snapshot intact, no qemu); saved-log token-leak grep (literal token) = **0**; `~/drill/bake-0.110.0.log` retained next to priors | +| **D — manifest + floor** | **OPERATOR** | 🛑 one hub UI save (artifact manifest) + the floor bump — see handoff below | +| E — demo self-update proof | **QUALIFIED** | the demo is ALREADY on 0.110.0 (manually deployed in the C2 task), so the floor-driven 0.109.1→0.110.0 self-update can't be demonstrated on it; the Day-0 DRY proof (anon-fetch BOTH artifacts + sha-verify) is DONE + green above (what Peti's installer does) | + +## Phase D — operator handoff (order matters: manifest BEFORE floor) + +1. **🛑 Viktor — artifact manifest (DB-backed operator UI, session-gated — CC cannot):** hub → Configs → + Day-0 artifacts → Agent **0.79.0** / sha `35a1625476…d27561`, Golden **0.110.0** / sha `1593597d98…f010f3d4` + → Save. (The sha the UI auto-reads must equal these.) +2. **Global floor 0.87.0 → 0.110.0 — AFTER the manifest save.** This is the `DEFAULT_MIN_CONTROLLER_VERSION` + env in `manifests/hub.yaml` (GitOps, NOT session-gated) — CC can bump it via commit+ArgoCD sync once + Viktor confirms the manifest is saved (respecting the order rule: never raise the floor before the + manifest vouches the target). Or Viktor sets it. Effect: any box below 0.110.0 auto-updates next report + (the demo is already there → no-op; Peti's future box lands current). ## Signing note (correcting the runbook's Phase-B assumption) @@ -41,20 +55,32 @@ So Phase B correctly required **no operator signature** — integrity for day-0 hub-manifest sha (Phase D) + anonymous fetchability (proven above). Nothing for Viktor to sign in this train unless/until a managed agent_update is triggered. -## Blocker → what's needed to resume (Phase C onward) +## READY-FOR-PETI checklist -To bake + publish golden 0.110.0 the drill VM must be booted, and the exact launch invocation was a manual -one-liner never saved. **Two ways forward (operator picks):** -1. Provide the `qemu-system-x86_64 …` launch command used for `~/drill/drill.qcow2` (revert-to-`virgin` + - boot with the slirp/hostfwd netdev), and CC resumes C→E autonomously. -2. Authorize CC to reconstruct it from the documented parameters (recorded as a deviation) — CC will - snapshot-revert to `virgin` first (non-destructive: `qemu-img snapshot -a virgin`), boot read-safe, and - abort if the guest doesn't come up cleanly. +| Item | State | +|---|---| +| Agent 0.79.0 published + anon-fetchable + sha-verified | ✅ (sha `35a1625476…d27561`) | +| Golden 0.110.0 published + anon-fetchable + sha-verified | ✅ (sha `1593597d98…f010f3d4`, 611 696 157 B) | +| Both artifacts fetch ANONYMOUSLY (what Peti's installer does) | ✅ (off-LAN HEAD 200 both) | +| Agent self-update signature path armed vs the pinned key | ✅ (pinned in GL-4 v1.11.1; signed round-trip proven GL-6) | +| Hub artifact manifest vouches 0.79.0 / 0.110.0 | ⏳ Phase D.1 (🛑 Viktor UI save) | +| Global floor at 0.110.0 | ⏳ Phase D.2 (GitOps, after D.1) | +| Demo on 0.110.0 | ✅ (already deployed; escrowed offsite intact) | +| Peti hub-side provisioning armed | ✅ (sub-account 269130, descriptor+fingerprint served, one-time secret unconsumed) | -Then Phases D (🛑 two UI saves) + E (demo floor self-update proof) follow, and the READY-FOR-PETI checklist -is completed. +## Deviations from the letter of the runbook -## Follow-ups already known for the checklist (Phase E) +- **Phase B needed NO operator signature** (the runbook assumed one). `publish-agent.sh` doesn't sign; + the integrity root is the SHA256 (`selfupdate/executor.go`) + the hub-manifest sha (Phase D). The + operator-signed `agent_update` is a RUNTIME managed-update concern (GL-6 proved it), not publish-time — + same as the GL-1 precedent (its Phase B was 404→201→sha, no signing). +- **Phase C drill launch RECONSTRUCTED** (operator-authorized): the canonical `qemu-system` one-liner was + never saved; reconstructed from the audits' parameters (recorded above); virtio bus + slirp/hostfwd + booted cleanly first try; virgin snapshot reverted afterwards, exactly as found. +- **Phase E qualified:** the demo was already on 0.110.0 (C2 task), so the floor-driven self-update proof + isn't demonstrable on it; the anon-fetch Day-0 dry proof stands in (a stronger fetchability proof). + +## Install-window items for Viktor (NOT this train — the Peti install session) - Two install-form items for the Peti window (NOT this train): cores 8 vs 12/16 (confirm with Peti); `--acl-storages` for his storage layout. - Send Peti the retrieval passphrase out-of-band; recommend `--preflight-only` first.