Memory tiers
Covenant's memory is a single store partitioned into three tiers. Tiers are represented as a column on a shared schema rather than as separate databases; records can be promoted between tiers without migration.
Tiers
| Tier | Lifespan | Typical use |
|---|---|---|
working | per-task scratch; cleared explicitly | Intermediate results during an intent run. Scratch memory the agent uses to reason. Default tier for automatic memory writes. |
episodic | task-grained, durable | Records of completed tasks retained across daemon restarts; the basis for queries about prior task outcomes. |
longterm | intentionally retained context | Curated reference material, persistent personal context, anything that should influence future routing and answer composition. |
Record shape
MemoryRecord {
id: uuid,
tier: "working" | "episodic" | "longterm",
owner: AgentId,
text: "the result text",
embedding: [f32; N], // empty if no embedder configured
metadata: JSON, // free-form, e.g. { "intent_text": "…" }
created_at: u64, // unix milliseconds
parent: uuid | null
}Storage
The persistent backend is SQLite at $COVENANT_HOME/memory.db. The schema is one row per record; embeddings are stored as raw f32 bytes for cheap cosine math. An in-memory backend covers tests; both implement the same MemoryStore trait.
The daemon does not maintain a separate vector index; cosine search executes against the rows in the queried tier. The default store performs adequately for tens of thousands of records. Deployments expecting larger row counts should plan for a dedicated vector index.
Embedding
The daemon embeds memory writes if an embedder is configured. With no embedder configured, records are written without an embedding and will not appear in similarity search; they still surface via recent queries.
Configure an embedder in ~/.covenant/secrets.toml:
[embed]
provider = "ollama"
model = "nomic-embed-text"With the above, every memory write embeds via Ollama on http://localhost:11434. The embedder is shared across writes and search queries, so query and document vectors are guaranteed to be in the same space.
Reading recent memory
Recent reads and semantic search require memory.read or a tier-specific memory.read.<tier> capability. Results are filtered to the authenticated owner and the signed memory scope before they are returned.
covenant memory recent
covenant memory recent --tier longterm
covenant memory recent --tier episodic --limit 50
covenant memory recent --tier working --limit 10 --json
# Or via HTTP:
curl -s '127.0.0.1:8421/memory/recent?tier=longterm&limit=50'Semantic search
Search runs cosine similarity over stored vectors. The query is embedded with the same provider used for writes; results are returned in descending similarity order.
covenant memory search "agent memory"
covenant memory search "agent memory" --tier longterm --limit 5
covenant memory search "agent memory" --tier working --limit 5 --json
# Or via HTTP:
curl -s '127.0.0.1:8421/memory/search?q=agent+memory&tier=longterm&limit=5'Garbage collection
Working-tier records grow unboundedly without explicit cleanup. The daemon exposes a purge primitive that removes records below a timestamp threshold:
# Purge working-tier records older than 24 hours.
covenant memory purge --tier working --older-than-ms 86400000 --json
# Purge anything before an explicit epoch.
covenant memory purge --before-ms 1714938000000
# Purge all tiers older than seven days.
covenant memory purge --older-than-ms $((7*24*60*60*1000))
# Machine-readable output:
{"kind":"memory_purged","tier":"working","before_ms":1714938000000,"purged":0}Episodic and long-term records are typically curated rather than auto-purged. The same primitive applies to those tiers; operators should select retention thresholds deliberately.
Drift reports
covenant verify runs read-only consistency checks across memory, audit, capability, and settlement state. The response includes aggregate checks plus machine-readable drift items that future repair commands can consume.
covenant verify --window 100 --json
# Drift kinds:
# memory_without_audit
# audit_without_memory
# memory_stale_parent
# capability_without_audit
# memory_receipt_mismatch
# memory_without_receipt
# receipt_without_memory_record
# memory_receipt_duplicate
# memory_receipt_owner_mismatchThe verifier does not delete, detach, or backfill records. It reports the repair posture for each drift item so an operator or future autonomous repair command can decide what to mutate.
Repair primitives
The memory crate defines explicit repair requests with dry_run and apply modes. Dry-run returns the exact before/after shape without mutating the store; apply performs the same checked operation.
detach_parentclears a stale parent reference and can guard against a changed record withexpected_parent.delete_recordremoves a confirmed invalid or unsafe memory record.backfill_provenancewrites provenance evidence undermetadata.provenancewhile preserving existing metadata.
These primitives are implemented in the store layer. Daemon, CLI, and audit-log exposure remain pending.
The .covenantignore allow/deny list
Covenant supports a .covenantignore file at $COVENANT_HOME/.covenantignore with gitignore- style patterns. An intent whose text matches any of the active patterns is short-circuited before dispatch:
- The router is skipped — no agent runs.
- No memory record is written.
- No settlement receipt is written.
- An
IntentIgnoredaudit event is recorded with the matching pattern.
Pattern syntax: * matches any sequence within a single segment, ** across segments, ? matches a single character. ! negates an earlier match. / at the start anchors to the path root. Last-rule-wins: a later rule supersedes an earlier match.
The default seed list, created on first daemon start when no file is present, covers common credential filenames. Intents that reference paths such as id_rsa, .env, or credentials.json are dropped without persisting to memory or producing a settlement receipt.
Test the ignore set
covenant ignore check --json "summarise ~/.ssh/id_rsa"
{"kind":"ignore_report","ignored":true,"matched_pattern":"id_rsa","rules_loaded":5}Related
- CLI — every memory subcommand.
- Audit log — where
IntentIgnoredlands. - Settlement — memory writes pair 1:1 with receipts.