colibri/docs/FREEBSD-BUILD-LANE.md

188 lines
7.1 KiB
Markdown
Raw Normal View History

# 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:
```sh
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`):
```sh
# 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)
```sh
# 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):
```sh
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
```sh
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:
```sh
# 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`:
```sh
# 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`.