From 116277ba7a9481ba8991eac2ee94a3816f52e982 Mon Sep 17 00:00:00 2001 From: Sam & Claude Date: Wed, 24 Jun 2026 10:56:56 +0200 Subject: [PATCH] docs(mother): add osa first-run verification checklist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An ordered first-run checklist for deploying on osa (or any new mother), covering the things that can only be validated against a live PostgreSQL + FreeBSD host: - build 0.12 on FreeBSD from current main + ci-checks (Linux binaries won't run) - record any pre-existing node-register before install - post-install integrity: installed node-register is the hardened hive_nodes version (grep -c "E'" == 0; grep hive_nodes > 0) — not the injectable copy - schema migrated in place (usb_nodes renamed, not duplicated; node_type present) - peer auth works; pg_hba peer rule present AND precedes generic local rules - external-mcp has all three servers (jq-merge preserved existing) - SSH forced-command wrapper rejects non-allowlisted commands - daemon env + service live; key hygiene (private key → seed only) Captures the operational risks flagged during the mother-infra review. --- packaging/mother/MOTHER-SETUP.md | 94 ++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/packaging/mother/MOTHER-SETUP.md b/packaging/mother/MOTHER-SETUP.md index 3154eac..7a7721c 100644 --- a/packaging/mother/MOTHER-SETUP.md +++ b/packaging/mother/MOTHER-SETUP.md @@ -89,6 +89,100 @@ sudo ./packaging/mother/setup-mother.sh Idempotent — running again is a no-op. +## First-run checklist (osa) + +Run through this the **first** time you deploy on osa (or any new mother). +Most of it is `setup-mother.sh`; the checks around it catch the things that +can't be validated until a real PostgreSQL + FreeBSD host is in front of you. + +**1. Build 0.12 on FreeBSD from current `main` (provenance).** +Binaries built on Linux will not run on osa. Build and gate on the host: + +```sh +cd /home/clawdie/ai/colibri +git fetch origin && git checkout main && git merge --ff-only origin/main +./scripts/ci-checks.sh # fmt, clippy -D warnings, tests — must be green +cargo build --workspace --release +``` + +**2. Before installing — note any pre-existing (possibly unsafe) tool.** +An older `node-register-mcp` may already sit in `/usr/local/bin` from an earlier +copy. `setup-mother.sh` overwrites it, but record what was there: + +```sh +ls -l /usr/local/bin/node-register-mcp 2>/dev/null || echo "(none installed yet)" +``` + +**3. Run the canonical setup.** Copy the printed private key straight to the +node seed (step 8) — do not leave it in shell scrollback or a logged session. + +```sh +sudo ./packaging/mother/setup-mother.sh +``` + +**4. The installed `node-register-mcp` is the hardened version.** +The safe tool uses parameterized `psql -v :'var'` against `hive_nodes`; the old +one used `E'${...}'` string interpolation (SQL-injectable). Verify: + +```sh +grep -c "E'" /usr/local/bin/node-register-mcp # expect 0 +grep -c hive_nodes /usr/local/bin/node-register-mcp # expect > 0 +``` + +**5. The schema migrated, data preserved.** On an existing DB, `usb_nodes` +should be renamed to `hive_nodes` (not duplicated), with the `node_type` column: + +```sh +sudo -u postgres psql -d mother_hive -c "SELECT to_regclass('public.usb_nodes')" # expect (null) +sudo -u postgres psql -d mother_hive -c "SELECT to_regclass('public.hive_nodes')" # expect hive_nodes +sudo -u postgres psql -d mother_hive -c "\d hive_nodes" | grep node_type # column present +``` + +**6. Peer auth works for the `colibri` role.** This is what `node-register-mcp` +relies on (no password): + +```sh +sudo -u colibri psql -d mother_hive -c "SELECT hostname, node_type, status FROM hive_nodes;" +``` + +If it errors with an auth failure, confirm the peer rule landed **and precedes** +any generic `local all all` line (pg_hba is first-match): + +```sh +HBA=$(sudo -u postgres psql -tAc 'SHOW hba_file'); sudo grep -n 'mother_hive .*colibri .*peer' "$HBA" +``` + +**7. External MCP registry has all three servers** (jq-merge preserved any +existing entries): + +```sh +jq '.servers | keys' /usr/local/etc/colibri/external-mcp.json +# expect: build-colibri (mother-build) / geodesic-dome / node-register present +``` + +**8. The SSH forced-command boundary allowlists.** A non-allowlisted command +must be rejected, not run: + +```sh +ssh colibri@localhost 'rm -rf /' # expect: rejected (exit 1), nothing runs +ssh colibri@localhost tools # expect: MCP tool list +``` + +**9. Daemon picked up the env and is live:** + +```sh +grep -E 'COLIBRI_AUTOSPAWN|COLIBRI_MCP_EXTERNAL_CALL' /usr/local/etc/colibri/provider.env +service colibri_daemon status +``` + +**10. End-to-end (optional, with a real DEEPSEEK key present):** register a +sample node and confirm the `derive_capabilities()` trigger populated +`capabilities` — see the [Verification](#verification) section below. + +**11. Key hygiene:** the mother-mcp private key from step 3 is on the node seed +(`CLAWDIESEED/colibri/ssh/mother-mcp`) and nowhere else persistent. See +[Key management](#key-management). + ## Key management The mother-mcp key is NOT baked into images. It lives: -- 2.45.3