Files
felhom.eu/documentation/pilot/RUNBOOK-GL1-publish-2026-07-07.md
T
admin a63cc7151b docs(pilot): RUNBOOK GL-1 executed — agent 0.74.0 + golden 0.103.0 published
Agent = the live felhom-pve bytes (sha 1ec3f588..76af05, round-trip verified);
golden baked clean-room in the drill VM (build-golden v2.0.0, controller
0.103.0, all integrity gates green, sha 8481e8a1..6026e) and published 201.
Both anon-fetch-verified (Gate 3c: packages world-readable -> G3 read-only
token rotation cannot break fetches; installer-side empty-token die is the
real precondition). Drill VM restored to virgin. OPERATOR NEXT: Day-0
manifest bump to the four recorded values.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-07 21:07:15 +02:00

5.8 KiB

RUNBOOK GL-1 — execution record: publish agent 0.74.0 + bake/publish golden 0.103.0 (2026-07-07)

Class: runbook execution (go-live item G1, partial). No code changes, no version bumps. Production touched read-only (felhom-pve: one scp out + --version/readlink; build server: normal kisfenyo work + drill-VM lifecycle). All root actions inside the disposable nested drill VM. No credential appears in this record; publish creds were sourced on the build server (~/.gitea-token, user admin) and the in-VM copy was shredded before poweroff.

The four operator values (hub Day-0 manifest → Configs → Day-0 artifacts)

AGENT_VERSION=0.74.0
AGENT_SHA256=1ec3f58842edce1e9e32d022eaef15b7ff599c658c7a36bfe7833c708076af05
GOLDEN_VERSION=0.103.0
GOLDEN_SHA256=8481e8a14e2aa0abe3831cc40e5aea4c32f2017e7561c15dca8a674df6a6026e

Gate outcomes

Gate Result Evidence
0a baselines PASS felhom-agent ced60ddf (v0.74.0), felhom-controller 59eb3bea (v0.103.0), felhom.eu 02d63ed0; published state pre-run: agent 0.63.0 = 200 / 0.74.0 = 404, golden 0.98.3 = 200 / 0.103.0 = 404
0b drill VM PASS ~/drill/drill.qcow2 on 192.168.0.180 with internal snapshot virgin (2026-07-03) intact
0c controller image PASS docker manifest inspect gitea.dooplex.hu/admin/felhom-controller:0.103.0 OK on the build server
0d headroom PASS 213 G free on 180 (golden ≈ 0.6 G); VM local-lvm 76 G thin, 0% used post-virgin
1a running binary PASS felhom-pve readlink /proc/$(pidof felhom-agent)/exe/usr/local/bin/felhom-agent, --version → 0.74.0; selfupdate state dir EMPTY (no pending A/B marker)
1b agent publish PASS the LIVE bytes (sha identical across felhom-pve→CC→180 hops) published via publish-agent.sh 0.74.0 from main@ced60ddf: pre-delete 404, PUT 201, round-trip GET sha match
2a drill VM ready PASS virgin-restored + booted (slirp dhcpstart=10.0.2.30 + hostfwd 2222→10.0.2.15:22, per DRILL precedent); PVE 9.2.2 responsive; gitea HTTP/2 200 from inside; debian-13 template ABSENT on virgin (expected) → pveam download inside, checksum verified
2b bake + publish PASS build-golden.sh (main@ced60ddf, script v2.0.0) as root@pam in-VM, baking felhom-controller:0.103.0; transcript: docker OK (overlay2; data-root /var/lib/docker), both /var/lib/docker + /mnt/sys_drive separate ext4 mounts, including mount point rootfs+mp0+mp1 (NO exclusions, no FATAL), archive 583MB, publish upload HTTP 201, GOLDEN_VERSION=0.103.0 + sha printed. Token-leak grep over the transcript: 0 hits
3a agent fetch PASS ANONYMOUS GET → 200, sha256 == AGENT_SHA256 (from the build server; HEAD 200 from the CC machine off-LAN too)
3b golden fetch PASS ANONYMOUS GET → 200, 611 696 321 bytes, sha256 == GOLDEN_SHA256 (streamed to disk, hashed, deleted)
3c read-token finding see below

Gate 3c — read-credential finding (feeds G3)

The specified reviewer read-only token (8417…4140) was not locatable by CC (not in the repos, not on the build server under any evident name). The gates were instead run with no credential at all — and passed: both generic packages are anonymously world-readable (deliberate posture; the agent's self-update and guest 9201's image pulls already rely on anon Gitea reads; integrity comes from the hub-manifest sha, not transport auth). Consequences:

  • A read-scoped token is trivially sufficient for artifact fetch — rotating the customer git.token to read-only (or revoking its package-write) CANNOT break fresh installs' fetch path. The G3 rotation is unblocked from this side.
  • Nuance: the installer (resolve_git_creds) dies on an empty git token even though the fetch itself would succeed anonymously — the credential is required by the script, not by Gitea. If the operator ever wants credential-less artifact fetch, that is a small host-install follow-up; until then customer configs still need a (read-scoped) token present.

Drill-VM end state

Build guest 9100 destroyed (--purge, all 3 LVs removed); in-VM cred file shredded; VM powered off; qcow2 restored to virgin (snapshot list verified) — the drill environment is exactly as found. Evidence retained on the build server: ~/drill/bake-0.103.0.log (next to the prior bake-A.log).

Deviations from the letter of the runbook

  • Gate 2a's template check was satisfied by downloading the template inside the VM (the virgin image never has it — same as the 0.98.3 bake) — anticipated by the runbook, noted as required.
  • Phase 3 ran anonymously instead of with the reviewer token (see Gate 3c) — a strictly stronger proof of fetchability.
  • The bake was launched as a transient systemd unit (systemd-run --unit=golden-bake) inside the VM instead of bare nohup (a plain ssh-backgrounded nohup did not survive session close).

Follow-ups (operator)

  1. Hub Day-0 manifest bump (Configs → Day-0 artifacts): enter the four values above. Until then fresh installs still fetch agent 0.63.0 + golden 0.98.3.
  2. Operator-key pin (out of scope here): day-0 installs no operator pubkey, so agent self-update stays dormant on fresh boxes; (a) pin the real key on felhom-pve, (b) small host-install follow-up ships the pinned pubkey at day-0 — candidate to fold into GL-4.
  3. G3 git.token rotation: unblocked per Gate 3c — issue read-scoped tokens (or rely on anon + keep a placeholder until the installer follow-up); also fixes demo-felhom's currently-EMPTY git credentials (found in GL-2; blocks any step-5 (re)install for that customer).
  4. GL-6 supervised drill consumes the bumped manifest end-to-end (Scenario-D-style proof for 0.74.0/0.103.0 — deliberately NOT run here).