clawdie-ai (TypeScript) is being phased out in favor of the colibri
(Rust) control plane. Remove its shallow git checkout from
/home/clawdie/ai/ on the ISO. The build manifest still records
clawdie-ai provenance; skills import and release gate checks are
unaffected — this only drops the source snapshot.
Also update the ai/README.txt to note the phase-out.
Documents the proven end-to-end chain: seed importer (rc.d BEFORE LOGIN)
→ BW creds in provider.env → clawdie-vault-fetch → colibri_daemon restart.
The only remaining click is the 'Join Hive' desktop launcher; the seed
partition already reduces onboarding from 3 typed secrets to one
double-click. True zero-touch requires ~30 lines of shell (xdg autostart).
Also records the zot extensions verdict: onboarding panel rejected
(chicken-and-egg), guard deferred (zot is not OOTB runtime), MCP bridge
kept as the first extension worth building (gated on colibri#143).
Stages the publish-time doc bump from 0.10.0 to 0.11.0: artifact filenames and
osa download/verify URLs (FLASHING, README, TESTING, BUILD, iso-publish skill),
the ISO product-version claims (README, BUILD), and enriches the existing
CHANGELOG [0.11.0] entry with this cycle's operator-facing ISO merges
(Join Hive vault provisioning, Tailscale auto-join, Mother MCP link, jq).
Left untouched: --clawdie-version examples (clawdie-ai namespace) and the
[0.10.0] CHANGELOG history. HOLD until the 0.11.0 image is built + hosted —
the download URLs 404 until then.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
build.cfg already targets ISO_VERSION 0.11.0; the runbook still said 0.10.0.
Scoped to the release-cutting doc only — download-URL docs (FLASHING/README/
TESTING) stay at 0.10.0 until 0.11.0 is actually published, and CHANGELOG
history is untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bumps the zot agent tag the image ships, consistently across build.cfg,
the preflight hint (build.sh), the staging hint (stage-zot-iso.sh), and the
live-rebuild doc. Continues work started by Codex (chore/zot-0.2.42-pin).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update the ISO default Zot pin and build docs from v0.2.29 to v0.2.42 so the next image stages the current rebuilt FreeBSD zot binary instead of recording a mismatched checkout/binary pair. Also refresh the release runbook's 0.11.0 examples.\n\nValidation: ./scripts/check-format.sh; sh -n build.sh scripts/stage-zot-iso.sh; BUILD_CHANNEL=dev build.cfg default check; git diff --check.
The spawner uses stdin(Stdio::null()); zot's --json and rpc modes
both require input. Pi's --mode json is autonomous. Document the
blocker inline so nobody tries the pi→zot config flip without the
driver. Ref: colibri issue zot-rpc-driver + ADR-agent-harness-consolidation.md.
PR #102 wired the standalone tailscale-auth-key vault item, but the
out-of-the-box path (no baked key) could not actually start the service:
- clawdie-tailscale-up kept required_files=<keyfile>, which onestart still
enforces; the keyfile is absent on the OOTB image. Removed it — the start
function already returns 0 when neither provider.env nor the keyfile carries
a key, so the guard is redundant.
- join-hive called `service ... start`: refused because the service defaults to
enable=NO without a baked key, and it lacked root. Now `mdo -u root service
... onestart` (root + bypass rcvar).
- join-hive's post-join cleanup ran `sed ... provider.env/d` — a stray /d on the
file path made it error. Dropped it; the rc.d strips the key on success.
- join-hive interpolated the key into `sh -c "..."` argv (visible in ps). Now
piped via stdin.
Also keep provider.env at 0600 after the rc.d rewrite (it still holds BW_*).
Validated: sh -n on both scripts, ./scripts/check-format.sh clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- join-hive.sh: sed -i '' '/^TAILSCALE_AUTH_KEY=*** → .../d' (delete was missing)
- tailscale-up: grep -v pattern aligned to match any value, not literal ***
- Both files pass sh -n
Adds step [2b] to join-hive: if bw is available and the node is not
yet on Tailscale, fetch the tailscale-auth-key item from Vaultwarden,
write TAILSCALE_AUTH_KEY to provider.env, and trigger tailscale-up.
- Handles both naming variants (tailscale-auth-key / tailscale_auth_key)
- One-shot: key removed from provider.env after successful join
- tailscale-up now reads from provider.env first, legacy key file as fallback
- Graceful: no vault item → clear message, no break
Move jq into the agent-jail section so the package list mirrors Colibri's agent-jail-bootstrap baseline, and apply Prettier to pulled markdown drift.\n\nValidation: ./scripts/check-format.sh; sh -n build.sh scripts/stage-colibri-iso.sh live/operator-session/clawdie-join-hive.sh live/operator-session/clawdie-enable-mother.sh live/operator-session/colibri-live-rebuild; ./scripts/test-release-gate.sh; git diff --check.
Vault-mediated key exchange (direction B — we call mother). After ensuring the
colibri SSH identity, enable-mother now upserts the pubkey into Vaultwarden as
`hive-pubkey-<hostname>` (via bw, run as root so it can read the BW_* bootstrap
creds from provider.env). Mother's mother-sync-hive-keys rebuilds its
authorized_keys from these items, so no operator copy-paste between machines.
The printed pubkey + restricted command= line remain as a manual fallback when
the vault publish is unavailable. Uses the bitwarden-cli-vault skill's
session+upsert pattern. sh -n clean; embedded JSON/id-extraction tested.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Track C's enable-mother overwrote external-mcp.json with a single mother
server. Use jq to merge the mother entry into the existing registry so other
configured servers are preserved, written atomically (mktemp in same dir + mv).
This is the concrete consumer that makes jq a real dependency of the MCP path;
fails loudly if jq is absent.
(Re-applied: the original commit was lost to a branch-recreation race when #97
merged at the packages-only commit.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The MCP tooling needs jq on PATH to parse colibri-mcp / external MCP JSON-RPC
output. Add it to the live operator image (where the auto-spawned Pi and
colibri-mcp run) and to the jail package union. The jail entry mirrors the
matching addition in Colibri's agent-jail-bootstrap.sh (kept in sync per the
list header).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per Hermes' review of the cred-capture flow: after the daemon restart that
loads the pulled keys, poll colibri status (up to 10s) for a live agent so the
operator sees confirmation that the Pi auto-spawn actually came up — instead of
just "daemon restarted". Prints "Pi agent is live." or a check hint.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Workstream C of the next ISO rebuild.
C1 — Auto-spawn lit up out of the box:
provider.env now ships COLIBRI_AUTOSPAWN_PI="YES", so colibri#137 fires on
the booted image once a DeepSeek key is present (pulled by Join Hive, A).
C2 — External MCP registry staged:
/usr/local/etc/colibri/external-mcp.json shipped as {"servers":{}} at the
path colibri-mcp reads by default. Empty = mother off by default.
C3 — Opt-in "Enable Mother Link" (clawdie-enable-mother + desktop entry):
Direction is "our Pi calls mother's tools" — colibri-mcp dials OUT to mother
over SSH-stdio and proxies mother's tools to the Pi via its external-call
path. The toggle:
- provisions an SSH identity for the colibri service account
(/var/db/colibri/.ssh — the daemon and its Pi run as `colibri`),
- writes the mother entry into external-mcp.json (ssh -i <key> ... mother),
- upserts COLIBRI_MCP_EXTERNAL_CALL=1 into provider.env,
- restarts the daemon and prints colibri's pubkey to authorize on mother.
provider.env.sample documents the new toggles. sh -n clean on all scripts;
the empty default and the emitted mother entry validate as JSON and match the
ExternalMcpRegistry {servers:{command,args,env}} shape.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Workstream A of the next ISO rebuild. The booted XFCE image's "Join Hive"
flow now collects the 3 Vaultwarden bootstrap values and pulls the provider
keys, instead of only warning when they are missing.
Step [2/4] now:
- If provider.env lacks BW_*, prompts for BW_CLIENTID/BW_CLIENTSECRET/
BW_PASSWORD (secret + password read with echo off) and upserts them into
provider.env (root-owned 0600). Entering nothing skips — manual floor intact.
- Then runs clawdie-vault-fetch against provider.env (as bootstrap and as
--write-env target) to pull DEEPSEEK_API_KEY (and other agent-secrets), and
restarts colibri_daemon so it loads the new keys — which triggers the Pi
auto-spawn (colibri#137).
Secrets never appear in process arguments: values stay in shell variables and a
0600 temp under ~/.cache/clawdie; provider.env is read/written via mdo. The
upsert preserves the endpoint line and other keys (verified: special characters
in the secret/password survive, no duplicate BW_* lines).
provider.env stays the single secret store — the daemon's vault provisioning and
the existing provider_env_has_bw_creds check already assume that.
sh -n clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The product-version scheme was only captured in scattered build.cfg/build.sh
comments and agent memory. Promote it to contributor-visible guidance:
- ISO_VERSION is an explicit product version in build.cfg (0.11.0, unified
with Colibri); no-version builds fail fast; image name = codename + version.
- Component versions are provenance in build-manifest.json (version_scheme
"product"), not the image identity.
- BUILD_CHANNEL dev|release; release gate (build.sh:check_release_gate)
requires clean staged trees so the manifest fully describes the artifact.
Matches shipped code; no behavior change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR #92 wired the ISO to the shared clawdie-npm-profile.sh but hardcoded
${SCRIPT_DIR}/../colibri and had no existence guard. Every other colibri
consumer in build.sh resolves through resolve_colibri_paths (default
/home/clawdie/ai/colibri, honoring COLIBRI_REPO), so the hardcoded path
diverged from the real build-host layout and ignored the override; a
missing file let cat fail silently into a half-written snippet.
Now: resolve via resolve_colibri_paths and preflight the file with a
clear error pointing at COLIBRI_REPO, matching preflight_colibri_artifacts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Completes colibri#122. The ISO now installs the canonical
clawdie-npm-profile.sh from colibri (same file agent-jail-bootstrap
uses). The ISO-specific clawdie.sh sources it rather than
duplicating the npm PATH + npm config lines.
Track C rewritten: old TS tarball-deploy plumbing replaced with
the clawdie Rust binary strategies (C1: CLI, C2: wizard, C3: declarative).
References the existing clawdie crate in Colibri (discover → plan → apply).
C1 is zero new code — needs only 1 destructive validation test.
Project Identity added: the ISO builds the operator USB which is both
the Colibri development surface AND the Clawdie bare-metal service
installer. Clawdie service target: ZFS RAID1, PostgreSQL + pgvector,
bhyve VMs, Bastille jails.
The one-liner's `output/FreeBSD-*.img` matched nothing — OUTPUT_DIR is
tmp/output, the built image is clawdie-*.img, and the cached memstick lives in
tmp/cache (FreeBSD-*-memstick.img). Replace with `tmp/packages tmp/cache
tmp/output` — clears bundled packages, all caches (incl. work.img + the cached
memstick), and built outputs; all regenerable, all under repo-local tmp/.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>