Architecture & the daemon
One self-contained Go binary that wears several faces, all sharing the same on-disk state:
| Capability | Description |
|---|---|
| Single-binary distribution | warden bundles the daemon, CLI clients, MCP server, TUI, and (in release builds) the embedded web GUI. wd is an installed symlink. |
| Local daemon | The single writer to warden-db. Serves a loopback REST API (127.0.0.1:8765) and runs a background poller that keeps each agent’s status and subject fresh. |
Single embedded warden-db | Every durable store (agents/sessions, pipelines, plans, projects, schedules, backends, snapshot metadata, …) lives in one embedded ScrivaDB (github.com/srjn45/scriva, SyncModeNone) rooted at <data_dir>/warden-db/ (default ~/.warden/warden-db/) — schema 2, the v11 layout. A mutation appends one record instead of rewriting a whole JSON file; still no database server to run. Existing installs are cut over once by warden update — see Upgrading & storage migration, the Schema 2 upgrade guide and Agent store integrity. |
| Claude Code lifecycle hooks | A hook script posts SessionStart/Notification/Stop/SubagentStop/SessionEnd to the daemon so status updates in real time without polling. Fails soft (never blocks the agent). |
| launchd auto-start (macOS) | Installs as an auto-starting, crash-restarting background service. |
| Stable code identity | One-time self-signed code-signing cert keeps the macOS TCC (Full Disk Access) grant stable across rebuilds. |
| Security hardening | 0700 data dir, slowloris/body/write timeouts (bypassed for SSE/WS/long-poll), refuses non-loopback bind unless WARDEN_ALLOW_NONLOOPBACK=1. |
warden doctor | Preflight checks: required binaries (tmux, git, claude, gh), daemon reachability, data directory. |
Stored entity hierarchy
Section titled “Stored entity hierarchy”Warden has four separate entities: Project, Agent, Terminal, and Pipeline.
A project’s agents[], pipelines[], and terminals[] are complete,
authoritative membership id lists, including nested agents and pipeline job
agents. Clients render these stored lists instead of inferring membership from
paths or scanning project_id back-references.
Agents store parent_id, child_agents[], and child_pipelines[]. A pipeline
stores parent_agent_id (empty for an operator-created pipeline) as the reverse
of its owner’s child_pipelines[]. Pipeline job agents never appear in the
owner’s child_agents[]: reach them through the pipeline’s jobs and their
pipeline_id. Pipelines retain their own DAG; terminals are project leaf members
with no agent children, AI transcript, or cost.
Opening a new project leaves it empty; spawn agents and terminals explicitly. Reopening restores previously hibernated members but never auto-spawns an orchestrator. Record creation alone is distinct from launching a live session; spawn wires membership and parent/child edges. Stored lists are ordered and de-duplicated, and may retain ids whose records are unavailable or hibernated.
See Agents & lifecycle for the seven presented states and recovery rules.
Multi-project peer orchestrators
Section titled “Multi-project peer orchestrators”When projects are organized into a project group, you run one orch-<project> orchestrator per project (spawned explicitly — the daemon does not create one on open). These orchestrators are peers — there is no global orchestrator above them. Each one plans and delegates to local workers, planners, and pipelines; it reaches the other projects by messaging their orchestrator directly.
frontend needs a change in backend, orch-frontend messages orch-backend — which coordinates its own local agents and replies. You spawn the orch-<project> agent into each project, and warden injects peer awareness (group name + sibling names) into every orchestrator at each relaunch.Upgrading & storage migration
Section titled “Upgrading & storage migration”Through v10 (schema 1) warden kept a separate store per concern — sessions-db/
(with active and closed collections, imported from the older sessions/ and
closed/ JSON), agents-db/, pipelines-db/, plans/plans-db/, projects/,
backends/ and others. The v11 major (schema 2) moves all of them into one
embedded ScrivaDB at <data_dir>/warden-db/. Agents are one collection there; the
active/closed split is no longer a pair of stores. This is an internal storage
change — the daemon’s REST API and the CLI/MCP clients are unchanged.
- Fresh install: stamped at schema 2 on first boot; only
warden-db/is created. - Existing install:
warden updateruns a one-time, offline, journaled cutover for you: it stops the daemon, takes an immutable checksummed backup underbackups/pre-schema2-<timestamp>/, exports to a staging store, proves it equal to the legacy data (record counts, canonical hashes, relationships), atomically promotes it, and only then moves the schema ledger (<data_dir>/schema.json) to 2. On any failure the previous binary and data are restored. Preview withwarden update --plan; the manual path iswarden migrate --plan/warden migrate --apply. - Nothing is deleted. The schema-1 directories are kept as inert copies and are
never read at runtime; the daemon runs on
warden-dbonly (no dual-write, no fallback). Compare them withwarden-dbusingwarden inspect legacy. - Integrity and repair: verify the store offline with
warden repair warden-db --dry-run. Ownership, health checks and the repair procedure are in Agent store integrity.