diff --git a/docs/ONBOARDING-SIMPLIFICATION.md b/docs/ONBOARDING-SIMPLIFICATION.md index 798a311..3f80398 100644 --- a/docs/ONBOARDING-SIMPLIFICATION.md +++ b/docs/ONBOARDING-SIMPLIFICATION.md @@ -42,23 +42,35 @@ just double-clicks "Join Hive" and the fetch runs automatically. | Join Hive | `live/operator-session/clawdie-join-hive.sh` | Desktop launcher: checks for creds → prompts or auto-fetches | | Seed README | `live/operator-session/clawdie-live-seed.README.txt` | Operator-facing seed partition instructions | -## Remaining work: delete the click +## Zero-touch: direct keys on the seed (implemented) -The seed partition path reduces onboarding to ONE double-click. Making it -zero-touch requires: +The click only existed to trigger the Vaultwarden round-trip. For a +personalized stick that already holds the real provider keys, that round-trip +is unnecessary — and the boot ordering already favors zero-touch: -1. **xdg autostart entry** — on first login, if BW\_\* creds are present in - provider.env AND `colibri_daemon` is not yet fully provisioned, auto-run - `clawdie-vault-fetch --write-env ` and restart the daemon. +- `clawdie_live_seed` runs as root, `BEFORE: LOGIN`. +- `colibri_daemon` runs `REQUIRE: LOGIN` — strictly after. -2. **First-boot guard** — run once per boot only (not on every login). A - sentinel file (`/var/db/clawdie/vault-fetched`) prevents re-triggering. +So the importer now merges the active agent's direct provider keys (everything +except `BW_*`) into the daemon's `provider.env` as well as the operator's +`~/.env`. The daemon starts afterward, finds `DEEPSEEK_API_KEY`, and +auto-spawns the agent (`COLIBRI_AUTOSPAWN_PI=YES`) — no click, no vault +round-trip, no typing. `BW_*` still route to `~/.config/vault-bootstrap.env` +for operators who prefer the vault-fetch path. -3. **START-HERE.txt update** — remove the "add your 3 BW secrets" section - when the seed partition is present. Show a confirmation instead: - "Secrets loaded from seed partition. Colibri is starting." +This makes the **personalized seed** the onboarding primitive: -Estimated: ~30 lines of shell. +- The image stays generic and publishable; secrets are never baked in. +- The seed (FAT32 `CLAWDIESEED`) is the personalization layer and stays + physical/offline — `env` (direct keys + optional `TAILSCALE_AUTH_KEY`), + `harness.toml`, `soul/`, `ssh/authorized_keys`, optional `/shred` to wipe + keys off the stick after first import. +- The seed can be generated by an agent (e.g. Hermes) that already holds the + soul and key material, written straight onto the mounted partition. + +This supersedes the earlier xdg-autostart "delete the click" plan: it removes +the click for free without a first-login sentinel or a network dependency at +first boot. ## Related: one-secret path (future) diff --git a/live/operator-session/START-HERE.txt b/live/operator-session/START-HERE.txt index da9fe93..eda097b 100644 --- a/live/operator-session/START-HERE.txt +++ b/live/operator-session/START-HERE.txt @@ -55,6 +55,11 @@ LIVE SEED Seed partition label: CLAWDIESEED +If this stick was seeded with provider keys, there is nothing to do: the +agent's keys were loaded before the daemon started, so Colibri auto-spawns +the agent on boot. Check with: + colibri status + Readable operator guide: /usr/local/share/clawdie-iso/seed/README.txt diff --git a/live/operator-session/clawdie-live-seed b/live/operator-session/clawdie-live-seed index 3f6de56..756215f 100644 --- a/live/operator-session/clawdie-live-seed +++ b/live/operator-session/clawdie-live-seed @@ -54,6 +54,12 @@ SEED_VALID_HARNESSES="pi zot local" # Vaultwarden bootstrap creds are routed out of .env into this file (relative to # the agent home) so clawdie-vault-fetch can consume them. SEED_VAULT_BOOTSTRAP_REL=".config/vault-bootstrap.env" +# colibri_daemon reads provider keys from this file (rc.conf +# colibri_daemon_provider_env), NOT the operator's ~/.env. The active agent's +# direct provider keys are merged here too so the daemon auto-spawns at boot +# from a seeded stick with no operator action (zero-touch provisioning). The +# importer runs as root before LOGIN, so it can write this root-owned file. +SEED_PROVIDER_ENV="${SEED_PROVIDER_ENV:-/usr/local/etc/colibri/provider.env}" _seed_log() { printf '%s %s\n' "$(date '+%Y-%m-%dT%H:%M:%S')" "$1" >>"${SEED_LOG}" 2>/dev/null || true @@ -261,6 +267,14 @@ _seed_activate_agent() { if [ -f "${_dir}/env" ]; then _seed_split_env "${_dir}/env" "${_stage}" _seed_merge_env "${_stage}/.app.env" "${_home}/.env" "${_user}" + # Feed the daemon too: colibri_daemon reads provider.env, not ~/.env. + # Routing the active agent's provider keys here lets a seeded stick boot + # straight into an auto-spawned agent — no Join Hive click, no vault + # round-trip. Lands root-owned 0600 (the importer is root, pre-LOGIN). + if [ -s "${_stage}/.app.env" ]; then + _seed_merge_env "${_stage}/.app.env" "${SEED_PROVIDER_ENV}" root + _seed_log "merged active-agent provider keys -> ${SEED_PROVIDER_ENV}" + fi if [ -s "${_stage}/.boot.env" ]; then _seed_merge_env "${_stage}/.boot.env" "${_home}/${SEED_VAULT_BOOTSTRAP_REL}" "${_user}" _seed_log "routed Vaultwarden bootstrap creds -> ${_home}/${SEED_VAULT_BOOTSTRAP_REL}" diff --git a/live/operator-session/clawdie-live-seed.README.txt b/live/operator-session/clawdie-live-seed.README.txt index 1742838..9345c84 100644 --- a/live/operator-session/clawdie-live-seed.README.txt +++ b/live/operator-session/clawdie-live-seed.README.txt @@ -40,14 +40,26 @@ LAYER 2 — PER-AGENT DIRECTORIES Create one directory per agent. THE DIRECTORY NAME IS THE AGENT NAME. Inside it, any of these are honored: - //env Plaintext KEY=VALUE lines. Merged into the - agent's .env (mode 0600). Keys you list + //env Plaintext KEY=VALUE lines. Keys you list replace existing values; keys you omit are preserved. Blank/`#` lines are ignored. - Typical contents: provider API keys - (ANTHROPIC_API_KEY=..., ZAI_API_KEY=...), - or the Vaultwarden bootstrap - (BW_CLIENTID/BW_CLIENTSECRET/BW_PASSWORD). + Routing for the ACTIVE agent: + - Provider API keys and toggles + (DEEPSEEK_API_KEY=..., OPENROUTER_API_KEY=..., + COLIBRI_AUTOSPAWN_PI=YES, ...) are merged + into BOTH the agent's ~/.env AND the daemon's + /usr/local/etc/colibri/provider.env (mode + 0600). Because the importer runs before the + daemon starts, a seeded provider key makes + colibri_daemon auto-spawn the agent on first + boot with NO operator action — fully + zero-touch. No Vaultwarden round-trip needed. + - Vaultwarden bootstrap creds + (BW_CLIENTID/BW_CLIENTSECRET/BW_PASSWORD) are + routed to ~/.config/vault-bootstrap.env for + clawdie-vault-fetch — use these only if you + want the vault-fetch path instead of direct + keys. The Vaultwarden endpoint is baked into the image; do not put it on the seed unless you are deliberately overriding it.