diff --git a/build.cfg b/build.cfg index d339d056..c092f308 100644 --- a/build.cfg +++ b/build.cfg @@ -90,9 +90,13 @@ COLIBRI_COST_MODE="${COLIBRI_COST_MODE:-smart}" # cargo build --release -p clawdie) # Leave them blank to ship a "bring your own key" binary configured via the # rc.d env file (/usr/local/etc/clawdie/clawdie.env) at runtime instead. +# CLAWDIE_ENABLE defaults NO: stage the binary + rc.d but do not auto-start at +# boot until rc.d supervision is proven on the target image (same caution as +# COLIBRI_DAEMON_ENABLE), so clawdie cannot interfere with SDDM/live boot. +# Start it manually with `service clawdie start`, then flip to YES once proven. FEATURE_CLAWDIE="${FEATURE_CLAWDIE:-NO}" CLAWDIE_ARTIFACT_DIR="${CLAWDIE_ARTIFACT_DIR:-}" -CLAWDIE_ENABLE="${CLAWDIE_ENABLE:-YES}" +CLAWDIE_ENABLE="${CLAWDIE_ENABLE:-NO}" # Local LLM runtime (optional) # Choices: none | ollama | llama_cpp diff --git a/build.sh b/build.sh index 00a89bd1..1f96f51f 100755 --- a/build.sh +++ b/build.sh @@ -121,7 +121,7 @@ echo " Pkg : ${DEFAULT_PKG_BRANCH}" echo " GPU : ${GPU_DRIVER:-auto-detect}" echo " Target : ${TARGET:-baremetal}" echo " Colibri : ${FEATURE_COLIBRI:-NO}" -echo " Clawdie : ${FEATURE_CLAWDIE:-NO}" +echo " Clawdie agent : ${FEATURE_CLAWDIE:-NO}" echo "" # Name the output for the thing we are actually building. @@ -794,18 +794,16 @@ install_clawdie_service() { env \ COLIBRI_REPO="${_resolved_clawdie_repo}" \ CLAWDIE_ARTIFACT_DIR="${_resolved_clawdie_artifact_dir}" \ - CLAWDIE_STAGE_ENABLE="${CLAWDIE_ENABLE:-YES}" \ + CLAWDIE_STAGE_ENABLE="${CLAWDIE_ENABLE:-NO}" \ "${SCRIPT_DIR}/scripts/stage-clawdie-iso.sh" "${MOUNT_POINT}" - if ! /usr/sbin/pw -R "${MOUNT_POINT}" groupshow clawdie >/dev/null 2>&1; then - /usr/sbin/pw -R "${MOUNT_POINT}" groupadd clawdie - fi + # The clawdie agent runs as the operator `clawdie` account (same pattern as + # Clawdie-AI). configure_live_operator_session() creates that user/group + # earlier in the build, so we reuse it rather than re-creating a conflicting + # nologin account here. Assert it exists instead of silently diverging. if ! /usr/sbin/pw -R "${MOUNT_POINT}" usershow clawdie >/dev/null 2>&1; then - /usr/sbin/pw -R "${MOUNT_POINT}" useradd clawdie \ - -g clawdie \ - -d /var/db/clawdie \ - -s /usr/sbin/nologin \ - -c "Clawdie Agent" + echo "ERROR: clawdie user missing — configure_live_operator_session must run before install_clawdie_service" + exit 1 fi mkdir -p \ @@ -821,7 +819,7 @@ install_clawdie_service() { "${MOUNT_POINT}/var/run/clawdie" \ "${MOUNT_POINT}/var/log/clawdie" - set_config_line "${MOUNT_POINT}/etc/rc.conf" "clawdie_enable=\"${CLAWDIE_ENABLE:-YES}\"" + set_config_line "${MOUNT_POINT}/etc/rc.conf" "clawdie_enable=\"${CLAWDIE_ENABLE:-NO}\"" set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_user="clawdie"' set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_group="clawdie"' set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_data_dir="/var/db/clawdie"' diff --git a/doc/CLAWDIE-CODEX-HANDOFF.md b/doc/CLAWDIE-CODEX-HANDOFF.md new file mode 100644 index 00000000..f9c7d143 --- /dev/null +++ b/doc/CLAWDIE-CODEX-HANDOFF.md @@ -0,0 +1,111 @@ +# Clawdie agent — Codex ISO Builder handoff + +**From:** Claude Reviewer (Linux) · **To:** Codex ISO Builder (FreeBSD 15 host) +**Subject:** stage + validate the simplified `clawdie` agent on the operator USB + +The `clawdie` binary is the simplified, operator-friendly Colibri agent: one +small Rust binary (glasspane + herdr supervision + a DeepSeek-backed Telegram +bot). All quota/cost-mode/provider-fallback complexity is lifted. It is wired +into the ISO behind `FEATURE_CLAWDIE` (default `NO`) and runs as an rc.d service +like Clawdie-AI. + +## Precondition (blocking) + +Two PRs must be merged to `main` **before** step 1 — until colibri `main` has +the `clawdie` crate, the workspace build won't produce the binary: + +- colibri: `feat/clawdie-agent` → main +- clawdie-iso: `fix/clawdie-prebuild-hardening` → main (this branch) + +## Task checklist + +- [ ] 1. Build colibri release artifacts (incl. `clawdie`) on the FreeBSD host. +- [ ] 2. Run ISO preflight syntax checks. +- [ ] 3. Build the image with `FEATURE_CLAWDIE=YES` (staged, NOT auto-started). +- [ ] 4. Inspect the mounted image. +- [ ] 5. Validate on real hardware (SDDM/XFCE first, then start clawdie). +- [ ] 6. Cleanup only after the ISO build consumed the artifacts. + +### 1. Build colibri (do NOT `cargo clean` afterward — the ISO consumes `target/release`) + +```sh +cd /home/clawdie/colibri +git fetch origin && git pull --ff-only +# Baked creds are compiled into the binary and are extractable from the image. +# For a distributable image, OMIT both flags and use the rc.d env file instead +# (/usr/local/etc/clawdie/clawdie.env at runtime). +CLAWDIE_TG_TOKEN="" \ +CLAWDIE_DEEPSEEK_KEY="" \ + cargo build --workspace --release +ls -lh target/release/clawdie && file target/release/clawdie +``` + +### 2. ISO preflight + +```sh +cd /home/clawdie/clawdie-iso +git fetch origin && git pull --ff-only +sh -n build.sh +sh -n scripts/stage-clawdie-iso.sh +``` + +### 3. Build with the clawdie lane on (staged but disabled at boot) + +`build.cfg` ships `FEATURE_CLAWDIE=NO` / `CLAWDIE_ENABLE=NO`. Enable staging for +this image; leave `CLAWDIE_ENABLE=NO` so clawdie cannot interfere with SDDM/live +boot until rc.d supervision is proven on hardware. Use the standard +`clawdie:3` / `iso` tmux pane per the `iso-build` skill. + +```sh +FEATURE_CLAWDIE=YES /usr/bin/script -q \ + tmp/operator-usb-$(git rev-parse --short HEAD)-build.log \ + ./build.sh --skip-memstick-fetch --live-default-password +``` + +### 4. Mounted-image inspection (before flashing) + +- `/usr/local/bin/clawdie` present + executable +- `/usr/local/etc/rc.d/clawdie` present +- `etc/rc.conf` → `clawdie_enable="NO"` (staged-disabled is intentional) +- `clawdie` is the **operator** account (reused, not a second nologin user) +- `/var/db/clawdie`, `/var/run/clawdie`, `/var/log/clawdie` owned + `clawdie:clawdie`, mode 0750 + +### 5. Hardware validation (final proof — bhyve/static inspection is not enough) + +1. Boot real hardware; confirm **SDDM → XFCE** first (clawdie disabled, so it + can't be blamed for any boot issue). +2. `service clawdie start` → `service clawdie status` +3. `sockstat | grep clawdie` (Herdr socket bound); tail + `/var/log/clawdie/clawdie.log` +4. Message the Telegram bot → expect a DeepSeek reply. +5. If clean, flip `CLAWDIE_ENABLE=YES` for the next image so it boots as a + service. + +### 6. Cleanup (only after the ISO build consumed the artifacts) + +```sh +cd /home/clawdie/colibri && cargo clean && rm -rf /tmp/colibri-* +``` + +## Notes / caveats + +- The clawdie daemon runs as the operator `clawdie` user (same pattern as + Clawdie-AI's rc.d service). `install_clawdie_service` reuses that account and + errors if it is missing rather than creating a conflicting nologin user. +- No new FreeBSD system deps: `reqwest`/`rustls`/`tokio`/`portable-pty`/`rusqlite` + are already in the colibri workspace. Build proof so far was Linux-only — this + handoff covers the first FreeBSD build. +- Reference docs on colibri `main` after merge: `docs/CLAWDIE-BUILD.md`, + `docs/CLAWDIE-AGENT-WIKI.md`. + +## Deletion criteria + +Delete this handoff once the first `FEATURE_CLAWDIE=YES` image has booted on real +hardware, clawdie has been started and confirmed (socket + Telegram reply), and +the result is recorded below. + +## Results + +_(Codex: record build host, commit SHAs, binary size, mounted-image findings, +and hardware validation outcome here.)_