clawdie-iso/BUILD.md

5.4 KiB

Clawdie ISO Builder

Builds a bootable FreeBSD 15.0 USB image with the Clawdie live installer, offline package repository, and bundled Clawdie-AI runtime.

The ISO version is independent from the bundled Clawdie-AI ref:

ISO_VERSION="0.1.0"
BUILD_CHANNEL="dev"      # dev | release
CLAWDIE_REF="main"       # validation default

Release builds must pin a Clawdie-AI tag with --clawdie-version X.Y.Z.


Prerequisites

On the FreeBSD build host:

sudo pkg install -y curl node24 npm-node24 qt6-base qt6-declarative qt6-buildtools sudo

Also required:

  • FreeBSD 15.0+
  • 150 GB free build space recommended
  • root or sudo for image assembly
  • 64 GB USB key minimum for the default IMAGE_SIZE=50G

Recommended for remote first setup:

export TAILSCALE_AUTHKEY="tskey-auth-..."

If TAILSCALE_AUTHKEY is absent, the build continues with a warning. The installed host keeps public SSH available on port 22 so the operator can still reach it.


Quick Start

# Full build: fetch + assemble.
sudo ./build.sh

Output:

tmp/output/clawdie-iso-unified-DD.mmm.YYYY.img

Write it to USB:

sudo dd if=tmp/output/clawdie-iso-unified-DD.mmm.YYYY.img of=/dev/daX bs=1M status=progress
sudo sync

Use the whole USB device (/dev/daX), not a partition.


Useful Build Modes

# Download/cache FreeBSD, packages, npm globals, and Clawdie-AI only.
./build.sh --fetch-only

# Assemble using cached inputs.
sudo ./build.sh --skip-fetch

# Bundle a specific branch/tag/commit ref.
sudo ./build.sh --clawdie-ref main
sudo ./build.sh --clawdie-ref f04f35eb4e16b50150ae73bad2e271388dc88f82

# Release build from a pinned Clawdie-AI tag.
BUILD_CHANNEL=release sudo ./build.sh --clawdie-version 0.10.0

--skip-fetch is provenance-safe for Clawdie-AI: moving refs are resolved to a commit and cached by that commit. If the commit cannot be resolved safely, the script refuses a moving-ref skip-fetch build rather than producing misleading manifest data.


Build Output and Provenance

The build header shows:

ISO     : 0.1.0-dev
FreeBSD : 15.0-RELEASE amd64
Clawdie : main
Clawdie commit: <resolved-sha>

The image contains:

/usr/local/share/clawdie-iso/build-manifest.json

The installed system receives the same manifest. It records:

  • ISO version and build channel
  • FreeBSD version/arch
  • bundled Clawdie-AI ref and commit
  • ISO repo commit and dirty state
  • UTC build timestamp

The final size output distinguishes:

  • Image size — logical size that must fit on the USB key
  • Allocated — sparse bytes used on the build host

Build Configuration

Edit build.cfg for persistent defaults:

ISO_VERSION="0.1.0"
BUILD_CHANNEL="${BUILD_CHANNEL:-dev}"
IMAGE_SIZE="50G"
CLAWDIE_REF="${CLAWDIE_REF:-main}"
DEFAULT_PKG_BRANCH="latest"
FEATURE_TAILSCALE="${FEATURE_TAILSCALE:-YES}"
TAILSCALE_AUTHKEY="${TAILSCALE_AUTHKEY:-}"

Notes:

  • Host pkg repo branch and ISO package branch are independent.
  • DEFAULT_PKG_BRANCH=latest is the ISO package source by default.
  • Provider keys and Telegram credentials are optional and normally configured after first boot through /setup.

Build Process

  1. Fetch FreeBSD memstick and verify checksum.
  2. Fetch all package archives for offline install.
  3. Build local pkg repository metadata.
  4. Fetch Clawdie-AI by resolved ref and prepare offline node_modules tarball.
  5. Create/attach the working image.
  6. Inject firstboot scripts, packages, QML installer, Clawdie-AI, build config, and manifest.
  7. Copy the final sparse image into tmp/output/.

The build is intentionally cache-friendly. If in doubt before validation, run the full sudo ./build.sh once after pulling current main.


Install Flow Produced by the Image

  1. USB boots to Lumina live session.

  2. QML installer launches automatically.

  3. Operator selects disk and enters identity/access details.

  4. Live commit helper runs the disk install and copies payload/handoff files.

  5. Installed system boots and runs clawdie-firstboot.

  6. shell-deploy.sh runs just install, starts the controlplane, rotates a bootstrap setup token, and writes MOTD instructions.

  7. Operator opens setup via local console or SSH tunnel:

    ssh -L 3100:127.0.0.1:3100 clawdie@<host>
    
    http://127.0.0.1:3100/setup
    

Provider/model choice, Telegram, and operator account creation happen in that post-install setup flow.


Testing

Before writing to hardware, use bhyve when available:

sudo ./scripts/bhyve-pf-allow.sh
sudo ./scripts/bhyve-test.sh

For the live QML installer itself:

make -C firstboot/gui/qml-installer

See TESTING.md for the full validation checklist.


Troubleshooting

ERROR: missing package archive for <pkg>

A package was added after your cache was created. Run a full fetch/build:

sudo ./build.sh

pkg not found during unprivileged fetch

build.sh now sets a known FreeBSD tool PATH internally. If your shell still cannot find pkg manually, add /usr/local/sbin to your login PATH.

npm ci falls back to npm install

The bundled Clawdie-AI ref has a package-lock mismatch. The build warns and falls back so validation can continue, but release refs should have a clean lock.

Image says small allocated size

The image is sparse on the build host. Use the logical image size when choosing a USB key.


Last updated: 12.maj.2026