The temporal knowledge graph
Memtrace parses your code into typed symbols and edges, versions every change bi-temporally, and keeps it queryable by your agent through hybrid search.
Every indexed repository becomes a graph: symbols, the typed edges between them, and a full history of how both changed over time. This is what your agent actually queries — not the files on disk.
What gets stored#
Memtrace parses source with tree-sitter into AST-derived symbols (functions, classes, types, and the rest of your language's declarations) and typed edges between them — calls, imports, type usages, and references. This is the same graph that graph algorithms, relationship queries, and blast-radius analysis all traverse.
The graph is stored in MemDB with bi-temporal versioning: every symbol and edge carries both when it was true in the code and when Memtrace learned about it. Each change is recorded as an episode — and episodes are captured at save granularity, not just at commit granularity.
Alongside the structural graph, Memtrace computes embeddings for semantic search — jina-code, a code-specialized 768-dimension model, is the default embedder. These embeddings back the semantic half of hybrid search; BM25 handles the lexical half. The embedder is swappable per repository — see embedder configuration.
Finally, the graph is branch-aware: versioning is scoped across two axes, branch and time, and this is on by default.
How it flows#
Why save granularity matters#
A file watcher feeds the same graph on every save, not just every commit — so episodes exist at a finer grain than git log can ever show. That gap is exactly what an agent needs: the sequence of intermediate edits between two commits — an approach tried and reverted, a symbol renamed twice, a function that existed for three saves before being deleted. Commit history alone erases all of that; save-granularity episodes keep it queryable.
Memtrace never deletes or prunes episode history. Full history is the product — the value of the graph compounds the longer it runs, and an agent asking what changed or why needs the complete record, not a pruned recent window. Maintenance tools exist (worktree and stale-record cleanup), but routine episode history is never rewritten.
Branch-aware by default#
The graph versions per branch as well as per commit: each branch gets its own live view, and queries scope to your current branch without losing the rest of the graph's history. This is on by default — there's no flag to opt in.
See architecture for how the graph fits into the rest of the runtime, or jump straight to hybrid search and temporal memory for how it's queried.