New docs/guide/ tree — canonical home for operator-facing procedural docs. Starlight frontmatter added to all files. 0.12 alignment fixes applied: - v0.11.0 → v0.12.0 throughout - PI_TUI_PROVIDER/MODEL → DEEPSEEK_API_KEY - Headless Codex login → Agent runtime setup (zot + RPC mode) - /login and auth.json references removed - pi → zot in provider-fallback spawn reference - colibri-provider-verify (was pi-provider-smoke) - Language cleanup: smoke test → verification, fake → test, can't self-fix → requires operator intervention, broken → unresponsive, Fix anything broken → Verify all checks pass Two-tree model: docs/wiki/ (decisions) + docs/guide/ (procedural). Single source of truth in colibri. clawdie-ai docs/public/ to be retired.
13 KiB
| title | description |
|---|---|
| Install Orchestrator | Single-command install flow for Clawdie. |
Command: just install
Quick start
Clawdie tracks the FreeBSD 15.x line. The installer rejects FreeBSD 14.x and any unvalidated future major version.
just install
ISO path
Current ISO validation is converging on: live QML installer → first installed
boot → loopback-bound controlplane /setup with a one-time bootstrap token.
Provider keys and Telegram are configured there after install. The older
setup.txt first-boot contract remains documented for legacy
non-interactive work and will be rewritten after live ISO validation.
After the initial boot, the same install flow described here runs in the
background.
Resume from a specific step after a failure:
just install-from-db
Skip service jails (db, git, cms) when running DB_RUNTIME=host or installing a second agent on an existing host:
just install-from hosts
Print the step plan without running anything:
just install -- --dry-run
Skip ZFS checkpoints (e.g. no ZFS pool):
just install -- --no-snapshots
Step flow
just install
│
▼
┌─────────────────────────────────────────────────────────┐
│ Detect ZFS dataset (zroot/bastille) │
│ Parse --from / --no-snapshots / --dry-run │
└─────────────────────────────────────────────────────────┘
│
▼
[ 1] onboarding first-boot setup seed or TUI fallback REQUIRED
│
[ 2] environment host pkg baseline, bridge, locale REQUIRED
│
[ 3] agent-config validate/write agent provider optional ─── warn on missing provider auth
│ └── pi missing → warn, continue
[ 4] pf write PF include (NAT egress) REQUIRED
│ └── 📸 snapshot: post-pf
[ 5] jails create worker jail (--create) REQUIRED
│ └── 📸 snapshot: post-jails
[ 6] git Git Service (git jail) DEFAULT ─── DB_RUNTIME=host → skip or use install-from hosts
│ └── 📸 snapshot: post-git
[ 7] forgejo Forgejo for Git Service DEFAULT ─── FEATURE_GITEA=NO → skip
│
[ 8] db Data Service (PostgreSQL) DEFAULT ─── DB_RUNTIME=host → skip; DB on host instead
│ └── 📸 snapshot: post-db
[ 9] skills-memory built-in knowledge import DEFAULT ─── artifact.sql ships in tarball
│
[10] skills-init Skills engine init (.nanoclaw) DEFAULT
│
[11] cms Web Service (cms jail: Astro+nginx) DEFAULT ─── use install-from hosts to skip
│ └── 📸 snapshot: post-cms
│
[12] ollama Local AI Models (Ollama jail .5) optional ─── FEATURE_OLLAMA≠YES → skip
│
[13] llama-cpp Local AI Models (llama-cpp jail .5) optional ─── FEATURE_LLAMA_CPP≠YES → skip
│
[14] hosts /etc/hosts + jail hostnames REQUIRED
│
[15] mounts validate jail mounts REQUIRED
│
[16] telegram-auth verify bot token optional ─── TELEGRAM_BOT_TOKEN unset → skip
│
[17] service build + install rc.d service REQUIRED
│
[18] hostd privileged host daemon (hostd) REQUIRED
│
[19] identity-restore Supabase restore optional ─── SUPABASE_URL unset → skip
│
[20] verify integrity check optional
│ └── 📸 snapshot: install-complete
│
▼
┌─────────────────────────────────────────────────────────┐
│ Summary: N ok N warnings N skipped N failed │
│ Snapshots taken: zroot/bastille@post-pf-… … │
│ LLM providers: anthropic ✓ openai ✗ ollama ✗ … │
└─────────────────────────────────────────────────────────┘
The onboarding step prefers the first-boot setup file (setup.txt; see
First boot). The interactive TUI wizard is the fallback when
the first-boot setup is absent or invalid; it sources locales from FreeBSD
itself, so any installed locale can be selected (en_US.UTF-8,
zh_CN.UTF-8, etc.) and is applied consistently.
setup.txt is the operator-intent contract, and system.env is the matching
hardware-intent contract. Inspect can populate both before the installer runs.
Set DB_RUNTIME=host in .env to provision PostgreSQL directly on the host instead of a db jail; DB_HOST defaults to ${AGENT_SUBNET_BASE}.1 so jails can reach it. Use DB_COMPRESSION=lz4 (default) or DB_COMPRESSION=zstd for ZFS compression on host datasets.
The root install owns shared platform services. It is not modeled as tenant zero.
ASSISTANT_NAME is display-only. Later additive tenants consume shared services such as:
- Git Service
- Web Service
- Local AI Models
ZFS snapshots
Snapshots are taken after each milestone step if a Bastille ZFS dataset is detected. Two paths:
| Context | Method |
|---|---|
| Running as root | zfs snapshot zroot/bastille@<tag> directly |
Non-root, sudo available |
sudo zfs snapshot zroot/bastille@<tag> |
| Non-root, hostd socket present | nc -U /var/run/<agent>-hostd.sock (hostd zfs-snapshot op) |
| Neither | skip silently |
Snapshot tags are suffixed with a Unix timestamp to prevent collisions on re-runs.
LLM providers
The orchestrator never exits on missing LLM provider auth. OpenAI/OpenRouter/Anthropic subscription auth is the recommended path for performance/price, but it is not a hard installer requirement and all supported providers are peer options. At the end of the run Clawdie prints a table of known providers:
△ LLM providers
anthropic ANTHROPIC_API_KEY ✓ configured
openai OPENAI_API_KEY ✗ not set
openrouter OPENROUTER_API_KEY ✗ not set
deepseek DEEPSEEK_API_KEY ✗ not set
zai ZAI_API_KEY ✗ not set
groq GROQ_API_KEY ✗ not set
azure AZURE_OPENAI_API_KEY ✗ not set
ollama OLLAMA_HOST ✗ not set
If no provider auth is found, it prints instructions:
No LLM provider auth found. Configure one after install and restart:
Set DEEPSEEK_API_KEY=... in provider.env for the default agent,
or add provider keys such as ANTHROPIC_API_KEY=sk-ant-...
service clawdie restart
The entire infrastructure (PF, jails, PostgreSQL, nginx, ZFS) has zero LLM dependency. Provider auth is only consumed when the jail-runner spawns a live response. Install and service start succeed without it.
After install, use the controlplane setup page to finish provider and optional Telegram configuration:
https://<agent-domain>/setup
Before setup is complete, do not expose this URL directly to the public internet. Use local console/loopback access, or a tailnet/LAN path protected by TLS and network allowlisting. The bootstrap token is a first-setup key, not a substitute for bind/PF/TLS policy.
If the printed bootstrap token is lost before setup completes, rotate a fresh one on the host:
npm run setup-token -- rotate
Agent runtime setup
The agent runtime uses DEEPSEEK_API_KEY from provider.env.
Colibri autospawns zot in RPC mode — no separate login or auth store
needed. zot reads its identity from $ZOT_HOME/AGENTS.md (installed
automatically from the seed partition).
Quick verification:
zot --no-session --print "Reply with exactly: zot-ok"
Expected output:
zot-ok
Control plane API auth
Agent subprocesses (pi, aider) authenticate back to the control plane API using a shared secret. Generate one after install:
echo "CONTROLPLANE_SHARED_SECRET=$(openssl rand -base64 32)" >> .env
sudo service ${AGENT_NAME} restart
Without it, the startup log warns and agent-to-API calls are rejected.
Service wrapper scripts
The rc.d service (/usr/local/etc/rc.d/${AGENT_NAME}) runs
run-${AGENT_NAME}.sh which is generated by just setup-service at
install time. It is not tracked in git (run-*.sh is in .gitignore).
If missing, re-run just setup-service to regenerate it.
Local LLM runtime is optional and configured via:
LOCAL_LLM_PROVIDER=none|ollama|llama_cpp
FEATURE_OLLAMA=YES|NO
FEATURE_LLAMA_CPP=YES|NO
FEATURE_OLLAMA_HPP=YES|NO # optional C++ bindings for Ollama clients
Required vs optional steps
Steps are required (failure stops install), default (runs out of the box but can be disabled), or optional (skipped unless explicitly enabled).
| Step | Status | Skip condition |
|---|---|---|
| onboarding | required | — |
| environment | required | — |
| agent-config | optional | warn on missing provider auth or missing agent binary |
| pf | required | — |
| jails | required | — |
| git | default | DB_RUNTIME=host or install-from hosts |
| forgejo | default | FEATURE_GITEA = NO |
| db | default | DB_RUNTIME=host skips jail, provisions on host instead |
| skills-memory | default | bootstrap/skills-memory/artifact.sql not present |
| skills-init | default | — |
| cms | default | install-from hosts skips; cms is a shared service, not per-agent |
| ollama | optional | FEATURE_OLLAMA ≠ YES |
| llama-cpp | optional | FEATURE_LLAMA_CPP ≠ YES |
| hosts | required | — |
| mounts | required | — |
| telegram-auth | optional | TELEGRAM_BOT_TOKEN not set |
| service | required | — |
| hostd | required | — |
| identity-restore | optional | SUPABASE_URL not set |
| verify | optional | warn on most check failures; fail on broken runtime integrity |
A required step failure stops the install immediately and prints the resume
command. Default steps ship enabled (FEATURE_GITEA=YES, artifact.sql bundled)
— they run unless the operator explicitly opts out.
Individual steps
The orchestrator calls each step through setup/index.ts as a subprocess
(spawnSync with tsx). This isolates process.exit(1) calls in individual
step modules from killing the orchestrator.
Individual steps can still be run directly:
just setup-db
just setup -- --step verify
verify checks more than the shared docs build. If tenant sites are
declared, it also checks their served output and publish-manifest consistency in
the CMS webroot. A site that is merely declared but not yet manually published
does not fail the step by itself; an inconsistent live publish state does.
The step registry is implemented in setup/index.ts.