All docs now use 10.0.0.x as the canonical example subnet, matching the code default in config.ts and shell-env.sh. Previously docs used a mix of 192.168.100.x (architecture docs) and 10.0.1.x (install docs). Also: - Fix dead link to setup-wizard.ts in git-storage.md (now points to setup/git.ts and setup/install.ts) - Update stale nomic-embed-text reference in SKILLS-ARTIFACT-V1-PLAN.md to current BAAI/bge-m3 at 1024 dims - Fix uppercase display text in internal doc cross-references Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --- Build: pass | Tests: pass — Tests 603 passed (603)
3.3 KiB
| title |
|---|
| Host Operator Model |
Current main uses the FreeBSD host as the operator surface.
There is no dedicated operator jail.
Core Rule
- SSH into the FreeBSD host
- run Ansible against the FreeBSD host
- manage Bastille jails from the host
- treat
{agent}-db,{agent}-git, and{agent}-cmsas host-managed service jails
This keeps the trust boundary simple and avoids a second operator layer inside the jailed runtime.
Responsibilities
The host owns:
- Bastille lifecycle
warden0bridge and PF/NAT- ZFS datasets and snapshots
- rc.d service installation
.env/etc/hostsmanaged internal block- deployment and verification steps
The service jails own:
- PostgreSQL in
{agent}-db - local bare repositories in
{agent}-git - nginx + Astro in
{agent}-cms(Strapi is optional, Ansible-managed when used)
Workers own only sandboxed execution.
Subnet Layout
All addresses relative to AGENT_SUBNET_BASE (default 10.0.0):
| Slot | Role | Type | Notes |
|---|---|---|---|
.1 |
gateway | host bridge | warden0 — all jails route through here |
.2 |
reserved | — | compatibility slot (legacy controlplane naming) |
.3 |
Data Service | jail | PostgreSQL 17 + pgvector |
.4 |
Web Service | jail | nginx, Astro, Strapi |
.5 |
Local Inference | jail | llama-cpp (llama-server, bge-m3 embeddings) |
.6 |
Code Service | jail | local git (optional) |
.149 |
browser | reserved | future browser automation slot |
.150 |
gui | reserved | future GUI slot |
.101+ |
Workers | jail | dynamic execution range |
Control vs Observe
The host controls — hostd, controlplane, watchdog all run on the host with root access. They issue commands to jails via bastille, ZFS, PF, and rc.d.
Service jails ({agent}-db, {agent}-git, {agent}-cms) provide persistent services. Worker jails provide isolated execution sandboxes.
Access Pattern
Default automation path:
operator -> ssh -> FreeBSD host -> bastille cmd -> db|git|cms|worker
That means:
- no default
sshdinside service jails - no default jail-to-host automation key chain
- fewer secrets and fewer trust boundaries to maintain
Privileged Host Daemon
At runtime, the agent user never calls sudo. All privileged host operations
go through hostd — a root daemon on /var/run/<agent>-hostd.sock:
agent user process
-> src/hostd/client.ts -> hostd(op, params)
-> /var/run/<agent>-hostd.sock (Unix socket, mode 0660, group clawdie)
-> src/hostd/daemon.ts (root)
-> whitelisted op handler (bastille, zfs, pf, service, etc.)
Two rc.conf entries:
{agent}_hostd_enable=YES— root daemon, always on{agent}_enable=YES(orAUTO) — user agent
The --step hostd setup step installs the rc.d script and starts the daemon.
src/controlplane.ts checks hostd reachability at startup and every 5 minutes,
and attempts to repair service jails and PF via hostd when needed.
Identities
Keep operator identities explicit on the host:
- interactive operator account, typically
clawdie - system services installed through host-managed setup steps
Avoid building operational assumptions around an internal operator jail.