Matrix logo

Cortex: Developer Reference

Cortex is Matrix's per-actor persistent memory store, a Pebble-backed KV database with a typed taxonomy, salience-ranked queries, async embeddings, Merkle snapshots, and a full replay invariant.

Cortex is Matrix's per-actor persistent memory store: a Pebble-backed key-value database with a typed memory taxonomy, a salience-ranked query engine, an async embedding pipeline, a Merkle-authenticated snapshot system, and a full replay invariant. Every durable thing an agent knows, facts, preferences, goals, constraints, past events, procedural patterns, lives here.

This documentation is written for people working on cortex itself, extending the memory types, tuning the salience formula, adding index layers, or understanding how the replay and snapshot machinery works.

Contents

DocumentWhat it covers
Memory TaxonomyThe 9 typed memory kinds, Head, Version, Forms, Tombstone
Store & JournalPer-actor Pebble DB, key encoding, atomic write batches, journal
Write APIWrite, Update, Tombstone, UpdateHead mutations and their journal footprint
Find QueryThe typed query engine, predicates, planner, ordering, graph traversal
Context BundleThe three-tier cold-start composer, Pinned, Frame-relevant, Outcomes
Embedder & VectorAsync embedding worker, pure-Go HNSW, Find Near / Find NearURI
Edges & GraphTyped edges, AddEdge, RemoveEdge, bounded BFS
Snapshot & ProofsJournal MMR, per-namespace SMTs, OverallRoot, multi-proofs
SalienceThe 5-factor formula, cold weights, EMA per-actor weight learning
Attest & CompactIntent attestation, salience feedback, budget-aware compaction
ScopeSub-agent CortexScope, Merkle-authenticated read/write gating
ReplayDrop-and-rebuild, the derivability invariant and Cortex.Rebuild

Repository layout

cortex/
├── go.mod
├── cortex.go               # top-level facade: Write / Update / Tombstone / Find / Context / Snapshot
├── attest.go               # Attest, intent-outcome salience feedback + EMA weight update
├── compact.go              # Compact, budget-aware context compaction + checkpoint records
├── context.go              # Context, three-tier cold-start bundle composer
├── edges.go                # AddEdge / RemoveEdge / GetEdge / IterEdgesOut / IterEdgesIn
├── embedder.go             # StartEmbedder / StopEmbedder / DrainEmbedder + HNSW worker
├── goal_state.go           # GoalRuntimeState sidecar (ambient scheduler bookkeeping)
├── ratelimit.go            # Phase 14 token-bucket DoS guards (scope violations + attests)
├── rebuild.go              # Cortex.Rebuild facade, delegates to replay.Rebuild
├── scope_enforce.go        # VerifyScope / enforceRead / enforceWrite / logScopeViolation
├── update_head.go          # UpdateHead, Head-only mutations without a Data version bump
├── keys/
│   └── keys.go             # all Pebble key constructors + namespace prefixes
├── journal/
│   └── journal.go          # Entry, Kind, payload types, canonical CBOR, leaf hash
├── memory/
│   ├── types.go            # Type, Visibility, Head, Version, Forms, Tombstone, SourceKind
│   ├── data.go             # IdentityData, FactData, …, PatternData (9 schemas)
│   ├── codec.go            # canonical CBOR encode/decode + HashVersion
│   ├── validate.go         # write-time schema validation
│   ├── verb.go             # Verb (10 D7 verbs), ObjKind, FrameRef
│   └── edge.go             # EdgeType, EdgeRecord
├── store/
│   ├── store.go            # Open, Get, PrefixIter, JournalHook, NextSeq
│   └── writebatch.go       # BeginWrite, AppendJournal (multi-entry), Commit / Abort
├── salience/
│   └── salience.go         # Score, ColdScore, ColdScoreWith, Weights, EMA helpers
├── forms/
│   ├── forms.go            # Render (short + medium), RenderFull (on-demand)
│   └── truncate.go         # TruncateToTokens (UTF-8-safe, bytes/4 heuristic)
├── query/
│   ├── predicate.go        # Predicate AST: Eq Ne Gt Gte Lt Lte In HasTag Matches And Or Not
│   ├── eval.go             # field resolver + scalar comparator
│   ├── find.go             # Run: planner, candidate scan, predicate eval, sort, render
│   └── graph.go            # BFS traversal for Query.From / Query.Follow
├── embed/
│   ├── embed.go            # Embedder interface + HashEmbedder (deterministic sha256 stub)
│   └── api_embedder.go     # HTTP-backed API embedder (nomic-embed-text-v1.5)
├── vector/
│   └── vector.go           # NewIndex, Add, Search, Save, Load, MapStore, VectorStore
├── snapshot/
│   ├── snapshot.go         # State, Snapshot(), CurrentRoots(), FindSnapshotByRoot()
│   ├── mmr.go              # journal MMR append + root computation
│   ├── smt.go              # per-namespace sparse Merkle tree (memories + edges)
│   └── multiproof.go       # MultiProof, BuildMultiProof, VerifyAgainstManifest
├── scope/
│   ├── scope.go            # Scope struct, Selector, Sign, Encode, Allows
│   ├── verify.go           # Verify, KeyResolver, StaticKeyResolver
│   ├── match.go            # Allows per-Head matching logic
│   └── errors.go           # ErrViolation, ErrNotWritable, ErrScopeExpired, …
├── replay/
│   ├── replay.go           # Rebuild, Result, Options, VerifyPreservesRoot
│   ├── rebuild.go          # rebuildMemoriesIndexes, rebuildEdgesSMT, rebuildJournalMMR, rebuildSalienceFromJournal
│   └── drop.go             # DropDerived, CountDerived
└── cmd/cortex-shell/       # smoke-test CLI: write/resolve/update/tombstone/find/snapshot

The one-sentence contract

Cortex is the ground truth for all durable agent memory. The context window is a cache; cortex is the disk. Every write is atomically journaled; the journal feeds a Merkle accumulator; snapshots seal the state root. Drop the derived indexes, replay the journal, roots match. That is the invariant everything else depends on.

Key locked decisions

These decisions are frozen. Do not re-litigate them without a documented protocol-level change.

IDDecision
D4Cortex holds no key material. Signing lives in the agent runtime or tools layer.
D11Compiler seed = sha256(intent.id || actor || OverallRoot || mtx_digest || model_digest). Same inputs produce same output.
D13#latest is forbidden at ParseURI time. All versions must be pinned before sign-off.
D17One Pebble DB per actor. All namespaces are key prefixes inside that DB, the only way to satisfy §11.1 batch atomicity across journal + head + version + indexes.
D7Verb vocabulary is closed at exactly 10 values: find acquire build modify deliver analyze negotiate schedule monitor delegate. ObjKind is similarly closed. Extending either requires a journaled migration.
§8.2Pinned memories carry a salience floor of 0.7. Tombstoned memories rank to zero and are filtered upstream.
§11.1Every store mutation, Write, Update, Tombstone, AddEdge, UpdateHead, Compact, Attest, commits journal + primary keys + index keys in a single atomic Pebble batch. A write without a journal entry fails with ErrBatchNoJournal.
Phase 10 Q7Sub-agent UpdateHead requires Scope.Writable=true. Default deny.