Files
felhom-agent/REPORT.md
T

5.0 KiB

REPORT — build-golden.sh v2.0.0: golden 0.98.3 rebuild (drill B5 + B1)

Date: 2026-07-03 · Class: implementation + clean-room drill (script-only — no Go code, no binary, no agent version bump; docs-only precedent) · Source findings: felhom.eu/documentation/audits/DRILL-day0-cleanroom-2026-07-03.md B5/B1 + the stale backlog note FOLLOWUP-golden-default-controller-tag.md (now resolved). Full drill evidence: felhom.eu/documentation/audits/DRILL-golden-098-2026-07-03.md.

Baselines & commits

What Value
Base c9f963d
Script commit ceca355 — configs/build-golden.sh v2.0.0 + CHANGELOG
Docs commit (this one — REPORT/CONTEXT)
felhom.eu guide/ledger/backlog/evidence-doc push (see that repo's REPORT)
Controller tag baked 0.98.3 (reconfirmed current: CHANGELOG top + manifest HTTP 200 pre-bake)

What changed (configs/build-golden.sh only)

  1. B5 — CONTROLLER_IMAGE (arg 6) MANDATORY: no default; missing → die with usage naming the convention. Rationale in-file: the hand-bumped default rotted twice (0.43.0 → 0.85.1 → stale again); a required arg cannot rot; auto-"latest" could bake an unvouched tag. Red-proof: the no-arg invocation exits 1 with the usage BEFORE any pct op (run locally + in the drill VM).
  2. B1 — baked felhom-controller-bootstrap.path (PathExists=/etc/felhom-bootstrap/bootstrap.json, enabled, WantedBy=multi-user.target): starts the Condition-gated oneshot service when the agent back-half hot-plugs the bootstrap mount into the RUNNING guest. Service unchanged (RemainAfterExit=yes prevents re-trigger loops; the enabled service still covers the plain boot case). The mp0/mp1 vzdump-inclusion guards untouched.
  3. GOLDEN_SCRIPT_VERSION=2.0.0 + [golden] provenance line (script version + baked tag) opening every bake transcript. Gates: bash -n clean; usage renders.

Clean-room validation (drill VM on 192.168.0.180, virgin-restored per scenario)

Scenario Result
A — bake integrity PASS: provenance line; controller 0.98.3 + infra images baked; docker logout + config.json removal before archive (line present, ran); vzdump including mp0 AND mp1; archive 583 MB, sha256 b9a02ef1b6f02b9b58babc4c6aad9cf6c053ebdfba116c78c8e7830de757fd01; guest 9100 destroyed
B — isolated hot-plug (STOP gate) PASS: fresh restore w/o mount → service inactive (dead) condition-unmet, path active (waiting); back-half-identical pct set -mp9 …,mp=/etc/felhom-bootstrap,ro=1 on the RUNNING guest → service SUCCESS ~1 s later, controller Up (healthy) 0.98.3, uptime -s unchanged (no reboot)
C — local-golden Day-0 (publish gate) PASS: served installer v1.9.1, canonical command w/o --force-gitea-golden[SKIP] using local golden (resolution order); first boot controller 0.98.3, NO D.1b; selfupdate/checkupdate_available:false (self-manages); selftest all-OK incl. pool read; bentopdf deployed via the dashboard endpoint → 200 via traefik; hub rows: agent 0.63.0 / controller 0.98.3
Publish PUT …/felhom-golden/0.98.3/golden.tar.zst201; round-trip GET sha matches (publish-agent.sh pattern mirrored)
Vouch operator vouched golden 0.98.3 in the Day-0 manifest (agent 0.63.0 already vouched — the v0.63.0 follow-up is DONE); confirmed via /api/v1/artifacts
D — published-artifact Day-0 PASS: virgin box, no local golden → fetching golden v0.98.3 from Giteaverified sha256 b9a02ef1… matches the hub manifest → SUCCESS; first boot 0.98.3; up-to-date. The exact fresh-customer path

Cleanup: all drill-1 hub rows deleted (8 tables, counts 0; demo-felhom/peti-felhom intact); drill VM reverted to virgin and kept; bake credential env (0600) removed. Registry read-cred handled via env only — never logged/committed.

Deviations & observations

  • Premature publish (caught + corrected): the script's opt-in publish block triggers on the same REGISTRY_* vars the pull needs — the Scenario A bake published immediately, before the Scenario C gate. Package DELETEd (204, anon 404 verified) and re-published only after C passed. Candidate cleanup (not done — no-"while-here" rule): a separate GOLDEN_PUBLISH=1 opt-in.
  • SECURITY (operator follow-up): the pull credential — the demo customer's git.token, i.e. what every customer box holds — turned out to be a Gitea admin token with package-WRITE (the premature publish proved it). Scope down to read-only + rotate.
  • Installer v1.9.1's post-provision reboot is now a redundant belt (the path unit deploys first) — removal recorded as a candidate installer cleanup, kept for now.
  • Drill-env: dhcpstart=10.0.2.30 + explicit hostfwd…-10.0.2.15:22 on the QEMU command removes the prior drill's slirp IP-collision quirk entirely.
  • Guide follow-through (felhom.eu): D.1b retired to a one-line version check; troubleshooting row covers pre-0.86.0 goldens; ledger B1/B5 FIXED; backlog note resolved.