Project memory a later session can explicitly recall
TRW Memory stores selected project learnings outside the conversation that produced them. When the agent calls session start or recall, ranked candidates can be added to context and re-checked before substantive work; optional graph expansion is shown at right.
Memory that survives compaction
Learnings live in a SQLite store on your machine, with no hosted service required. The trw-mcp memory daemon keeps one file, by default ~/.trw/memory/memory.db, with a separate namespace for each project. Optional sync depends on configuration. Inside your repo, .trw/ holds the project's settings, including which namespace it uses, and a YAML copy of each learning.
Durable storage survives conversation compaction, but context injection is still an explicit ceremony action. The agent or client calls trw_session_start() first, or uses trw_recall(), to retrieve candidates again before substantive work.
id: M-a3f2c1b9 summary: JWT refresh tokens need rotation on every use tags: [security, auth] importance: 0.93 created_at: 2026-04-01T09:12:43Z
4000+
repository inventory, not outcome proof
Local
primary SQLite storage
Not just vectors. A scoring engine.
Retrieval fuses keyword matching with dense vector similarity (with embeddings installed), then a cross-encoder re-reads the top candidates and sets the final order when its model is available. Utility, built from importance and time decay, does not reorder search results: it orders a recall with no query and, with age, decides what is archived or purged. The retrieval path does not run or observe repository checks.
A learning recorded again decays more slowly. Frequent recall adds a small, capped access boost, while a separate recall-frequency decay lowers an entry's importance the more often it is recalled, down to a floor.
UTILITY FORMULA
search = keyword + vector fusion, then cross-encoder re-rank
utility does not reorder search results
utility = importance × max(floor, 0.95^r) × retention
+ access_boost + source_boost
r = times recalled
orders recall with no query; with age, gates archive and purge
retention = exp(−(ln2 / half_life) / k^0.6 × days_unused)
k = recurrence (starts at 1; +1 each time it is recorded again)
half_life: per type and confidence (14-day fallback)Utility never reorders search results. It orders a recall with no query and, with age, gates archive and purge.
HYBRID RETRIEVAL PIPELINE
BM25 (keyword)
BM25Okapi sparse retrieval — exact match, token overlap
Dense (vector)
Cosine similarity via sqlite-vec — conceptual similarity
RRF fusion
Reciprocal Rank Fusion — entries present in both lists score higher. The Python library also blends in each entry’s importance (30% by default); the MCP tools fuse on rank alone
Re-rank
When its model is available, a second model re-reads the top candidates and drops weak matches, in the Python library and the MCP recall tools alike
Utility order (no query)
A search keeps the order above. Only a recall with no query, which has no search ranking, is ordered by utility
Graceful degradation: if the embedding model is not cached, BM25 runs alone and recall stays keyword-only until you run trw-mcp models fetch. Without the re-ranker model, recall keeps fusion order.
What it finds, and what it costs
Memory only helps if the right note comes back when your agent needs it. Here is how often trw-memory finds it on two public benchmarks, how it compares with Mem0 on Mem0's own test, and what it costs to run as your store grows. Methods, raw tables and the full fine print are in the trw-memory README.
PUBLIC BENCHMARK · LOCOMO
10 long conversations, 1,540 questions
85.8%
found in top 10
95% CI 83.9–87.4%
92.7%
found in top 50
95% CI 91.3–93.9%
How often the message that holds the answer came back in the results.
PUBLIC BENCHMARK · LongMemEval
470 questions, each with its own 38 to 62 past chat sessions
93.8%
found in top 10
95% CI 91.3–95.7%
97.4%
found in top 50
95% CI 95.6–98.5%
How often the turn that holds the answer came back in the results.
These are search hit rates with no AI model grading anything: LOCOMO from the trw-memory 4.0.0 release candidate, LongMemEval from 2.0.0. They measure something different from the answer scores most memory products publish, so we don’t put the two side by side. The Mem0 comparison below is graded answers, run the same way on both systems.
KEYWORD + MEANING SEARCH
889 searches over real engineering notes. How often the right note made the top 10.
Combining the two scored highest of the three (point estimates; significance not assessed). Measured on trw-memory 0.9.12.
CATCHING REPEAT WORK
175 times an agent in our own project re-learned something it had already written down. Would a search have turned up the earlier note?
The two 95% confidence intervals do not overlap. Measured on trw-memory 0.9.12.
HEAD TO HEAD WITH MEM0
All 1,540 LOCOMO questions, answered and graded the same way for both systems.
| Measure | Mem0 | trw-memory |
|---|---|---|
| Answers judged correct | 84.1% | 88.9% |
| AI calls to store 5,882 turns | 1 per turn | none |
trw-memory answered 4.8 points more questions correctly, a statistically significant lead (paired 95% interval +2.9 to +6.8, McNemar p < 0.0001), and led in all ten conversations. By default, storing makes no AI calls: trw-memory keeps each turn as written, while Mem0 makes an extraction call for every write.
Method: Mem0’s evaluation harness on all ten LOCOMO conversations. Each system answered from its top 10 memories with the same reader and judge (gpt-4o-mini) and the same prompts. trw-memory 2.0.0 with bge-small-en-v1.5 against self-hosted mem0ai 2.0.20 with all-MiniLM-L6-v2; the embedders differed. September 2026.
COSTS THAT STAY SMALL AS IT GROWS
Time per operation on one machine, before and after our September 2026 work.
| Operation | Before | After |
|---|---|---|
| Ingest per conversation turn, shared store | 1,464 ms | 15 ms |
| Save with 20 projects sharing it | 708 ms | 15 ms |
| Housekeeping per search, 20,000 notes | 289 ms | 1.3 ms |
| Scan per search, 20,000 notes | 60.5 ms | 3.2 ms |
| Link related notes, 10,000 notes | 12.4 ms | 2.3 ms |
Each of these used to slow down sharply as the store grew or as more projects shared it. Profiling cut them by 2× to over 200×. Single runs on one machine.
MEMORY ACROSS SESSIONS
58 / 58
with memory
0 / 50
without memory
Tasks finished
We built tasks that can only be finished with a fact from an earlier session. With memory, agents finished all of them. Without it, none, because the fact existed nowhere else (paired McNemar p = 3.6×10⁻¹⁵ over 49 matched pairs). The result held on a second model family.
The tasks were built to need a fact from an earlier session, so this shows what recall across sessions makes possible, not a general measure of coding performance.
A typed knowledge graph, not a flat index
Each learning can become a node and relationships can become typed edges. When a caller explicitly enables graph expansion, BFS traversal from a matched root can surface related entries that share no query keywords. Graph expansion is disabled on the default recall path; the hero demo visualizes the opt-in capability.
INFERRED SIMILARITY
similarityCosine similarity above threshold
tag_cooccurrenceShared tags, Jaccard-weighted
related_toGeneral associative relation
co_anchoredEntries anchor to one source
LIFECYCLE + PROVENANCE
consolidationMerge lineage
anchored_toBound to a source file
producedAction generated the entry
motivated_byCreated in response to another
supersedesNewer entry replaces an older one
DECLARED REASONING
same_root_causeOne failure mode
depends_onValidity depends on another entry
evidence_forEmpirical support for another entry
conflicts_withContradictory entries
When enabled, BFS traversal depth is capped at 3. Cross-edge propagation rates vary by type: evidence_for propagates impact at 30%, co_anchored at 20%, same_root_cause at 15%.
Required first call, inspectable recall path
TRW requires the agent to call trw_session_start() as its first TRW action. The call is explicit: storage does not autonomously place memories into a prompt, and optional client hooks are only additive reminders.
- 01Agent callsSession start supplies project and task context to the memory query.
- 02Memory ranksKeyword and dense search are fused and re-ranked into a bounded candidate list.
- 03Agent re-checksCandidates enter working context and must be verified against the current repository before reuse.
Explicit deposits use trw_learn(); targeted lookups use trw_recall().
Order is real; timings are omitted deliberately. Run-to-run latency varies by index size and whether embeddings are enabled.
Technical specification
DEFAULT PATH
OPTIONAL CONTROLS
PACKAGE SURFACE
Share with authorisation. Keep the source.
A useful discovery may apply beyond one repository. Choose the sharing boundary explicitly; relevance and supporting evidence do not grant permission to cross it.
Project recall stays scoped
MCP recall reads the current project namespace and machine-wide user-scope learnings. It does not search other projects' namespaces in that store. Keep secrets and project-specific sensitive knowledge out of user scope.
Shared stores are a separate choice
Standalone cross-validation uses explicitly co-located namespaces and compatible embeddings. Hosted team sync is opt-in. Namespace labels are not an access-control guarantee; verify storage access and configuration before sharing sensitive material.
What memory does not do
Accurate scoping saves debugging time later.
No pre-populated graph
The knowledge graph builds entirely from entries you deposit. A fresh install has no edges and no semantic clusters — those emerge over sessions.
Recall frequency cuts both ways
Search results are ordered by relevance; utility orders only a recall with no query and decides what is archived. Frequent recall adds a small, capped access boost, and a separate recall-frequency decay lowers importance, down to a floor. A learning recorded again decays more slowly.
Embeddings are optional
Dense vector search needs the [embeddings] extra, which the installer adds by default. Without it, retrieval falls back to BM25 keyword matching only — still useful, not identical.
Memory does not self-correct wrong entries
If an agent stores an incorrect learning, it persists until it is explicitly forgotten or superseded. Memory is as reliable as the agents depositing into it.
Not a replacement for checkpoints
Memory stores learnings — patterns, gotchas, decisions. Checkpoints save resumable execution state. They are complementary, not interchangeable.
Recall is an explicit action
The agent or client must call session start or recall. Optional hooks can remind or invoke compatible paths, but storage alone does not inject context.
Graph expansion is opt-in
Typed graph traversal is available when recall enables graph expansion. The default recall path does not traverse graph neighbors.
Common questions
What is the difference between TRW Memory and Claude Code's built-in memory?
Does TRW Memory send code or project data to a server?
What happens to recalled learnings when context compacts?
How long before Memory starts being useful in a new project?
Give your agents persistent memory
Install the open framework, store one material project learning, then retrieve and re-check it from a later session. The tool signatures, defaults, and storage layout are in the memory spec.
# install
$ curl -fsSL https://trwframework.com/install.sh | bash