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 scaffoldProcess model
covenantdruns as a single process per machine, owned by the operator's user account. It owns:
- a Unix socket at
$COVENANT_HOME/sockfor local clients, - an HTTP listener on
127.0.0.1:8421for browser- facing UIs and third-party tooling (loopback only), - the SQLite memory database at
$COVENANT_HOME/memory.db, - append-only JSONL stores under
$COVENANT_HOMEfor 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
- A client (CLI, TUI, web UI, third-party caller) sends a
SubmitIntentrequest over the Unix socket or HTTP. - The daemon checks the intent text against the configured ignore set; matches are short-circuited with an
IntentIgnoredaudit event and skipped. - 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).
- The daemon runs a capability check for the matched agent's required actions. The check writes a
CapabilityCheckaudit event regardless of outcome. A failed check rejects the dispatch withResponse::Error. - 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_taskand the periodic projection tick that preempts viaSIGTERM/grace/SIGKILLon projected overshoot. - The daemon writes a working-tier
MemoryRecord(with an embedding vector if an embedder is configured), aSettlementReceiptfor the resources consumed, and anIntentDispatchedaudit event. - The client receives an
IntentResultwith 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.
| Path | Format | Owner |
|---|---|---|
identity/local.key | raw 32 bytes (ed25519 seed) | covenant-identity |
memory.db | SQLite | covenant-memory |
audit/events.jsonl | JSONL, append-only | covenant-audit |
audit/events.chain.jsonl | JSONL, append-only hash-chain sidecar | covenant-audit |
capabilities/granted.jsonl | JSONL, append-only | covenant-permissions |
capabilities/revoked.jsonl | JSONL, append-only (tombstones) | covenant-permissions |
peers/registry.jsonl | JSONL, append-only | covenant-peer-auth |
peers/operator.token | opaque token bytes, mode 0600 | covenant-peer-auth |
receipts/working.jsonl | JSONL, append-only | covenant-settlement |
budget/ledger.jsonl | JSONL, append-only | covenant-budget |
budget/checkpoints.jsonl | JSONL, append-only | covenant-budget |
a2a/events.jsonl | JSONL, append-only (leased-queue mailbox) | covenant-a2a |
agents/<name>/agent.toml | TOML, one manifest per package directory | covenant-router |
secrets.toml | TOML | covenant-llm, covenant-tools, covenant-mcp |
.covenantignore | gitignore-style patterns | covenant-memory |
runtime/gvisor | scratch directory | covenant-runtime |
sock | Unix domain socket | covenant-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.
| Crate | Role |
|---|---|
covenant-types | Wire-level types shared by every other crate ( Intent, AgentId, Priority, MemoryRecord, MemoryTier, Capability, SettlementReceipt). |
covenant-manifest | Parser 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-router | Router 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-runtime | Runner 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-memory | Three-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-identity | ed25519 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-auth | Peer-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-permissions | Capability-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-audit | Append-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-settlement | Settlement 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-budget | Per-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-llm | Provider 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-tools | SearchProvider 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-mcp | Model 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-a2a | Agent-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-ipc | Length-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). |
covenantd | The 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. |
covenant | The CLI binary. Submits intents and drives memory, capabilities, receipts, chain, audit, tools, A2A, and peer-registry surfaces over the local IPC socket. |
covenant-tui | Terminal UI binary with intent, memory, audit, capabilities, A2A, chain-receipts, and peer-registry views over the daemon IPC. |
Settlement
Covenant records local settlement receipts today. The Solana settlement program is deployed and live on mainnet — credit mint and burn, staking, slashing, and on-chain receipt anchoring are implemented on-chain (seeSettlement). The daemon-driven per-intent settlement lifecycle and provider-payout flows are not yet production.
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.