feat(iso): live-rebuild lane covers zot + version-model cleanup #56
9 changed files with 101 additions and 47 deletions
8
BUILD.md
8
BUILD.md
|
|
@ -21,7 +21,7 @@ On `xfce-operator-usb`, builds a bootable FreeBSD 15.0 operator USB image with:
|
|||
The ISO version is independent from the bundled Clawdie-AI ref:
|
||||
|
||||
```sh
|
||||
ISO_VERSION="0.1.0"
|
||||
ISO_VERSION="auto" # default: git describe, then ZOT_VERSION fallback
|
||||
BUILD_CHANNEL="dev" # dev | release
|
||||
CLAWDIE_REF="main" # validation default
|
||||
```
|
||||
|
|
@ -92,7 +92,7 @@ Colibri-backed. The image includes:
|
|||
```
|
||||
|
||||
The build also creates the `colibri` service user/group and writes rc.conf
|
||||
values for `colibri_daemon_enable`, paths, and `colibri_cost_mode`. Operator USB
|
||||
values for `colibri_daemon_enable`, paths, and `colibri_daemon_cost_mode`. Operator USB
|
||||
validation builds enable `colibri_daemon_enable=YES`; the service starts after
|
||||
the login milestone and is the lightweight control plane for the live USB.
|
||||
|
||||
|
|
@ -396,7 +396,7 @@ boolean `tailscale_auth_key_baked: true|false` is recorded in the manifest.
|
|||
The build header shows:
|
||||
|
||||
```text
|
||||
ISO : 0.1.0-dev
|
||||
ISO : <iso-version>-dev
|
||||
FreeBSD : 15.0-RELEASE amd64
|
||||
Clawdie : main
|
||||
Clawdie commit: <resolved-sha>
|
||||
|
|
@ -428,7 +428,7 @@ The final size output distinguishes:
|
|||
Edit `build.cfg` for persistent defaults:
|
||||
|
||||
```sh
|
||||
ISO_VERSION="0.1.0"
|
||||
ISO_VERSION="${ISO_VERSION:-auto}"
|
||||
BUILD_CHANNEL="${BUILD_CHANNEL:-dev}"
|
||||
IMAGE_SIZE="28G"
|
||||
CLAWDIE_REF="${CLAWDIE_REF:-main}"
|
||||
|
|
|
|||
21
CHANGELOG.md
21
CHANGELOG.md
|
|
@ -7,12 +7,16 @@ All notable changes to Clawdie-ISO are documented here.
|
|||
## [Unreleased]
|
||||
|
||||
### 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)
|
||||
|
||||
### 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-<freebsd-codename>-<version>.img`. No separately invented ISO number.
|
||||
|
||||
---
|
||||
|
||||
## [0.9.0] — 2026-04-06
|
||||
|
|
@ -54,9 +58,14 @@ All notable changes to Clawdie-ISO are documented here.
|
|||
|
||||
## Repository Status
|
||||
|
||||
| Repo | Status | Latest |
|
||||
|------|--------|--------|
|
||||
| clawdie-ai | Active | v0.9.0 |
|
||||
| clawdie-iso | Active | v0.9.0 + Phase 0 |
|
||||
| clawdie-shell | **Archived** | — |
|
||||
| pi | Independent | v0.56.3 |
|
||||
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.
|
||||
|
||||
| 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-ai | Being pruned (features → zot/Colibri) | — |
|
||||
| pi | Demoted — spawnable backend, not default | upstream npm |
|
||||
| clawdie-shell | **Archived** (merged into clawdie-iso) | — |
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ contract between agents.
|
|||
| ------------------ | ------------------------------ | ---------------------------------- | ----------------------------------------------------- |
|
||||
| Build result | `iso-build` | `clawdie.iso.build.v1` | Commit, flags, log path, output files, static checks |
|
||||
| Publish result | `iso-publish` | `clawdie.iso.publish.v1` | Public URLs, checksums, manifest path, symlink state |
|
||||
| Flash verification | `iso-flash-verify` | `clawdie.iso.flash.v1` | Download, checksum, xz test, target disk fit, flash |
|
||||
| Flash verification | `iso-flash-verify` | `clawdie.iso.flash.v1` | Download, checksum, xz test, target disk fit, flash |
|
||||
| Mounted validation | `iso-validate-image` | `clawdie.iso.validation.v1` | SDDM, CLIs, `mdo`, seed slice, no-blank, panel assets |
|
||||
| Hardware report | `iso-hardware-report-ingest` | `clawdie.iso.hardware.v1` | GPU/KMS, GL renderer, input, audio, Wi-Fi, SDDM/XFCE |
|
||||
| Package audit | `iso-package-audit` | `clawdie.iso.package-audit.v1` | Category, size, flat size, reason kept, deferral risk |
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ BUILD_CHANNEL=release sudo ./build.sh --clawdie-version 0.10.0
|
|||
The build prints provenance similar to:
|
||||
|
||||
```text
|
||||
ISO : 0.1.0-dev
|
||||
ISO : <iso-version>-dev
|
||||
FreeBSD : 15.0-RELEASE amd64
|
||||
Clawdie : main
|
||||
Clawdie commit: <sha>
|
||||
|
|
|
|||
44
build.sh
44
build.sh
|
|
@ -820,7 +820,7 @@ install_colibri_service() {
|
|||
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'colibri_daemon_logfile="/var/log/colibri/daemon.log"'
|
||||
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'colibri_daemon_provider_env="/usr/local/etc/colibri/provider.env"'
|
||||
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'colibri_daemon_host="$(hostname)"'
|
||||
set_config_line "${MOUNT_POINT}/etc/rc.conf" "colibri_cost_mode=\"${COLIBRI_COST_MODE:-smart}\""
|
||||
set_config_line "${MOUNT_POINT}/etc/rc.conf" "colibri_daemon_cost_mode=\"${COLIBRI_COST_MODE:-smart}\""
|
||||
|
||||
if [ ! -x "${MOUNT_POINT}/usr/local/bin/colibri-daemon" ] || \
|
||||
[ ! -x "${MOUNT_POINT}/usr/local/bin/colibri" ] || \
|
||||
|
|
@ -1055,14 +1055,22 @@ seed_live_ai_source_repo() {
|
|||
return 0
|
||||
fi
|
||||
|
||||
echo " Seeding AI source snapshot: ${_repo_name}"
|
||||
rm -rf "${_repo_dest}"
|
||||
mkdir -p "${_repo_dest}"
|
||||
git -C "${_repo_src}" archive --format=tar HEAD | tar -C "${_repo_dest}" -xf -
|
||||
|
||||
_repo_branch=$(git -C "${_repo_src}" symbolic-ref --short -q HEAD 2>/dev/null || echo detached)
|
||||
_repo_commit=$(git -C "${_repo_src}" rev-parse HEAD 2>/dev/null || echo unknown)
|
||||
_repo_origin=$(git -C "${_repo_src}" remote get-url origin 2>/dev/null || echo unknown)
|
||||
_repo_src_real=$(cd "${_repo_src}" && pwd -P)
|
||||
|
||||
echo " Seeding AI source checkout: ${_repo_name} (${_repo_commit})"
|
||||
rm -rf "${_repo_dest}"
|
||||
if [ "${_repo_branch}" != "detached" ]; then
|
||||
git clone --quiet --depth 1 --branch "${_repo_branch}" "file://${_repo_src_real}" "${_repo_dest}"
|
||||
else
|
||||
git clone --quiet "file://${_repo_src_real}" "${_repo_dest}"
|
||||
git -C "${_repo_dest}" checkout --quiet --detach "${_repo_commit}"
|
||||
fi
|
||||
git -C "${_repo_dest}" remote set-url origin "${_repo_origin}" 2>/dev/null || true
|
||||
printf '%s\n' '.clawdie-source.json' >> "${_repo_dest}/.git/info/exclude"
|
||||
|
||||
_repo_dirty=false
|
||||
if ! git -C "${_repo_src}" diff --quiet 2>/dev/null || ! git -C "${_repo_src}" diff --cached --quiet 2>/dev/null; then
|
||||
_repo_dirty=true
|
||||
|
|
@ -1076,31 +1084,39 @@ seed_live_ai_source_repo() {
|
|||
"branch": "$(json_escape "${_repo_branch}")",
|
||||
"commit": "$(json_escape "${_repo_commit}")",
|
||||
"dirty_at_build": ${_repo_dirty},
|
||||
"snapshot_note": "git archive of HEAD; uncommitted changes and ignored/private files are not included"
|
||||
"iso_version": "$(json_escape "${ISO_VERSION}")",
|
||||
"build_channel": "$(json_escape "${BUILD_CHANNEL}")",
|
||||
"snapshot_kind": "shallow git checkout",
|
||||
"snapshot_note": "shallow git checkout of HEAD; uncommitted changes and ignored/private files are not included"
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
install_live_ai_source_snapshots() {
|
||||
echo " Installing live AI source snapshots..."
|
||||
echo " Installing live AI source checkouts..."
|
||||
resolve_clawdie_ai_repo
|
||||
resolve_colibri_paths
|
||||
mkdir -p "${MOUNT_POINT}/home/clawdie/ai"
|
||||
cat > "${MOUNT_POINT}/home/clawdie/ai/README.txt" <<'EOF'
|
||||
Clawdie live AI source snapshots
|
||||
Clawdie live AI source checkouts
|
||||
|
||||
These directories are included so the operator can start a local provider-backed
|
||||
Pi session from the live XFCE desktop and inspect the shipped source beside the
|
||||
running system.
|
||||
Pi session from the live XFCE desktop, inspect the shipped source beside the
|
||||
running system, and fetch follow-up commits from Forgejo when network access is
|
||||
available.
|
||||
|
||||
No API keys, .env files, SSH private keys, build caches, package caches, tmp/
|
||||
directories, or uncommitted worktree changes are included. Each snapshot has a
|
||||
.clawdie-source.json file recording the source remote, branch, commit, and dirty
|
||||
state at image build time.
|
||||
directories, or uncommitted worktree changes are included. Each checkout keeps a
|
||||
.git directory plus a .clawdie-source.json file recording the source remote,
|
||||
branch, commit, dirty state, ISO version, and build channel at image build time.
|
||||
EOF
|
||||
seed_live_ai_source_repo "${SCRIPT_DIR}" "clawdie-iso"
|
||||
seed_live_ai_source_repo "${_resolved_clawdie_ai_repo}" "clawdie-ai"
|
||||
seed_live_ai_source_repo "${_resolved_colibri_repo}" "colibri"
|
||||
# zot source so the live rebuild lane can rebuild the agent (Go) too, not
|
||||
# just Colibri (Rust). Skipped automatically if the zot checkout is absent.
|
||||
resolve_zot_paths
|
||||
seed_live_ai_source_repo "${_resolved_zot_repo}" "zot"
|
||||
chroot "${MOUNT_POINT}" chown -R clawdie:clawdie /home/clawdie/ai
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,18 +10,11 @@ the next image is rebuilt.
|
|||
|
||||
## Why this exists
|
||||
|
||||
The live USB currently stages `/home/clawdie/ai/colibri` as a source snapshot
|
||||
from `git archive`. That snapshot is useful for inspection, but it is not a real
|
||||
git checkout and has no `.git` directory:
|
||||
|
||||
```sh
|
||||
cd /home/clawdie/ai/colibri
|
||||
git remote -v
|
||||
# fatal: not a git repository (or any of the parent directories): .git
|
||||
```
|
||||
|
||||
For rebuilds, clone a fresh working checkout into a separate directory such as
|
||||
`/home/clawdie/ai/colibri-build` or `/var/tmp/colibri-build`.
|
||||
New live USB builds stage `/home/clawdie/ai/colibri` as a shallow git checkout
|
||||
with a `.git` directory and a `.clawdie-source.json` provenance file. You can
|
||||
rebuild directly from that checkout, or clone a separate working checkout such
|
||||
as `/home/clawdie/ai/colibri-build` if you want to keep the shipped source
|
||||
untouched while testing a branch.
|
||||
|
||||
## Required live packages
|
||||
|
||||
|
|
@ -32,10 +25,12 @@ box:
|
|||
rust
|
||||
pkgconf
|
||||
git
|
||||
go
|
||||
```
|
||||
|
||||
`git` is already in the live operator package list. `rust` provides `cargo` on
|
||||
FreeBSD. `pkgconf` is needed by common Rust native dependency build scripts.
|
||||
`go` builds the zot agent (see "Rebuild zot" below).
|
||||
|
||||
Optional if future dependencies need them:
|
||||
|
||||
|
|
@ -56,7 +51,8 @@ pkgconf --version
|
|||
```
|
||||
|
||||
If `rustc` or `cargo` is missing, the current USB cannot rebuild Colibri from
|
||||
source without installing packages first or using a newer ISO.
|
||||
source without installing packages first or using a newer ISO. Likewise check
|
||||
`go version` before attempting a zot rebuild.
|
||||
|
||||
## Clone or update Colibri
|
||||
|
||||
|
|
@ -181,6 +177,36 @@ mdo -u root install -m 0644 /tmp/colibri-live-rebuild.sha256 /var/db/colibri/liv
|
|||
|
||||
Report both files with validation notes when handing findings back through git.
|
||||
|
||||
## Rebuild zot (agent)
|
||||
|
||||
zot is the Go agent staged as a prebuilt binary at `/usr/local/bin/zot`. New
|
||||
live USB builds seed `/home/clawdie/ai/zot` as a shallow git checkout with
|
||||
`.clawdie-source.json` provenance, so you can rebuild there or clone a separate
|
||||
`zot-build` checkout for branch testing.
|
||||
|
||||
```sh
|
||||
mkdir -p /home/clawdie/ai
|
||||
cd /home/clawdie/ai
|
||||
if [ ! -d zot-build/.git ]; then
|
||||
git clone https://code.smilepowered.org/clawdie/zot.git zot-build
|
||||
fi
|
||||
cd zot-build
|
||||
git fetch --prune origin
|
||||
git checkout v0.2.29 # ship the tag the ISO version tracks
|
||||
|
||||
go build -trimpath -o bin/zot ./cmd/zot
|
||||
```
|
||||
|
||||
Install into the running USB (privileged steps via `mdo`):
|
||||
|
||||
```sh
|
||||
mdo -u root install -m 0555 bin/zot /usr/local/bin/zot
|
||||
zot --version
|
||||
```
|
||||
|
||||
zot has no rc.d service of its own — Colibri spawns it — so no service restart
|
||||
is needed. Validate with `zot --version` and a Colibri spawn check.
|
||||
|
||||
## Fast rc.d-only repair
|
||||
|
||||
If only the service script is broken and no binary rebuild is needed, fetch the
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Clawdie Operator USB — v0.9.1</title>
|
||||
<title>Clawdie Operator USB</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #f3f1ea;
|
||||
|
|
@ -84,7 +84,7 @@
|
|||
</p>
|
||||
|
||||
<div class="card">
|
||||
<strong>Included now (v0.9.1):</strong>
|
||||
<strong>Included in this build:</strong>
|
||||
<ul>
|
||||
<li>XFCE desktop — dual-monitor, panel, wallpaper</li>
|
||||
<li><code>colibri-daemon</code> — agent supervisor, skills catalog, Glasspane state machine</li>
|
||||
|
|
|
|||
|
|
@ -21,10 +21,13 @@ bash
|
|||
zsh
|
||||
ohmyzsh
|
||||
git
|
||||
# Live Colibri rebuild lane: lets the running USB rebuild and redeploy Colibri
|
||||
# Live rebuild lane: lets the running USB rebuild and redeploy the agent stack
|
||||
# without a full ISO rebuild for every small service/runtime iteration.
|
||||
# rust + pkgconf -> Colibri (Rust control plane)
|
||||
# go -> zot (Go agent)
|
||||
rust
|
||||
pkgconf
|
||||
go
|
||||
tailscale
|
||||
avahi-app
|
||||
nss_mdns
|
||||
|
|
|
|||
|
|
@ -73,9 +73,9 @@ install -m 0644 "${NEWSYSLOG_SOURCE}" "${NEWSYSLOG_DIR}/colibri.conf"
|
|||
if ! grep -q '^command="/usr/sbin/daemon"' "${RC_DIR}/colibri_daemon" || \
|
||||
! grep -q -- '-o .*colibri_daemon_binary' "${RC_DIR}/colibri_daemon" || \
|
||||
! grep -q 'colibri_daemon_provider_env' "${RC_DIR}/colibri_daemon" || \
|
||||
! grep -q 'rm -f "${colibri_daemon_socket}" "${pidfile}" "${supervisor_pidfile}"' "${RC_DIR}/colibri_daemon" || \
|
||||
! grep -q 'chmod 644 "${pidfile}"' "${RC_DIR}/colibri_daemon" || \
|
||||
! grep -q 'chmod 660 "${colibri_daemon_socket}"' "${RC_DIR}/colibri_daemon"; then
|
||||
! grep -q 'colibri_daemon_cost_mode' "${RC_DIR}/colibri_daemon" || \
|
||||
! grep -q 'rm -f "${pidfile}" "${supervisor_pidfile}"' "${RC_DIR}/colibri_daemon" || \
|
||||
! grep -q 'export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"' "${RC_DIR}/colibri_daemon"; then
|
||||
echo "ERROR: staged colibri_daemon rc.d script is missing required live USB supervision hooks" >&2
|
||||
echo " Update COLIBRI_REPO (${COLIBRI_REPO}) before building." >&2
|
||||
exit 66
|
||||
|
|
@ -99,8 +99,8 @@ colibri_daemon_socket="/var/run/colibri/colibri.sock"
|
|||
colibri_daemon_db_path="/var/db/colibri/colibri.sqlite"
|
||||
colibri_daemon_logfile="/var/log/colibri/daemon.log"
|
||||
colibri_daemon_provider_env="/usr/local/etc/colibri/provider.env"
|
||||
colibri_daemon_host="\$(hostname)"
|
||||
colibri_cost_mode="${COLIBRI_COST_MODE}"
|
||||
colibri_daemon_host="\$(/bin/hostname)"
|
||||
colibri_daemon_cost_mode="${COLIBRI_COST_MODE}"
|
||||
EOF
|
||||
|
||||
cat > "${ETC_DIR}/provider.env.sample" <<'EOF'
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue