Every file under docs/internal/ ends up in the bootstrap/skills-memory artifact (per metadata.json: "Full project docs, internal docs, identity files, and skill definitions"). Stale handoffs, dated build reports, single-commit reviews, and superseded design notes were polluting the embedding index with low-signal chunks. Removed: - TLS-CERT-LIFECYCLE-HANDOFF.md, GLASSPANE-FREEBSD-HANDOFF.md, CMS-ASTRO-SOURCE-OF-TRUTH-HANDOFF.md (handoffs whose work has landed) - HOST-DB-READINESS-REVIEW.md, HOST-DB-REBOOT-REVIEW.md, HOST-DB-RECOVERY-PLAN.md, SYSTEM-NAMESPACE-BRANCH-REVIEW.md (commit/branch reviews self-marked as historical) - BUILD-TEST-REPORT-06.APR.2026.md, test-results.md (dated snapshots) - DEBUG_CHECKLIST.md (Feb 2026 known-issues list, top item already fixed) - BOOTABLE-ISO-PLAN-V1.md (V1 plan; ISO-FIRST-BOOT-IMPLEMENTATION.md is now the source of truth) - STRAPI-FREEBSD-SETUP.md, PI-SKILLS-INTEGRATION.md, CODEX-FREEBSD.md (workarounds and one-off design notes for resolved/superseded paths) - REFACTOR-PLAN.md, nanoclaw-architecture-final.md, AGENT-HARNESS-V2.md, AGENT-SKILLS-VS-REALITY.md (older planning/architecture docs whose decisions are now in code or ARCHITECTURE.md) - BUILTIN-KNOWLEDGE-SPEC.md, LOCAL-KNOWLEDGE-BOOTSTRAP.md (early specs superseded by SKILLS-ARTIFACT-V1-PLAN.md) - HEARTBEAT.md (design doc; implementation lives in scripts/heartbeat.sh and src/controlplane-heartbeat.ts) - POSTGRES-PERMISSIONS.md (one-off fix recipe) - RUNTIME-MANIFEST-DESIGN.md (status: Implemented; design is in code now) Updates to remaining files patch broken cross-links: - ARCHITECTURE.md drops the two table rows pointing at deleted docs - doc/THREE-BIRD-ARCHITECTURE.md drops Strapi-setup link references - docs/internal/SKILLS-ARTIFACT-V1-PLAN.md drops the "Depends on" line - docs/internal/SUDO_REPLACEMENT.md trims its list of internal docs that reference sudo - .agent/skills/setup and .agent/skills/docs-deployment drop pointers to REFACTOR-PLAN and DEBUG_CHECKLIST Net: 23 files deleted, 7566 lines removed. docs/internal/ goes from 41 to 18 markdown files. The artifact's next refresh will see proportionally less noise in retrieval. --- Build: FAIL | Tests: FAIL — 16 failed
8.5 KiB
Architecture Overview
Last Updated: 16.apr.2026
Clawdie is a self-hosted AI assistant platform running on FreeBSD. It uses Bastille jails for service isolation, PostgreSQL for all data, and a multi-agent control plane for task orchestration.
High-Level Layout
FreeBSD Host (ZFS)
├── Agent Service (runs as AGENT_NAME user, port 3100)
│ ├── Telegram bot (message intake)
│ ├── HTTP REST API (control plane + health/metrics)
│ ├── Unified scheduler (task routing, heartbeats, budgets)
│ ├── Control plane runner (spawns pi/aider per task)
│ └── Watchdog (health checks, concurrency control)
│
├── hostd daemon (root, Unix socket)
│ └── Privileged ops: bastille, zfs, pf
│
├── PostgreSQL 18 (on host by default; db jail is opt-in via DB_RUNTIME=jail)
│ ├── {agent}_ops — tasks, agents, activity, budgets, approvals
│ ├── {agent}_skills — built-in knowledge (read-only artifact)
│ └── {agent}_memory — user/agent dynamic memory, pgvector embeddings
│
└── Bastille Jails
├── db (.3) — Data Service: PostgreSQL (only when DB_RUNTIME=jail; host is default)
├── cms (.4) — Web Service: nginx + Astro static site
├── git (.6) — Code Service: bare repos + Forgejo (optional)
├── llama-cpp (.5) — Local LLM inference (optional)
├── worker (.101) — General worker jail (legacy)
├── db-worker (.211) — DB Admin agent jail (Phase 7)
├── git-worker (.212) — Git Admin agent jail (Phase 7)
└── ctrl-worker (.213) — Coordinator agent jail (Phase 7)
Agent System
One agent runs per installation. The agent has a name (AGENT_NAME, default: clawdie) and runs as a FreeBSD service under that user.
Roles
| Role | Budget | Heartbeat | Purpose |
|---|---|---|---|
| Orchestrator | 80% | On-demand | Primary decision-maker, responds to Telegram |
| Sysadmin | 10% | Daily | System health checks, ZFS, PF, jails |
| DB Admin | 5% | On-demand | PostgreSQL maintenance, migrations |
| Git Admin | 5% | On-demand | Repository management, backups |
Each role has an identity file in .agent/identities/ that gets injected when the agent spawns for that role.
Task Flow
Telegram message / API request
→ Control plane queues task
→ Scheduler assigns to specialist role
→ Runner spawns pi/aider with role identity + budget + `--no-skills`
→ Agent gets: identity file + skill index + (on FreeBSD) pi extension tools
→ Output captured, activity logged
→ Response routed back to channel
Prompt Assembly
| Context | Source | Frequency | Path |
|---|---|---|---|
| Identity | .agent/identities/{ROLE}.md + SOUL/USER/IDENTITY files |
Per-run | Both (controlplane + telegram) |
| Runtime manifest | src/runtime-manifest.ts (repo/skills/capabilities) |
Fresh per-message | Injected into main prompt |
| Skill index | agent/library.yaml → one-line summaries |
Per-run | Controlplane (pi) |
| Profile rules | src/pi-profile.ts |
Per-run | Telegram only |
| System state | src/system-state.ts (live hostd/ZFS/PF) |
Per-run | Telegram only |
| Pi extension tools | .pi/extensions/clawdie-harness/ |
Per-run | Telegram only (needs loading for controlplane) |
Runtime manifest (<runtime-manifest> block):
- Generated fresh from local sources:
.gitconfig,agent/library.yaml, built-in artifact metadata - Answers: "What repo am I running from? What branch? What skills exist? What specialists can I coordinate?"
- Injected as compact XML-like block (~50 tokens), solves the coherence gap where agent infrastructure facts were invisible to the model
- See
src/runtime-manifest.tsfor implementation
Skills are injected as a compact index (~200 tokens) instead of full content (~15,000+ tokens). Full SKILL.md available on-demand through the skills_search extension tool.
Jail Isolation (Phase 7)
When CONTROLPLANE_JAIL_ISOLATION=YES, specialist agents run inside dedicated thin jails. Each jail gets scoped secrets (DB creds for db-worker, SSH keys for git-worker) and restricted network access via PF. Feature flag defaults to NO.
Jail agents reach hostd through the controlplane API (POST /api/controlplane/hostd), not via direct Unix socket. The API authenticates the request and proxies to the hostd daemon. This means no socket mount is needed inside jails — only network access to CONTROLPLANE_HOST_IP:CONTROLPLANE_API_PORT.
Split-Brain Database
All three databases run on the same PostgreSQL 18 instance, each with its own user and permissions:
| Database | Contents | Write Pattern |
|---|---|---|
{agent}_ops |
Tasks, agents, activity log, budgets, approvals, auth | Frequent writes |
{agent}_skills |
Preloaded knowledge chunks with pgvector embeddings | Read-only after import |
{agent}_memory |
User facts, agent memories, semantic search via pgvector | Moderate writes |
Multiple agents on the same host share the PostgreSQL instance but get their own set of 3 databases (e.g., clawdie_ops + atlas_ops).
Configuration
All runtime config comes from .env in the project root. Key variables:
| Variable | Purpose | Default |
|---|---|---|
AGENT_NAME |
Agent identity | clawdie |
DB_RUNTIME |
PostgreSQL location | host |
CONTROLPLANE_JAIL_ISOLATION |
Enable per-specialist jails | NO |
WARDEN_SUBNET_BASE |
Jail IP subnet | 10.0.0 |
CONTROLPLANE_PORT |
API port | 3100 |
CONTROLPLANE_SHARED_SECRET |
API auth for agent subprocesses | `` |
CONTROLPLANE_BIND_HOST |
API listen address | 0.0.0.0 |
AGENT_MAX_INBOUND_CHARS |
Inbound message cap | 12000 |
AGENT_SESSION_MAX_BYTES |
Session rollover threshold | 2000000 |
PI_TUI_PROVIDER |
LLM provider | (required) |
Secrets (DB passwords, API keys) are generated by setup/secrets.ts and stored in .env.
Infrastructure as Code
infra/jails.yaml— Single source of truth for all jail definitions (IPs, packages, services, mounts)setup/bastille-helpers.ts— Shared provisioner (create, start, install packages, configure services)setup/install.ts— 20-step install orchestrator with ZFS checkpointsjustfile— CLI front door with 60+ recipes for common operations
Channels
Messages arrive via Telegram (grammy bot) or HTTP API. The router dispatches to the control plane, which queues tasks and assigns them to specialist agents.
Documentation Map
| Topic | File |
|---|---|
| Agent development conventions | AGENTS.md |
| Contributing guide | CONTRIBUTING.md |
| Control plane architecture | doc/CONTROLPLANE-ARCHITECTURE.md |
| Agent roles and skills | doc/CONTROLPLANE-AGENT-ROLES.md |
| API message contracts | doc/CONTROLPLANE-MESSAGE-CONTRACT.md |
| Multi-LLM provider routing | doc/MULTI-PROVIDER-ARCHITECTURE.md |
| Docs localization pipeline | doc/THREE-BIRD-ARCHITECTURE.md |
| Install guide | docs/public/install/install.md |
| Deployment models | docs/public/architecture/deployment-models.md |
| Disaster recovery | docs/public/operate/db-disaster-recovery.md |