- Update ssh/config example to show mother-mcp key with both Host entries
(mother MCP and code.smilepowered.org with IdentitiesOnly yes)
- Add dedicated mother-mcp section explaining the key serves two roles:
1. MCP calls to mother (command=colibri-mcp,restrict)
2. Git pull from Forgejo as a read-only deploy key
- Note that read-only is sufficient and limits blast radius
- Update START-HERE.txt to mention git pull works OOTB with seeded key
- Stage hermes-bsd as shallow clone in /home/clawdie/ai/ (next to colibri/zot)
- Switch default harness from pi to zot (COLIBRI_PI_BINARY=zot)
- Add TELEGRAM_BOT_TOKEN placeholder to provider.env and sample
- Removes stale zot-rpc-driver blocker comment (colibri#143 resolved)
pkg lock prevents pkg upgrade from replacing the repacked
networkmgr (mdo-based) with upstream (sudo-dependent).
Run inside the chroot while devfs is still mounted.
CPU graph now comes before the systray (NetworkManager + volumeicon),
followed by the keyboard layout switcher and clock. Language widget
display-scale reduced from 60 to 50 (was still too large).
Places uBlock Origin XPI in Firefox's distribution/extensions
directory during ISO build. Also sets DontCheckDefaultBrowser via
policies.json — Firefox is the only browser on the USB so the
popup is pointless.
Firefox auto-installs the extension on first launch with no
internet required on the booted USB.
All decompress-and-write one-liners now share the same form:
xz -dc ...img.xz | of=/dev/sdX bs=4M status=progress conv=fsync && sync
- sudo removed (operator runs as root on USB stick)
- && sync appended to all image-write commands
- /dev/zero wipe commands unchanged
- build.sh echo updated to match
All decompress-and-write one-liners now share the same form:
xz -dc ...img.xz | of=/dev/sdX bs=4M status=progress conv=fsync && sync
- sudo removed (operator runs as root on USB stick)
- && sync appended to all image-write commands
- /dev/zero wipe commands unchanged
- build.sh echo updated to match
The baked mother key (build/mother-ssh-key) puts a private key in the image,
which only works for a non-published personalized stick. The offline FAT32
seed is the correct home for per-node secrets.
Teach the importer to install outbound SSH client material from an agent's
ssh/ dir into the agent home:
- config -> ~/.ssh/config (0600)
- known_hosts* -> ~/.ssh/known_hosts* (0644, merged + de-duped)
- <name>.pub -> ~/.ssh/<name>.pub (0644)
- <name> -> ~/.ssh/<name> (0600, any other file = private key)
authorized_keys stays inbound-only via _seed_install_authorized_keys.
This closes the 'without manual key exchange' gap: known_hosts pins mother's
host key so the first node->mother connect does not prompt, and the private
client key rides on the offline seed instead of the base image — so the
published image stays secret-free. Supersedes the baked-key path (#112),
which can retire once this is validated on hardware.
Verified offline (CLAWDIE_SEED_TEST): correct perms (key 0600, pub/known_hosts
0644, config 0600, .ssh 0700) and idempotent known_hosts merge across re-runs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The image-assembly guard (build/mother-ssh-key, #113) refuses to copy the
mother key into a release image, but only after a full build run. Add the
same check to check_release_gate so a BUILD_CHANNEL=release build with the
key present on the host aborts in seconds, not after fetch/build/assemble.
The assembly-time guard stays as defense in depth.
(BUILD_CHANNEL already defaults to dev in build.cfg:17, so no change needed
there.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The trigger copies osa-mother-2026 from the build host into any ISO
as long as the key file exists (which it does permanently on OSA).
A BUILD_CHANNEL=release build would embed the private key into a
publicly hosted image = mother compromise.
Add a fail-closed guard: release builds exit with an error before
copying the key. Dev builds (including personalized sticks) are
unaffected.
Copies /home/clawdie/.ssh/osa-mother-2026 (ed25519) from the build
host into the ISO at /home/clawdie/.ssh/osa-mother-2026 (0600).
Public key is in mother's authorized_keys. Lets the live USB node
SSH straight into the mother server without manual key exchange.
Skipped silently if the key file doesn't exist on the build host.
The live seed importer merged the active agent's provider keys into the
operator ~/.env, but colibri_daemon reads /usr/local/etc/colibri/provider.env
(rc.conf colibri_daemon_provider_env). So a personalized seed carrying real
provider keys never reached the daemon and no agent auto-spawned.
Route the active agent's non-BW_* keys into provider.env (0600 root) in
addition to ~/.env. The importer runs as root BEFORE LOGIN and colibri_daemon
REQUIREs LOGIN, so the daemon starts after the keys land and auto-spawns the
agent on first boot — no Join Hive click, no Vaultwarden round-trip, no typing.
This makes a personalized seed the zero-touch onboarding primitive: the image
stays generic/publishable, the FAT32 seed is the (offline) personalization
layer. BW_* still route to vault-bootstrap.env for the vault-fetch path.
Docs: seed README, START-HERE, and ONBOARDING-SIMPLIFICATION updated to
describe the direct-keys path (supersedes the xdg-autostart plan).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>