colibri/docs/guide/install/install.md
Sam & Claude 95c487546d
Some checks are pending
CI / rust (pull_request) Waiting to run
CI / markdown (pull_request) Waiting to run
CI / port (pull_request) Waiting to run
CI / agent-jail-pkgs (pull_request) Waiting to run
docs(guide): port 39 procedural docs from clawdie-ai to colibri
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.
2026-06-26 09:16:43 +02:00

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.