colibri/docs/FREEBSD-BUILD-LANE-HANDOFF.md
Sam & Claude f89701cc2c
Some checks failed
CI / rust (pull_request) Has been cancelled
CI / markdown (pull_request) Has been cancelled
docs(handoff): pin exact zot build command + artifact path
Replace the "see zot/README" placeholder with the canonical build invocation
that clawdie-iso's preflight prints:

  git checkout v0.2.29
  GOOS=freebsd GOARCH=amd64 go build -trimpath -o bin/zot ./cmd/zot

Output must land at <zot>/bin/zot (the ISO default artifact dir); the checked-
out ref becomes ISO_VERSION via git describe. Add the zot/agent build overrides
(ZOT_REPO, ZOT_ARTIFACT_DIR, COLIBRI_STAGE_AGENT) and the zot binary to the
preflight checklist.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 15:45:40 +02:00

6.7 KiB

FreeBSD Build Lane — ISO Validation Handoff

For: Codex (FreeBSD 15 host) · Goal: produce a Colibri-backed ISO candidate and prove ISO Gate 1 (passive service) on real FreeBSD.

This is the runtime-proof step for Priority 1 of PRIORITY-HANDOFF-ISO-SPAWN-COST.md. The build-side wiring is already done on Linux — clawdie-iso build.sh stages the Colibri binaries, installs the rc.d script, creates the colibri user, and enables the service. What remains is work only a FreeBSD host can do: build the FreeBSD binaries, run the image build, boot it, and run the acceptance checks.

Linux agents cannot cross-compile the x86_64-unknown-freebsd binaries, so this lane belongs to the FreeBSD agent end to end.

0. Host evidence to report

Run once and paste into the validation report:

freebsd-version
uname -a
rustc --version
cargo --version
go version

1. Sources

Three repos must sit side by side (the ISO build defaults to ../colibri):

# expected layout
#   <work>/clawdie-iso
#   <work>/colibri
#   <work>/zot
git -C colibri    pull --ff-only      # or: git reset --hard origin/main
git -C clawdie-iso pull --ff-only
git -C zot        pull --ff-only

colibri main tip for this handoff includes the staged-env tests and the ISO Priority 1 re-scope; zot provides the agent binary that the ISO version auto-tracks.

2. Build the FreeBSD artifacts (host toolchains, not on the image)

# Colibri release binaries — staged by the ISO build, never compiled by it
cd colibri
cargo build --workspace --release
cargo test --workspace            # confirm green on real FreeBSD; report output
cargo clippy --workspace --all-targets -- -D warnings

# zot agent binary (Go) — the agent has no FreeBSD release, so build it.
# This is the exact command clawdie-iso's preflight prints; ZOT_VERSION
# defaults to v0.2.29. Output must land at bin/zot (the ISO default artifact
# path). Check out the tag you intend to ship: ISO_VERSION auto-tracks the
# zot checkout via `git describe`, so the checked-out ref becomes the ISO
# version.
cd ../zot
git checkout v0.2.29
GOOS=freebsd GOARCH=amd64 go build -trimpath -o bin/zot ./cmd/zot

After both builds, these must exist (the ISO preflight checks each):

ls -l colibri/target/release/colibri-daemon \
      colibri/target/release/colibri \
      colibri/target/release/colibri-smoke-agent
ls -l zot/bin/zot
# colibri-tui is optional (staged if present)

3. Build the image

cd clawdie-iso
sudo ./build.sh            # FEATURE_COLIBRI defaults to YES

build.sh will:

  • preflight_colibri_artifacts — fail early if any of the three binaries above are missing (it prints the exact cargo build command to fix it).
  • install_colibri_service — run scripts/stage-colibri-iso.sh against the image root, then pw -R <root> useradd colibri and write colibri_daemon_enable=YES into the image.

Useful overrides (defaults are fine for a standard run):

  • COLIBRI_REPO=/path/to/colibri if not at ../colibri.
  • COLIBRI_ARTIFACT_DIR=... if binaries live outside target/release.
  • COLIBRI_COST_MODE=smart|fast|max (default smart).
  • ZOT_REPO=/path/to/zot if not at ../zot; ZOT_ARTIFACT_DIR=... if the binary is not at <zot>/bin/zot.
  • COLIBRI_STAGE_AGENT=NO to skip the zot agent (default YES, needs the prebuilt zot); FEATURE_COLIBRI=NO to skip Colibri entirely (not for this lane).

Output image name encodes the zot version, e.g. clawdie-quindecim-<ver>.img.

4. Boot and validate Colibri (ISO Gate 1)

Boot the image in a bhyve VM or on hardware, then run the full docs/ISO-ACCEPTANCE-RUNBOOK.md. Minimum pass set:

# pre-flight
id colibri
ls -l /usr/local/bin/colibri /usr/local/bin/colibri-daemon
ls -l /usr/local/etc/rc.d/colibri_daemon
sysrc colibri_daemon_enable

# lifecycle + smoke
service colibri_daemon start
colibri status                                   # paths, cost.mode, scheduler, tasks
colibri create-task --title "iso smoke"
colibri list-tasks --status queued               # contains "iso smoke"
colibri intake-task --title "iso intake smoke" --capability freebsd
sleep 35                                          # one scheduler tick (~30s)
colibri list-tasks --status queued               # contains "iso intake smoke"
service colibri_daemon stop                       # socket gone, SQLite remains
service colibri_daemon start && colibri list-tasks --status queued  # persistence

Confirm cost.mode matches the COLIBRI_COST_MODE baked at build time.

5. Validate the Hermes rc.d service

hermes_daemon is not staged by the clawdie-iso build (only Colibri is) — install it manually from the hermes-bsd repo on the booted image (or any FreeBSD host) per hermes-bsd/README-FreeBSD.md:

# one-time setup (from hermes-bsd checkout)
sudo pw groupadd hermes
sudo pw useradd hermes -g hermes -d /var/db/hermes -s /usr/sbin/nologin
sudo cp packaging/freebsd/hermes_daemon.in /usr/local/etc/rc.d/hermes_daemon
sudo chmod 555 /usr/local/etc/rc.d/hermes_daemon
sudo sysrc hermes_daemon_enable=YES

# missing-config abort: must fail cleanly, NOT crash-loop under daemon(8) -r
sudo service hermes_daemon start        # expect exit 1 + clear "config not found"

# after `hermes setup` + `hermes model` write /var/db/hermes/config.yaml:
sudo service hermes_daemon start
sudo service hermes_daemon health       # "healthy (pid N alive)"
sudo service hermes_daemon stop         # supervisor exits, child does not respawn

Confirm both the supervisor and child pidfiles under /var/run/hermes/ are removed on stop.

6. Report + acceptance

Report back: host evidence (§0), full cargo test output, the runbook results, and the Hermes checks. File any FreeBSD-specific differences from Linux-built behavior as a PR, not a silent local fix.

Delete this doc when all are true:

  • cargo test --workspace passes on FreeBSD 15 (output + versions reported).
  • sudo ./build.sh produces an image with Colibri staged (preflight passed, colibri user present, service enabled).
  • Booted image passes the Colibri acceptance runbook (start/status/task/ intake/stop/restart-persistence).
  • Hermes rc.d: missing-config start aborts (no crash loop); configured start/health/stop work and pidfiles are cleaned up.
  • Any platform differences are filed as a PR and reported.

Notes

  • The build host needs Go + Rust; the image does not (binaries are staged, not compiled on device). See clawdie-iso/REQUIREMENTS.md.
  • /var/run is tmpfs on FreeBSD — both rc.d scripts recreate their run dirs in prestart, so a fresh boot is the correct test.
  • Cost-mode enforcement wiring is Priority 3 (Linux-doable, separate lane); this lane only confirms the baked cost.mode is surfaced by colibri status.