README said 'no separate feature flag', but the build keeps FEATURE_COLIBRI
(build.cfg default YES) as an internal escape hatch (e.g. building without a
colibri checkout). Clarify: colibri is staged by default; FEATURE_COLIBRI=NO is
an internal build-time hatch, not a user-facing option. Resolves a wiki-ledger
residue item.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The mother MCP scripts were copied into clawdie-iso (packaging/mother/) AND
colibri. The iso copies drifted: node-register-mcp on iso main was the old,
SQL-injectable version (E'${HOST_ESCAPED}' string interpolation) using
usb_nodes — while colibri #161 carries the reviewed, parameterized (psql -v
:'var') hive_nodes version.
One canonical home: colibri. Remove packaging/mother/ from the iso (nothing in
the iso build references it), redirect the two doc path references to the colibri
repo, and align the docs to hive_nodes (matching the colibri schema rename).
Supersedes #127 (which only renamed docs and conflicted after the iso copies
landed). Doc-only + file removals; markdown gate green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New packaging/mother/node-register-mcp accepts JSON-RPC tools/call,
inserts hw_profile into mother_hive.usb_nodes, and returns the row
with auto-derived capabilities (derive_capabilities trigger fires).
Requires one-time PostgreSQL setup on mother:
CREATE ROLE colibri WITH LOGIN;
GRANT CONNECT ON DATABASE mother_hive TO colibri;
GRANT INSERT, UPDATE ON usb_nodes TO colibri;
GRANT USAGE ON SEQUENCE usb_nodes_id_seq TO colibri;
Also updates docs to reflect 0.12 daemon behavior: hw-probe is
collected by the daemon (not the agent) and passed via CLAWDIE_HW_PROFILE
env var. COLIBRI_AUTOSPAWN_ARGS default is binary-dependent (zot->rpc,
others->--mode json).
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.