The image shipped a hard pin (@earendil-works/pi-coding-agent@0.78.0) while
'pi upgrade' on hosts had moved to 0.80.2, so builds lagged. Switch Pi to the
@latest dist-tag so every image bundles the newest Pi.
To keep the floating spec traceable, record the version that actually got
fetched in build-manifest.json as pi_version, derived from the bundled tarball
name (earendil-works-pi-coding-agent-<version>.tgz) after fetch+install.
fetch-npm-globals.sh now also echoes the resolved tarball so the build log
shows the version a dist-tag resolved to.
Other globals (bw) stay pinned. Image is node24, compatible with current Pi
(the legacy-node20 dist-tag is for node20 only).
Verified: fetch resolves @latest → 0.80.2; version extraction matches npm.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Harness-neutral, lighter wording for the optional local test-double agent
(colibri-test-agent), matching the colibri-side fake→sample rename. Only the
two references that named it 'fake-agent' (build.cfg comment, AGENTS.md
staging note); the unrelated /tmp/fake-usb example path in FIRSTBOOT.md is a
different context and left as-is.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pi-era residue in current-tense docs/strings (CHANGELOG history left intact):
- ONBOARDING-SIMPLIFICATION: COLIBRI_AUTOSPAWN_PI -> COLIBRI_AUTOSPAWN; 'Pi
agent' -> 'agent'.
- clawdie-join-hive.sh: user-facing 'Pi agent is live' / 'no Pi agent' ->
harness-neutral (default agent is now zot).
- clawdie-live-seed.README.txt: COLIBRI_AUTOSPAWN_PI -> COLIBRI_AUTOSPAWN.
- stage-colibri-iso.sh provider.env.sample: the AUTOSPAWN_ARGS example showed
'--mode json' (invalid for the zot default); note the default is
harness-derived (zot -> rpc, pi -> --mode json).
Also restore the markdown format gate: 5 docs from the 0.12.0 work were
prettier-dirty, so ./scripts/check-format.sh was already failing on main (the
gate was red and unenforced — same pattern as the colibri build break).
prettier --write brings them to style; gate is green again. No prose changes
in those 5 — formatting only.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5 steps from nothing to working: SSH key + config → enable
external MCP → register mother server → install hw-probe →
restart daemon. Uses real hosts (osa.smilepowered.org at
100.72.229.63, USB as clawdie-usb) with l33t placeholder keys.
ASCII architecture diagram showing persistent SSH child process,
JSON-RPC over stdin/stdout, mother-side forced-command wrapper.
Includes: end-to-end test, future autospawn flow, and
troubleshooting table for all common failure modes.
USB can connect to mother right now with 0.11 daemon —
colibri_external_mcp_call_tool is already in the tools list.
Just needs: SSH key, external-mcp.json, COLIBRI_MCP_EXTERNAL_CALL=1,
hw-probe installed, and daemon restart.
Architecture: USB spawns 'ssh colibri@mother colibri-mcp' as
persistent child process, JSON-RPC over stdin/stdout. Mother-side
wrapper strips forced-command layer. One SSH connection for
daemon lifetime.
Missing: node_register MCP tool on mother (needs implementation),
auto-key from seed partition (planned for 0.12 ISO build).
Cross-reference from OSA audit (2026-06-23): SSH hardening,
MCP socket, firewall, listening ports, service accounts,
external MCP servers. Each check has command + expected output.
OSA exceptions documented: password auth kept for dev access.
USB should be stricter — key-only SSH, no 0.0.0.0 bindings.
Skill saved: security-audit-clawdie (freebsd category)
Each step has diagrams, input/output schemas, test cases.
Added Step 6: mother-blender-render — photorealistic 3D via
Blender on mother node. USB requests renders via MCP, same
pattern as build-colibri.sh. 1 GiB Blender stays on mother;
light nodes get PNGs back. ~30h total implementation estimate.
GURS WFS endpoints for parcel boundaries, address lookup, and
spatial data (CC BY 4.0, free). Google 3D Tiles for photorealistic
backgrounds (paid). Four-phase plan: address → parcel → dome
placement → site-specific BOM. All Slovenian data sources
documented with endpoint URLs and coordinate systems.
Records the decision to use a pure-Python geodesic dome tool
(6KB, numpy+Pillow) instead of Blender (1 GiB, 53 packages).
OSA registered as first node in mother_hive PostgreSQL with
real hardware profile: 12GB RAM, no GPU, geodesic_dome_mcp=true.
This document serves as a capability baseline — any node that
can run Python can generate dome wireframes and structural BOMs.
Two variants of a photorealistic 6V frequency geodesic dome
encapsulating an organic farm at golden hour. Generated via
OpenRouter (google/gemini-2.5-flash-image, upscaled to 3840x2160).
The existing clawdie-operator-bg remains as the default — these
are alternatives the operator can select.
Replace the filled gradient triangle with the geodesic 2V logo:
outer triangle + inverted inner triangle at midpoints. Cyan
on dark gradient. SVG + 2560x1440 PNG render.
Replace the dot-in-triangle (docs) and plain △ (landing) with a
unified geodesic 2V subdivision logo. Both sites now use the same
geometric mark: a large triangle with an inverted inner triangle
whose vertices touch the midpoints of the outer sides.
Reflects geodesic dome design — Class I, Frequency 2 subdivision.
- OperatorBanner is ISO-only (shows when hostname !== clawdie.si)
- Production site at clawdie.si should never show it
- Replace broken emoji flags (🇬🇧🇸🇮) with clean EN/SI text labels
- Copy Astro landing page source into docs/website/ (20K, no node_modules)
- Add ISO version badge to LandingBody.astro (only shown when
ASTRO_ISO_VERSION is set during build)
- Add build_and_stage_docs() to build.sh: builds the Astro site with
the ISO version, stages output at /usr/local/share/clawdie-iso/docs/
- Skips gracefully when node/npm unavailable
- On the booted USB: open docs/index.html to see version-matched docs
- 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.