diff --git a/BUILD.md b/BUILD.md index 039d8296..f3c4af6b 100644 --- a/BUILD.md +++ b/BUILD.md @@ -18,10 +18,11 @@ On `xfce-operator-usb`, builds a bootable FreeBSD 15.0 operator USB image with: - Colibri Rust control-plane service for the live USB - deployed-system `clawdie` service lane for future disk/server installs -The ISO version is independent from the bundled Clawdie-AI ref: +The ISO carries its own product version, independent of any component (zot, +Colibri, Clawdie-AI). Component versions are recorded in `build-manifest.json`. ```sh -ISO_VERSION="auto" # default: git describe, then ZOT_VERSION fallback +ISO_VERSION="0.10.0" # explicit product version (required; no zot-tracking) BUILD_CHANNEL="dev" # dev | release CLAWDIE_REF="main" # validation default ``` @@ -137,14 +138,14 @@ sudo ./build.sh Output: ```text -tmp/output/clawdie-quindecim-0.2.29.img +tmp/output/clawdie-quindecim-0.10.0.img ``` Published/downloaded artifacts are compressed as `.img.xz`. Stream the compressed image directly into `dd`: ```sh -xz -dc clawdie-quindecim-0.2.29.img.xz | sudo dd of=/dev/daX bs=1M status=progress conv=fsync +xz -dc clawdie-quindecim-0.10.0.img.xz | sudo dd of=/dev/daX bs=1M status=progress conv=fsync sync ``` @@ -153,15 +154,15 @@ For Linux or FreeBSD downloads from the published HTTPS path, prefer resumable ```sh curl -fL --continue-at - --retry 5 --retry-delay 5 --progress-bar -O \ - https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.2.29.img.xz + https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz curl -fL --retry 5 --retry-delay 5 -O \ - https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.2.29.img.xz.sha256 + https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz.sha256 ``` For a build-local uncompressed image, plain `dd` is also fine: ```sh -sudo dd if=tmp/output/clawdie-quindecim-0.2.29.img of=/dev/daX bs=1M status=progress conv=fsync +sudo dd if=tmp/output/clawdie-quindecim-0.10.0.img of=/dev/daX bs=1M status=progress conv=fsync sync ``` @@ -428,7 +429,7 @@ The final size output distinguishes: Edit `build.cfg` for persistent defaults: ```sh -ISO_VERSION="${ISO_VERSION:-auto}" +ISO_VERSION="${ISO_VERSION:-0.10.0}" BUILD_CHANNEL="${BUILD_CHANNEL:-dev}" IMAGE_SIZE="28G" CLAWDIE_REF="${CLAWDIE_REF:-main}" diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c0cdbcf..7c973bb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,17 +6,34 @@ All notable changes to Clawdie-ISO are documented here. ## [Unreleased] +_Nothing yet._ + +--- + +## [0.10.0] — 2026-06-15 + +**Codename:** Operator Image + +First numbered milestone since the architecture settled on **zot (agent) + +Colibri (control plane)**. Not production, but a real, flashable operator image: +the XFCE live experience is stable and the Colibri service bugs are fixed, so the +image is meant to work out of the box. Work continues from here toward `1.0.0`. + +### Versioning +- The ISO now carries its **own product version** and no longer borrows zot's number. `ISO_VERSION` is explicit (set in `build.cfg`); `auto`/zot-tracking is gone and a build with no version fails fast. Component versions (zot, colibri, clawdie-ai, clawdie-iso) are recorded as provenance in `build-manifest.json`. +- `build-manifest.json` now records `colibri_commit`/`colibri_dirty` — the image stages adjacent colibri binaries, so the commit that produced them is captured for reproducibility. + ### Added - Live rebuild lane now covers the **whole agent stack**: `go` added to the live-operator package list and the `zot` source seeded at `/home/clawdie/ai/zot`, so a booted USB can rebuild zot (Go) as well as Colibri (Rust). See `docs/LIVE-COLIBRI-REBUILD.md`. - Aider+Pi harness venv provisioning — `firstboot/shell-deploy.sh` now creates `/opt/clawdie/venv/aider` with pinned deps: `aider-chat==0.86.2`, `litellm==1.81.10`, `tree_sitter==0.20.4` - Aider availability check in post-install verification (logs `aider` version at end of deployment) +### Fixed +- Colibri daemon now handles SIGTERM (graceful socket cleanup + agent reaping on `service stop`), refuses to steal a live socket, and fails closed if it cannot bind a control socket (colibri PR #75). + ### Improvements - Updated firstboot completion messages to highlight Aider and Pi as primary harnesses (Codex listed as optional alternative) -### Versioning -- The image version tracks the `zot` release it is built on (resolved via `git describe`, falling back to `ZOT_VERSION`); the output is named `clawdie--.img`. No separately invented ISO number. - --- ## [0.9.0] — 2026-04-06 @@ -59,13 +76,14 @@ All notable changes to Clawdie-ISO are documented here. ## Repository Status The agent stack is **zot (Go agent) + Colibri (Rust control plane)**; "Clawdie" -is the product name for the two together. The image version tracks zot. +is the product name for the two together. The image carries its own product +version; component versions are recorded as provenance in `build-manifest.json`. | Repo | Status | Version source | | ------------- | ----------------------------------- | ------------------------------- | | zot | Active — the agent (front door) | pinned tag (`ZOT_VERSION`) | | colibri | Active — control plane + installer | workspace `Cargo.toml` | -| clawdie-iso | Active — image builder | tracks zot (`git describe`) | +| clawdie-iso | Active — image builder | product version (`ISO_VERSION`) | | clawdie-ai | Being pruned (features → zot/Colibri) | — | | pi | Demoted — spawnable backend, not default | upstream npm | | clawdie-shell | **Archived** (merged into clawdie-iso) | — | diff --git a/FLASHING.md b/FLASHING.md index a9e920ac..4ea4ede8 100644 --- a/FLASHING.md +++ b/FLASHING.md @@ -3,7 +3,7 @@ Published Clawdie operator USB artifacts are compressed: ```text -clawdie-quindecim-0.2.29.img.xz +clawdie-quindecim-0.10.0.img.xz ``` Default policy: @@ -47,15 +47,15 @@ Download with resume and retries: ```sh curl -fL --continue-at - --retry 5 --retry-delay 5 --progress-bar -O \ - https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.2.29.img.xz + https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz curl -fL --retry 5 --retry-delay 5 -O \ - https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.2.29.img.xz.sha256 + https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz.sha256 ``` Verify the downloaded artifact: ```sh -sha256sum -c clawdie-quindecim-0.2.29.img.xz.sha256 +sha256sum -c clawdie-quindecim-0.10.0.img.xz.sha256 ``` Unmount mounted USB partitions if needed: @@ -68,7 +68,7 @@ Flash by streaming xz into `dd`: ```sh set -o pipefail 2>/dev/null || true -xz -dc clawdie-quindecim-0.2.29.img.xz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync +xz -dc clawdie-quindecim-0.10.0.img.xz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync sync ``` @@ -89,22 +89,22 @@ Download with resume and retries: ```sh curl -fL --continue-at - --retry 5 --retry-delay 5 --progress-bar -O \ - https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.2.29.img.xz + https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz curl -fL --retry 5 --retry-delay 5 -O \ - https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.2.29.img.xz.sha256 + https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz.sha256 ``` Verify the downloaded artifact: ```sh -HASH=$(awk '{print $1}' clawdie-quindecim-0.2.29.img.xz.sha256) -sha256 -c "$HASH" clawdie-quindecim-0.2.29.img.xz +HASH=$(awk '{print $1}' clawdie-quindecim-0.10.0.img.xz.sha256) +sha256 -c "$HASH" clawdie-quindecim-0.10.0.img.xz ``` If `sha256sum` is installed, this GNU-style form is also OK: ```sh -sha256sum -c clawdie-quindecim-0.2.29.img.xz.sha256 +sha256sum -c clawdie-quindecim-0.10.0.img.xz.sha256 ``` Unmount mounted USB partitions if needed: @@ -116,7 +116,7 @@ sudo umount /dev/daXs* 2>/dev/null Flash by streaming xz into `dd`: ```sh -xz -dc clawdie-quindecim-0.2.29.img.xz | sudo dd of=/dev/daX bs=1M status=progress conv=fsync +xz -dc clawdie-quindecim-0.10.0.img.xz | sudo dd of=/dev/daX bs=1M status=progress conv=fsync sync ``` @@ -129,11 +129,11 @@ Replace `/dev/daX` with the actual whole USB disk. No decompression step needed — both tools read `.img.xz` directly. 1. Download both files (same folder): - - `clawdie-quindecim-0.2.29.img.xz` - - `clawdie-quindecim-0.2.29.img.xz.sha256` + - `clawdie-quindecim-0.10.0.img.xz` + - `clawdie-quindecim-0.10.0.img.xz.sha256` 2. (Recommended) verify the checksum in PowerShell: ```powershell - (Get-FileHash .\clawdie-quindecim-0.2.29.img.xz -Algorithm SHA256).Hash.ToLower() + (Get-FileHash .\clawdie-quindecim-0.10.0.img.xz -Algorithm SHA256).Hash.ToLower() # compare against the value in the .sha256 file ``` 3. **Rufus:** open Rufus → **SELECT** the `.img.xz` → choose the USB drive under "Device" → **START**. Rufus decompresses and writes in one step. (Use "DD Image" mode if prompted.) @@ -152,21 +152,21 @@ For a local build artifact that already exists as a raw image: ### Linux ```sh -sudo dd if=clawdie-quindecim-0.2.29.img of=/dev/sdX bs=4M status=progress conv=fsync +sudo dd if=clawdie-quindecim-0.10.0.img of=/dev/sdX bs=4M status=progress conv=fsync sync ``` ### FreeBSD ```sh -sudo dd if=clawdie-quindecim-0.2.29.img of=/dev/daX bs=1M status=progress conv=fsync +sudo dd if=clawdie-quindecim-0.10.0.img of=/dev/daX bs=1M status=progress conv=fsync sync ``` Only unxz first if you specifically need the raw file for inspection or reuse: ```sh -unxz -k clawdie-quindecim-0.2.29.img.xz +unxz -k clawdie-quindecim-0.10.0.img.xz ``` --- diff --git a/README.md b/README.md index 6067f2d8..522cc336 100644 --- a/README.md +++ b/README.md @@ -170,17 +170,17 @@ Artifact names use a short Latin codename for the FreeBSD major line they were built on. For FreeBSD `15`, that codename is `quindecim`, so: ```text -clawdie-quindecim-0.2.29.img +clawdie-quindecim-0.10.0.img ``` means: - `clawdie` — project name - `quindecim` — Latin for `15`, matching the FreeBSD 15 build line -- `0.2.29` — version, tracking the zot release the image is built upon +- `0.10.0` — the ISO product version (set in `build.cfg`) -Per-build provenance (build date, `clawdie-iso` commit, zot commit) lives in -`build-manifest.json`, not the filename. +Per-build provenance (build date and the `clawdie-iso`, `colibri`, `zot`, and +`clawdie-ai` commits) lives in `build-manifest.json`, not the filename. Small reference for the current naming convention: @@ -233,26 +233,26 @@ Download on Linux or FreeBSD with resume and retries: ```sh curl -fL --continue-at - --retry 5 --retry-delay 5 --progress-bar -O \ - https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.2.29.img.xz + https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz curl -fL --retry 5 --retry-delay 5 -O \ - https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.2.29.img.xz.sha256 + https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz.sha256 ``` Linux: ```sh -sha256sum -c clawdie-quindecim-0.2.29.img.xz.sha256 +sha256sum -c clawdie-quindecim-0.10.0.img.xz.sha256 set -o pipefail 2>/dev/null || true -xz -dc clawdie-quindecim-0.2.29.img.xz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync +xz -dc clawdie-quindecim-0.10.0.img.xz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync sync ``` FreeBSD: ```sh -HASH=$(awk '{print $1}' clawdie-quindecim-0.2.29.img.xz.sha256) -sha256 -c "$HASH" clawdie-quindecim-0.2.29.img.xz -xz -dc clawdie-quindecim-0.2.29.img.xz | sudo dd of=/dev/daX bs=1M status=progress conv=fsync +HASH=$(awk '{print $1}' clawdie-quindecim-0.10.0.img.xz.sha256) +sha256 -c "$HASH" clawdie-quindecim-0.10.0.img.xz +xz -dc clawdie-quindecim-0.10.0.img.xz | sudo dd of=/dev/daX bs=1M status=progress conv=fsync sync ``` diff --git a/TESTING.md b/TESTING.md index 331eb564..d0530d0b 100644 --- a/TESTING.md +++ b/TESTING.md @@ -1,7 +1,7 @@ # Clawdie Operator USB Testing Guide **Branch:** `xfce-operator-usb` -**Target artifact:** `clawdie-quindecim-0.2.29.img` +**Target artifact:** `clawdie-quindecim-0.10.0.img` **Current desktop path:** XFCE via SDDM, interactive login as `clawdie` --- @@ -105,7 +105,7 @@ Run this on the FreeBSD build host after `build.sh` finishes. ### Useful verification commands ```sh -sudo mdconfig -a -t vnode -f tmp/output/clawdie-quindecim-0.2.29.img +sudo mdconfig -a -t vnode -f tmp/output/clawdie-quindecim-0.10.0.img sudo mount -o ro /dev/md0s2a /mnt egrep 'hostname|root_rw_mount|tmpmfs|varmfs|sshd|avahi|powerd|powerdxx|pf_enable|sddm|display_manager|clawdie_live_gpu|clawdie_tailscale_up|linux_enable|zfs_enable|kld_list' /mnt/etc/rc.conf @@ -426,12 +426,12 @@ FreeBSD. For a published compressed image on Linux, the default path is: ```sh curl -fL --continue-at - --retry 5 --retry-delay 5 --progress-bar -O \ - https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.2.29.img.xz + https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz curl -fL --retry 5 --retry-delay 5 -O \ - https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.2.29.img.xz.sha256 -sha256sum -c clawdie-quindecim-0.2.29.img.xz.sha256 + https://osa.smilepowered.org/downloads/iso/clawdie-quindecim-0.10.0.img.xz.sha256 +sha256sum -c clawdie-quindecim-0.10.0.img.xz.sha256 set -o pipefail 2>/dev/null || true -xz -dc clawdie-quindecim-0.2.29.img.xz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync +xz -dc clawdie-quindecim-0.10.0.img.xz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync sync ``` diff --git a/build.cfg b/build.cfg index bd2e6bf4..fe1abd09 100644 --- a/build.cfg +++ b/build.cfg @@ -10,10 +10,10 @@ FREEBSD_MEMSTICK_URL="${FREEBSD_ISO_BASE_URL}/FreeBSD-${FREEBSD_VERSION}-${FREEB FREEBSD_MEMSTICK_SHA256_URL="${FREEBSD_ISO_BASE_URL}/CHECKSUM.SHA256-FreeBSD-${FREEBSD_VERSION}-${FREEBSD_ARCH}" # ISO version metadata. -# The ISO version tracks the zot release the image is built upon — no separately -# invented number. "auto" resolves it at build time from the zot checkout -# (git describe), falling back to ZOT_VERSION. Set ISO_VERSION=x.y.z to override. -ISO_VERSION="${ISO_VERSION:-auto}" +# The ISO carries its own product version — it does NOT borrow a component's +# number. Component versions (zot, colibri, clawdie-ai, clawdie-iso) are recorded +# as provenance in build-manifest.json. Bump this for each milestone image. +ISO_VERSION="${ISO_VERSION:-0.10.0}" BUILD_CHANNEL="${BUILD_CHANNEL:-dev}" # dev | release # Output image diff --git a/build.sh b/build.sh index b63dbf5c..57b6d5b4 100755 --- a/build.sh +++ b/build.sh @@ -112,8 +112,14 @@ if [ "${BUILD_CHANNEL}" = "release" ]; then esac fi -# ISO version tracks the zot release built upon — no separately invented number. -# "auto" resolves from the zot checkout (git describe); else the pinned ZOT_VERSION. +# The ISO carries its own product version (ISO_VERSION in build.cfg). It does not +# track any single component. Component versions are resolved below purely for +# provenance in build-manifest.json. A milestone build must declare a version. +if [ -z "${ISO_VERSION:-}" ] || [ "${ISO_VERSION}" = "auto" ]; then + echo "ERROR: ISO_VERSION must be an explicit product version (e.g. 0.10.0)." + echo " The image no longer tracks zot — set ISO_VERSION in build.cfg." + exit 1 +fi _iso_zot_repo="${ZOT_REPO:-${SCRIPT_DIR}/../zot}" case "${_iso_zot_repo}" in /*) ;; *) _iso_zot_repo="${SCRIPT_DIR}/${_iso_zot_repo}" ;; esac ZOT_RESOLVED_VERSION="" @@ -123,12 +129,9 @@ if [ -d "${_iso_zot_repo}/.git" ]; then ZOT_RESOLVED_COMMIT="$(git -C "${_iso_zot_repo}" rev-parse --short=12 HEAD 2>/dev/null || true)" fi [ -n "${ZOT_RESOLVED_VERSION}" ] || ZOT_RESOLVED_VERSION="${ZOT_VERSION}" -if [ -z "${ISO_VERSION:-}" ] || [ "${ISO_VERSION}" = "auto" ]; then - ISO_VERSION="${ZOT_RESOLVED_VERSION#v}" -fi echo "==> clawdie-iso build" -echo " ISO : ${ISO_VERSION}-${BUILD_CHANNEL} (tracks zot ${ZOT_RESOLVED_VERSION})" +echo " ISO : ${ISO_VERSION}-${BUILD_CHANNEL} (zot ${ZOT_RESOLVED_VERSION})" echo " FreeBSD : ${FREEBSD_VERSION} ${FREEBSD_ARCH}" echo " Clawdie : ${CLAWDIE_REF}" echo " Desktop : ${DEFAULT_DESKTOP}" @@ -139,9 +142,9 @@ echo " Target : ${TARGET:-baremetal}" echo " Colibri : ${FEATURE_COLIBRI:-NO} (agent ${ZOT_VERSION:-} / stage ${COLIBRI_STAGE_AGENT:-YES})" echo "" -# Name the output: clawdie--.img, where the version -# tracks zot (see ISO_VERSION above). Per-build provenance — date, clawdie-iso -# commit, zot commit — lives in build-manifest.json, not the filename. +# Name the output: clawdie--.img, where the version is +# the ISO product version (see ISO_VERSION above). Per-build provenance — date, +# clawdie-iso/colibri/zot/clawdie-ai commits — lives in build-manifest.json. BUILD_FREEBSD_MAJOR="${FREEBSD_RELEASE_SERIES%%.*}" BUILD_FREEBSD_STAMP="$(printf '%s' "${FREEBSD_RELEASE_SERIES}" | tr 'A-Z' 'a-z')" case "${BUILD_FREEBSD_MAJOR}" in @@ -481,13 +484,31 @@ write_build_manifest() { if [ -n "${LIVE_SSH_PUBKEY_FP:-}" ]; then _live_ssh_pubkey_fp_json="\"$(json_escape "${LIVE_SSH_PUBKEY_FP}")\"" fi + # Colibri provenance: the image stages adjacent colibri binaries, so record + # which commit produced them (the biggest gap for a reproducible release). + _colibri_commit="unknown" + _colibri_dirty="null" + if [ "${FEATURE_COLIBRI:-NO}" = "YES" ]; then + resolve_colibri_paths + if git -C "${_resolved_colibri_repo}" rev-parse --git-dir >/dev/null 2>&1; then + _colibri_commit=$(git -C "${_resolved_colibri_repo}" rev-parse HEAD 2>/dev/null || echo unknown) + if git -C "${_resolved_colibri_repo}" diff --quiet 2>/dev/null && \ + git -C "${_resolved_colibri_repo}" diff --cached --quiet 2>/dev/null; then + _colibri_dirty="false" + else + _colibri_dirty="true" + fi + fi + fi mkdir -p "$(dirname "$_manifest_path")" cat > "$_manifest_path" <