AgentMemorySync
A shared memory layer for Claude Code and Codex CLI. Both agents work the same repository from one searchable history. Neither agent starts from zero.
Two agents on one repo, each with amnesia.
Run Claude Code and Codex CLI against the same codebase and they act like strangers. Every session re-reads the same files. Every session re-derives the same architecture. Every session re-explains the same decisions. Worse: the two agents can edit the same file minutes apart with no awareness of each other. Best case, duplicated work. Worst case, silent conflicts.
The bottleneck is not intelligence. The bottleneck is continuity. No shared, queryable record existed for what either agent had already done.
Each new session re-reads context cold and rebuilds a mental model from scratch.
Duplicated edits, contradictory changes, and repeated explanations across sessions.
One pooled history each agent retrieves from at the start of a session.
One memory store, reached two ways.
Claude Code integrates through session hooks; Codex through a FastAPI-backed MCP server. Both paths call the same write and recall logic, so everything either agent records lands in one SQLite database and one shared timeline, keyed by git repository root.
· MCP
write · recall · graph
Both clients write to and recall from a single store. No per-agent silos.
The service writes sessions, decisions, and file touches as timeline events, and redacts secrets on the way in.
Each event is indexed for full-text search (BM25) and embedded by a local model for dense retrieval. Vectors are cached in SQLite, keyed by content hash and model.
On session start, an agent asks for what matters. The service fuses the two rankings and returns a compact briefing.
Hybrid retrieval, fused with reciprocal rank fusion.
Lexical search nails exact identifiers: a function name, an error string, a file path. It is helpless when the query and the answer share no words. Dense embeddings catch that paraphrase and intent, but blur exact-token lookups. Neither method wins alone. Both run, and the system merges their rankings.
FTS5's built-in BM25 ranking scores the event text directly. Fast, exact, and free of any model dependency. The store is the index. On the benchmark it recalls exact-identifier lookups at 1.00.
bge-small-en-v1.5 runs on CPU through ONNX (via fastembed): a real 384-dimension embedding, no API key and no network after a one-time model download. Similarity is cosine against a measured 0.60 floor; if the model can't load, retrieval degrades to a lexical-hashing fallback and the dashboard reports it as degraded rather than pretending.
RRF combines the two ranked lists by rank position, not raw score, so the retrievers' incompatible scales never need calibrating. The constant k was swept on the benchmark and set to 5, not the textbook 60, which flattens a two-leg fusion. A result ranked highly by either method rises to the top.
An earlier build used hashed character n-grams as the "semantic" leg. That is a lexical signal in a vector's clothing: two paraphrases with no shared words hash into different buckets, so it added almost nothing over BM25. The rewrite swapped it for a trained embedding model, and rebuilt the evaluation to a split where queries are guaranteed to share zero content words with their answers, plus one keyword-sharing hard negative per case, so the number could not be gamed. The improvement below is against that harder test.
A parallel AST-derived symbol graph tracks calls, references, inheritance, and test links across the Python codebase. Recall expands from a single hit to every structurally connected symbol.
Reciprocal rank fusion, in the hot path.
The fusion step is small, and ranking quality leans on it. Each retriever returns an ordered list of event ids. RRF scores every id by 1 / (k + rank) and sums the scores across lists.
Illustrative excerpt, reconstructed from the public repo's design. See the source for the real implementation.
Measured, not asserted.
Retrieval quality answers to a labeled benchmark, not vibes. A 40-query, 60-document set with an enforced zero-lexical-overlap paraphrase split and hard negatives scores every change. The table below compares the naive scan, BM25 alone, and the production hybrid path.
- Both agents start each session with the other's relevant history instead of a cold read.
- Security is first-class: per-repo RBAC, secret redaction on ingest, and SHA-256 hash-chained audit logs make the history tamper-evident.
- No API keys, no per-token cost, no rate limits. The 64 MB embedding model runs locally on CPU; vectors cache in SQLite, and retrieval degrades to lexical if the model is ever unavailable.
AgentMemorySync is open source.