Skip to main content

System architecture

Covenant is a single long-running daemon (covenantd) plus a thin set of clients (the CLI, the TUI, the web UI, third-party tooling over HTTP) and a number of agent processes. The daemon is the only component that holds state; everything else is replaceable.

Component map

┌──────────────────────────────────────────────────────────────┐
│                          covenantd                           │
│ ┌──────────┐  ┌──────────┐  ┌────────────┐  ┌────────────┐  │
│ │  IPC     │  │   HTTP   │  │   MCP      │  │   A2A      │  │
│ │  socket  │  │  gateway │  │ adapter    │  │ adapter    │  │
│ └────┬─────┘  └────┬─────┘  └─────┬──────┘  └─────┬──────┘  │
│      │             │              │               │          │
│      ▼             ▼              ▼               ▼          │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │                    Server::respond                       │ │
│ │ (intent dispatch, capability checks, audit, ignore set)  │ │
│ └────────┬─────────┬─────────┬─────────┬─────────┬─────────┘ │
│          │         │         │         │         │            │
│          ▼         ▼         ▼         ▼         ▼            │
│      ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────────┐        │
│      │Router│ │Runtime│ │Memory│ │ Audit│ │Settlement│        │
│      └──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘ └──┬───────┘        │
│         │        │        │        │        │                │
└─────────┼────────┼────────┼────────┼────────┼────────────────┘
          │        │        │        │        │
          ▼        ▼        ▼        ▼        ▼
       cards    spawned  SQLite  JSONL    JSONL     local
       on disk  processes  +    audit/   receipts  settlement
                          embeds events           scaffold

Process model

covenantdruns as a single process per machine, owned by the operator's user account. It owns:

  • a Unix socket at $COVENANT_HOME/sock for local clients,
  • an HTTP listener on 127.0.0.1:8421 for browser- facing UIs and third-party tooling (loopback only),
  • the SQLite memory database at $COVENANT_HOME/memory.db,
  • append-only JSONL stores under $COVENANT_HOME for audit, capabilities, peers, receipts, budget, and a2a,
  • the local ed25519 identity key.

Subprocess-style agents (rust-bin, python3, node) run as child processes spawned on demand when an intent is dispatched. The runtime registers each subprocess in an in-memory tracker, walks the tracker on a periodic projection tick, and preempts via SIGTERM with a grace window before SIGKILL whenever project_overshoot flags an in-flight process as on track to exceed its remaining credit budget. The wall-clock kill at the agent-declared cpu_ms_per_task remains as the final backstop. hermes-runtime agents are not subprocesses; the daemon delegates the intent to a configured Hermes HTTP endpoint and treats the response as the agent result. In either model, agents have no direct access to the daemon's state; every interaction goes through the daemon.

Request lifecycle

  1. A client (CLI, TUI, web UI, third-party caller) sends a SubmitIntent request over the Unix socket or HTTP.
  2. The daemon checks the intent text against the configured ignore set; matches are short-circuited with anIntentIgnored audit event and skipped.
  3. The router scores the intent against registered agent capability cards via keyword overlap and selects the best match (or falls back to an echo response).
  4. The daemon runs a capability check for the matched agent's required actions. The check writes a CapabilityCheck audit event regardless of outcome. A failed check rejects the dispatch with Response::Error.
  5. On success, the runtime spawns the agent, sends the intent on stdin, reads the result on stdout, and enforces the budget via both the wall-clock kill at cpu_ms_per_task and the periodic projection tick that preempts via SIGTERM/grace/SIGKILL on projected overshoot.
  6. The daemon writes a working-tier MemoryRecord (with an embedding vector if an embedder is configured), a SettlementReceipt for the resources consumed, and an IntentDispatched audit event.
  7. The client receives an IntentResult with the intent UUID, the result text, sources, and (when applicable) the receipt.

State on disk

Everything Covenant remembers about its operations sits under $COVENANT_HOME. Default location is ~/.covenant; override with the COVENANT_HOME environment variable.

PathFormatOwner
identity/local.keyraw 32 bytes (ed25519 seed)covenant-identity
memory.dbSQLitecovenant-memory
audit/events.jsonlJSONL, append-onlycovenant-audit
audit/events.chain.jsonlJSONL, append-only hash-chain sidecarcovenant-audit
capabilities/granted.jsonlJSONL, append-onlycovenant-permissions
capabilities/revoked.jsonlJSONL, append-only (tombstones)covenant-permissions
peers/registry.jsonlJSONL, append-onlycovenant-peer-auth
peers/operator.tokenopaque token bytes, mode 0600covenant-peer-auth
receipts/working.jsonlJSONL, append-onlycovenant-settlement
budget/ledger.jsonlJSONL, append-onlycovenant-budget
budget/checkpoints.jsonlJSONL, append-onlycovenant-budget
a2a/events.jsonlJSONL, append-only (leased-queue mailbox)covenant-a2a
agents/<name>/agent.tomlTOML, one manifest per package directorycovenant-router
secrets.tomlTOMLcovenant-llm, covenant-tools, covenant-mcp
.covenantignoregitignore-style patternscovenant-memory
runtime/gvisorscratch directorycovenant-runtime
sockUnix domain socketcovenant-ipc

Crate layout

The daemon is composed from a number of small Rust crates, each owning one primitive. Each crate exposes a trait + at least two implementations (one for production, one in-memory for tests), which keeps the daemon's wiring straightforward and the test suite fast.

CrateRole
covenant-typesWire-level types shared by every other crate ( Intent, AgentId, Priority, MemoryRecord, MemoryTier, Capability, SettlementReceipt).
covenant-manifestParser and validator for agent.toml manifests. Reads the agent, capabilities, resources, sandbox, settlement, and hermes sections; parses Runtime (python3, node, rust-bin, hermes), NetworkPolicy (off, outbound-https-only, full), SandboxBackend (trusted-local, linux-gvisor), FilesystemPolicy (read-only-package, ephemeral, host), and HermesApprovalPolicy (operator-prompt, auto-deny, auto-once); pins RESERVED_NAMESPACES (intent., memory., identity., tool., agent.) for capability ids; and surfaces ManifestError Parse, Io, and Validation.
covenant-routerRouter over a Vec of AgentCard with route doing case-insensitive keyword-overlap matching and insertion-order tie-breaking, find_by_id/register/from_cards helpers, and the RouteMatch result type (agent_id plus score); load_agents_from_dir walks $COVENANT_HOME/agents/ for agent.toml manifests and returns cards sorted by manifest id for deterministic routing across hosts; RouterError::Io and RouterError::Manifest preserve the inner std::io::Error and covenant_manifest::ManifestError via #[source] for downstream retry-policy downcasts.
covenant-runtimeRunner trait with SubprocessRunner, GvisorRunner, and HermesRunner implementations, a stdin/stdout JSON protocol, and per-task budget enforcement via projection-tick preempt and a wall-clock backstop.
covenant-memoryThree-tier memory store (working, episodic, long-term): MemoryStore trait with SQLite-backed persistence and an in-memory backend for tests, cosine similarity search over embedded vectors, tier-scoped purge, bounded compaction, and scoped repair commands.
covenant-identityed25519 identity: keypair generation, on-disk persistence, signing, and verification helpers. The same key signs on-chain settlement transactions, so there is no second keypair system.
covenant-peer-authPeer-token registry binding ipc/http callers to AgentIds: per-agent random 32-byte tokens with 6-char b58 prefix-only operator visibility (full tokens never leave the daemon), jsonl-backed event log, revocation tombstones with prefix-based discovery, and live/revoked/all status-filter queries, plus an in-memory backend for tests.
covenant-permissionsCapability-token primitive: ed25519-signed SignedCapabilitys over a deterministic canonical message, persistent JSONL and in-memory CapabilityStore backends, revocation tombstones, and verify-with-clock for expiry. Plus grant-time scope validation and dispatch-time scope predicates for tool-call argument allowlists, before-ms cutoffs, and per-namespace memory, A2A, peer, chain, and audit-purge enforcement.
covenant-auditAppend-only audit log: AuditLog trait with JSONL and in-memory backends, per-event hash-chain integrity verification surfaced via verify_integrity, and recorded event kinds spanning intent dispatch, capability checks/grants/rejections, budget enforcement, agent-to-agent messaging, tool approval and invocation, memory maintenance, peer and operator administration, and authentication failures.
covenant-settlementSettlement primitive implementing the credits-and-buyback model: Settlementtrait with in-memory and JSONL receipt-store backends; receipts accumulate in a local JSONL log until batched and flushed to the on-chain settlement program, at which point each receipt's onchain_sig is populated.
covenant-budgetPer-agent token-bucket budget ledger: BudgetLedger trait with in-memory and JSONL-backed event-log backends, a separate pause/resume checkpoint store, and bounded compaction that emits per-agent Snapshot events at the cutoff alongside debit records and exhaustion signals.
covenant-llmProvider trait with MockProvider, OllamaProvider, AnthropicProvider, and an OpenAI-compatible implementation, a separate Embedder trait with MockEmbedder and OllamaEmbedder, a ProviderConfig reader for ~/.covenant/secrets.toml and an EmbedderConfig reader over the same file, and a pick_provider helper that returns the highest-priority configured backend, falling back to Ollama if reachable and to MockProvider otherwise.
covenant-toolsSearchProvider trait with MockSearch, BraveSearch, and SerpApiSearch implementations, a SearchConfig reader for the [search] section of secrets.toml, and a pick_search helper that falls back to MockSearch when nothing is configured.
covenant-mcpModel Context Protocol integration: tool trait following the public MCP wire shapes (name, description, inputSchema, Content blocks, isError) so the same trait backs native Rust implementations and external MCP servers, in-process registry, native tools, stdio JSON-RPC 2.0 transport for external servers.
covenant-a2aAgent-to-agent task and result envelopes; async Mailbox trait with an in-memory backend and a durable JSONL-backed implementation over a leased task queue, plus a receiver-side idempotency cache, operator-facing repair commands, and an opt-in auto-retry policy.
covenant-ipcLength-prefixed JSON IPC for the local socket: 4-byte big-endian length prefix, frames bounded at 8 MB via MAX_FRAME, and a versioned protocol shape (v1 baseline, v2 reserved for streaming responses).
covenantdThe daemon binary. Wires the primitives together and exposes intent dispatch, agent runtime, memory, identity, permissions, audit, and settlement over a Unix socket and an HTTP gateway.
covenantThe CLI binary. Submits intents and drives memory, capabilities, receipts, chain, audit, tools, A2A, and peer-registry surfaces over the local IPC socket.
covenant-tuiTerminal UI binary with intent, memory, audit, capabilities, A2A, chain-receipts, and peer-registry views over the daemon IPC.

Settlement scaffold

Covenant records local settlement receipts today. The repository also contains an experimental Anchor program for the future Solana settlement path described in Settlement. Credit minting, burn reconciliation, oracle integration, and provider payout flows are tracked as protocol hardening work.

The design boundary is deliberate: local receipts make resource accounting inspectable while the on-chain authority surface remains a hardening target.

Position in the stack

Covenant operates between the host operating system and user-facing agentic applications. It does not host language models and does not prescribe agent reasoning strategies. Custom agents, framework-built agents, and end-to-end fine-tuned agents integrate against the same primitive set, so that identity, permissions, memory, communication, and settlement are provided as shared host-level services rather than reimplemented per application.