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>
Tier 1 of the hermes out-of-the-box dependency sweep. hermes is a Python/uv app
(requires-python >=3.11,<3.14) whose venvs use --system-site-packages, so system
py311-* pkgs satisfy compiled deps without building.
- ffmpeg: hermes runtime baseline (installer) + voice-transcription/media skills.
- py311-pillow: Pillow is a hermes CORE dependency; the --system-site-packages
venv picks up the prebuilt system pkg (no source build).
- python311 explicit (python3 = 3.11 after the default flip); python312 stays.
- Fix the stale "python312 owns python3" comment.
Covers hermes core + telegram gateway + voice. Tier 2 (discord-voice libsodium/
opus, astro vips, ollama/llama-cpp) pending confirmation of default integrations.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stop fighting FreeBSD's PYTHON_DEFAULT=3.11: make python3 resolve to 3.11
(python312 stays installed and available as python3.12 for anything needing
newer). This also makes Pillow trivial — py311-pillow imports on plain python3,
so the image-render/screenshot skill needs no version gymnastics.
- build.sh: python3/python symlink → 3.11 (prefer python3.11, else lowest).
- pkg-list-live-operator.txt: add py311-pillow.
- clawdie-join-hive.sh: advertise image-render when `python3 -c import PIL`
works, and screenshot when $DISPLAY is set.
- BUILD.md: short note (python3=3.11; python3.12 available; image-render via
py311-pillow).
Validated: sh -n build.sh + join-hive clean; markdown gate clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
FreeBSD pkg repos build against PYTHON_DEFAULT=3.11, so system packages
(git, libinput, npm-node24) pull python311 as transitive deps. We keep
python312 as the application Python — it wins the python3 symlink via
sort -V. Document this in BUILD.md, build.sh, package lists, and
bootstrap.html so the dual-version reality is explicit and intentional.
Add COLIBRI_STAGE_TEST_AGENT with dev/release defaults so validation builds can include colibri-test-agent while production/release operator USB images omit it by default. Keep poudriere guidance test-friendly and document binary roles in BUILD.md.\n\nValidation: sh -n build.sh scripts/stage-colibri-iso.sh live/operator-session/colibri-live-rebuild; ./scripts/check-format.sh; ./scripts/test-release-gate.sh; build.cfg default/override checks.
Concise, release-specific handoff for codex/osa: repo state at unified 0.11.0
(commits + tags), the release-channel build command, the release-gate clean-tree
requirement (iso/colibri/clawdie-ai/zot), and the two caveats for this build —
colibri ships as raw FreeBSD binaries (poudriere/Phase 4 deferred until
mother-build) and CI is dormant (validate via local gates, not forge checks).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an agent-jail section to pkg-list-jails.txt mirroring Colibri agent-jail-bootstrap.sh, include python312, and use npm-node24 instead of generic npm. This satisfies issue #70 acceptance and resolves the npm package-name drift in favor of the node24-tied package.\n\nValidation: ./scripts/check-format.sh; sh -n build.sh; git diff --check
Match the colibri relicense (AGPL-3.0 -> MIT, same as layered-soul) in the
build-server doc's port key-facts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- build.cfg: ISO_VERSION 0.10.0 -> 0.11.0; reword the version note — clawdie-iso
and colibri now share one unified Clawdie release version (zot/clawdie-ai stay
provenance in build-manifest.json).
- CHANGELOG: [0.11.0] entry (date in EU format DD.mon.YYYY per AGENTS rule)
covering the versioning unify, operator-session hardening, poudriere
build-server scripts, and the duplicate-port retirement.
colibri Cargo.toml + port DISTVERSION bump to 0.11.0 lands in the colibri repo
(separate branch). Tags held until both bumps merge.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The canonical Colibri FreeBSD port lives in the colibri repo
(packaging/freebsd/port/sysutils/colibri), kept with the code it builds and
guarded by a CARGO_CRATES drift check in colibri CI. The copy here was a
divergent duplicate (wrong LICENSE=MIT vs AGPLv3, CARGO_BUILD=no skeleton that
could not build, different binary set) that the drift check could not protect.
- delete ports/sysutils/colibri/ (no longer maintained here)
- build.sh release gate: fail if ports/sysutils/colibri/ reappears, pointing at
the canonical location — keeps the cleanup structural, not just one-time
- docs/POUDRIERE-BUILD-SERVER.md + scripts/poudriere/README.md: state colibri
owns the port, copy it into the ports tree, this repo keeps no duplicate
Validation: build.sh sh -n clean; release-gate self-test passes; guard fires on
a reintroduced dir; markdown gate clean. Nothing references the deleted path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Replace GH_ACCOUNT+GH_PROJECT with MASTER_SITES pointing at
code.smilepowered.org/clawdie/colibri/archive/
- Fix distinfo to match Forgejo archive naming (v0.0.1.tar.gz)
clawdie_live_power is a one-shot boot script that applies the power_profile
C-state policy once (FreeBSD's power_profile is nostart and otherwise only
runs on a devd AC-line transition). Comment-only clarification — no behavior
change:
- Move the PROVIDE/REQUIRE/BEFORE/KEYWORD rcorder block to the top (convention;
rcorder scans the whole file, so behavior is identical).
- Document scope explicitly: this selects a CPU C-state/freq profile ONLY —
never suspend/sleep/blank/DPMS (screen-blank is the separate no-blank stack).
- Record the wake-safety invariant: both AC (0x01) and battery (0x00) branches
are safe because rc.conf pins performance_cx_lowest AND economy_cx_lowest to
C3, so neither can select a deeper C-state that breaks USB resume. Guard-rail
for future editors: do not deepen on the live USB.
sh -n clean; rcorder tags intact.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The inline Makefile example claimed LICENSE=MIT (wrong — colibri is
AGPL-3.0-only) and duplicated what now lives canonically in
colibri/packaging/freebsd/port/. Replace the snippet with a pointer + the
corrected key facts (license, binaries shipped, generated files).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>