colibri/docs/FREEBSD-BUILD-LANE.md
Sam & Claude b8d499e85c
Some checks are pending
CI / rust (pull_request) Waiting to run
CI / markdown (pull_request) Waiting to run
CI / port (pull_request) Waiting to run
CI / agent-jail-pkgs (pull_request) Waiting to run
docs: rename PLAN/PROPOSAL/HANDOFF/ENHANCEMENT → implementation names
7 renames (no plan/proposal/handoff/enhancement in filenames):

    CLAWDIE-INSTALLER-HANDOFF.md → CLAWDIE-INSTALLER-VALIDATION.md
    CLAWDIE-STUDIO-PROPOSAL.md   → CLAWDIE-STUDIO.md
    COLIBRI-SKILLS-PLAN.md       → COLIBRI-SKILLS.md
    FREEBSD-BUILD-LANE-HANDOFF.md→ FREEBSD-BUILD-LANE.md
    GLASSPANE-TUI-ENHANCEMENTS.md→ GLASSPANE-TUI-DESIGN.md
    MULTI-AGENT-HOST-PLAN.md     → MULTI-AGENT-HOST.md
    PLAN-WIKI-CLAWDIE-SI.md      → WIKI-CLAWDIE-SI.md

  16 cross-references updated across 10 files.
  wiki-lint --strict: PASS (146 refs, 0 failures).
2026-06-26 17:32:39 +02:00

7.1 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 the FreeBSD ISO validation tracked in MULTI-AGENT-HOST.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.

The x86_64-unknown-freebsd binaries must be compiled on the FreeBSD host; this lane belongs to the FreeBSD agent end to end.

Mother-node setup (osa): standing up the mother MCP host that USB nodes register into is a separate step from this build lane — follow packaging/mother/MOTHER-SETUP.md and run packaging/mother/setup-mother.sh (check its Prerequisites first).

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 — pre-built and staged by the ISO build only
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.
# Use the version-stamped Makefile path, not a bare `go build`, so
# `./bin/zot --version` matches the shipped tag. 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.47
ZOT_BUILD_VERSION="${ZOT_VERSION:-v0.2.47}"
VERSION="${ZOT_BUILD_VERSION#v}" make build
./bin/zot --version

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-mcp
ls -l zot/bin/zot
# colibri-tui and colibri-test-agent are optional (staged if present and requested)

3. Build the image

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

build.sh will:

  • preflight_colibri_artifacts — fail early if colibri-daemon, colibri, or colibri-mcp 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 + checks
service colibri_daemon start
colibri status                                   # paths, cost.mode, scheduler, tasks
colibri create-task --title "iso check"
colibri list-tasks --status queued               # contains "iso check"
colibri intake-task --title "iso intake check" --capability freebsd
sleep 35                                          # one scheduler tick (~30s)
colibri list-tasks --status queued               # contains "iso intake check"
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 + Node.js (npm); the image does not (binaries and docs 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.