clawdie-iso/skills/iso-build/SKILL.md

8.8 KiB

name description
iso-build Build the current Clawdie ISO image on the FreeBSD host from this repo, using the default tmux window workflow (`clawdie:3` / `iso`), repo-local tmp/ caches, step-by-step preflight, and the current operator-USB validation expectations.

iso-build

Use this skill for the normal FreeBSD host build path from the checked-out clawdie-iso repo. This is the current repo-local operator workflow, not the older “clone elsewhere and publish to nginx” flow.

Only run an ISO build when the operator explicitly assigns it. If the task is planning, docs, package-list edits, or static inspection only, do not build.

Current operator-USB expectations

  • Default validation image size: 28G
  • Live browser: Firefox, not Chromium
  • SDDM interactive login as clawdie; no live autologin
  • CLAWDIESEED exists as FAT32 slice 3 for post-flash, pre-boot seed import
  • Live CLI policy: ship codex, pi, gemini; do not ship claude
  • Operator editors: mousepad, geany, and micro
  • Hardware/custom-ISO report collector: hw-report
  • Vulkan diagnostic tool: vulkaninfo from vulkan-tools; Zed remains deferred until Intel+AMD Vulkan are proven on hardware
  • X blanking / DPMS disabled; NumLock off
  • Power policy: powerdxx + C3, not Cmax
  • Panel/runtime checks include mixer; clipman is intentionally dropped from the panel pending a D-Bus root-cause (see doc/XFCE-PANEL-BUGS-HANDOFF.md)
  • Final graphical validation requires real hardware, not bhyve/nested VM only

Workspace names

Keep the real paths as-is, but speak about them clearly:

  • tmp/output = output image artifacts
  • tmp/cache = build cache
  • tmp/cache/mnt = mounted work image
  • tmp/cache/FreeBSD-*.img = cached memstick base image
  • tmp/packages = fetched package archives

Manifest contract

The build workflow should emit or hand off clawdie.iso.build.v1 results under tmp/colibri/iso-build/ when Colibri ingestion is part of the task. The image itself also embeds /usr/local/share/clawdie-iso/build-manifest.json for live runtime inspection. See docs/ISO-MANIFESTS.md for the schema fields and path conventions.

Preconditions

  • Run on the FreeBSD build host, from the repo root
  • Prefer tmux for long builds
  • Use an elevated shell in the tmux pane so the build command itself runs without a sudo prefix
  • Run one command at a time; do not hide failures behind chained shell commands
  • Fetch before reporting remote state or starting a build
  • If disk is tight, the image build was interrupted, or tmp/cache/mnt is still mounted, use iso-build-cleanup first

Default tmux workflow

This is the default operator workflow and should be treated as the normal path.

1. Ensure the dedicated ISO window exists

tmux list-windows -t clawdie

If clawdie:3 / iso does not exist, create it:

tmux new-window -t clawdie:3 -n iso

2. Inspect the pane before reusing it

tmux capture-pane -pt clawdie:3.1 -S -30
ps auxww | egrep '[b]uild.sh|[s]cript -q tmp/operator-usb-.*-build.log'

If a build is still active, do not clobber it. Stop or wait deliberately.

3. Start clean after a failed attempt

When reusing the pane from a failed attempt:

  • stop the foreground command with Ctrl-C
  • return to repo root
  • clear the pane with Ctrl-L
  • emit a marker line so the next run is easy to identify in scrollback

Suggested marker:

echo "test build nr: $(ls tmp/operator-usb-*-build.log 2>/dev/null | wc -l | tr -d ' ') date: $(date +%d.%b.%y) ver: $(git rev-parse --short HEAD)"

4. Use the standard build command in 3:iso

/usr/bin/script -q tmp/operator-usb-$(git rev-parse --short HEAD)-build.log ./build.sh --skip-memstick-fetch --live-default-password

If the operator explicitly asked for a baked SSH key, append:

--ssh-key '<public key>'

Preflight

Run these before starting a build, one command at a time:

git fetch origin
git status --short --branch
git log --oneline -5
git rev-parse --short HEAD
df -h /home/clawdie /
du -xh -d 2 tmp | sort -h | tail -n 40
ls -lh tmp/output
du -xh -d 1 tmp/cache | sort -h

If you see stale mounts, md devices, or work.img still attached, stop and switch to iso-build-cleanup.

Colibri artifact preflight

FEATURE_COLIBRI=YES is the default for the next ISO lane. The ISO build stages FreeBSD-native Colibri artifacts from the adjacent ../colibri checkout; it does not build Rust while the image is mounted. The daemon is staged but kept disabled at boot by default (COLIBRI_DAEMON_ENABLE=NO) until rc.d supervision has passed live-USB validation, so Colibri cannot block SDDM/XFCE startup.

Build Colibri on the FreeBSD/OSA host, not on Debian/Linux. Do not cross-ship from debby unless the native OSA build fails.

Run this before the ISO build:

cd /home/clawdie/colibri
git fetch origin
git status --short --branch
git pull --ff-only
cargo build --workspace --release

ls -lh target/release/colibri-daemon \
       target/release/colibri \
       target/release/colibri-smoke-agent \
       target/release/colibri-tui

file target/release/colibri-daemon \
     target/release/colibri \
     target/release/colibri-smoke-agent \
     target/release/colibri-tui

target/release/colibri --help | head

Then return to the ISO repo and run syntax/preflight checks:

cd /home/clawdie/clawdie-iso
git fetch origin
git status --short --branch
git pull --ff-only
sh -n build.sh
sh -n scripts/stage-colibri-iso.sh

Important cleanup timing: do not run cargo clean immediately after the Colibri build. The ISO preflight/build consumes ../colibri/target/release. Only clean Colibri after the ISO build or after deciding those artifacts are no longer needed:

cd /home/clawdie/colibri
cargo clean
rm -rf /tmp/colibri-*

colibri-tui is optional in the staging script, but desired for this operator USB target and should be verified with the other three binaries.

Choose fetch mode

Use the lightest safe flag:

  • ./build.sh Fresh fetch of memstick + packages

  • ./build.sh --skip-memstick-fetch Reuse the cached FreeBSD memstick image, but refresh packages

  • ./build.sh --skip-fetch Reuse both memstick and package caches; use only when both caches are known-good

For the current operator workflow, the default is:

./build.sh --skip-memstick-fetch --live-default-password

What to watch

Normal progress moves through:

  1. Fetch/update package repo
  2. Prepare Clawdie-AI offline tarball
  3. Prepare work image
  4. Inject payload
  5. Write output image

Watch for these common blockers:

  • pkg-static ... conflicts with ...
  • Write error while extracting a package
  • database is locked after a package failure
  • Not a directory under tmp/cache/mnt/usr/local/share/clawdie-iso/...
  • mdconfig devices left attached after interruption
  • wrong ownership on /opt/clawdie/npm-global

If the build is interrupted or the work image gets wedged, stop and use iso-build-cleanup before retrying.

Output checks

After a successful build:

ls -lh tmp/output
find tmp/output -maxdepth 1 -type f -ls

Typical artifacts are:

  • raw .img
  • compressed .img.gz
  • matching .img.gz.sha256

Public/test artifact names should include the source commit suffix.

Static image expectations

Mounted-image checks should confirm:

  • firefox is installed on the live rootfs
  • chromium is not installed on the live rootfs
  • codex, pi, and gemini are present
  • claude is absent
  • mousepad, geany, and micro are present
  • hw-report and its desktop launcher are present
  • hw-probe, smartmontools, lscpu, lsblk, hwstat, and usbhid-dump are present
  • libinput, xinput, xrandr, and glxinfo are present for input/video diagnostics
  • vulkaninfo is present for Intel+AMD Vulkan checks before any future Zed move to live rootfs
  • sudo is absent
  • live privileged commands use mdo -u root ...
  • CLAWDIESEED exists as slice 3
  • branded Start icon (/usr/local/share/clawdie-iso/icons/clawdie-start.png) and wallpaper (/usr/local/share/clawdie-iso/wallpapers/clawdie-operator-bg.png) are installed
  • X blanking / DPMS are disabled
  • NumLock is forced off
  • powerdxx is installed and the live policy uses C3
  • panel checks cover mixer; clipman is intentionally absent (dropped pending root-cause — see doc/XFCE-PANEL-BUGS-HANDOFF.md)

If you plan another rebuild soon, keep:

  • tmp/cache/FreeBSD-15.0-RELEASE-amd64-memstick.img
  • tmp/cache/FreeBSD-15.0-RELEASE-amd64-memstick.img.SHA256
  • tmp/packages/
  • tmp/npm-globals/

Retry guidance

Use these rules:

  • build failed after package refresh but memstick cache is fine: retry with --skip-memstick-fetch
  • build failed because package cache looks wrong: retry without --skip-fetch
  • build failed after leaving mounts, md devices, or a large stale work.img: run iso-build-cleanup, then retry