Memory and knowledge
TRW has two related memory surfaces: the project memory used by trw-mcp and the standalone trw-memory engine, which applications can embed or run as a daemon. This page explains persistence and retrieval; it does not make recalled entries automatic truth. Re-check them against the current repository and task.
Their default storage layouts and activation paths differ. See cross-project memory boundaries before sharing or migrating data.
The knowledge flywheel
TRW's architecture is built around a reinforcing loop: capture what mattered, rank it by usefulness, and retrieve it when a later task asks for it. Early sessions can produce raw learnings; later sessions explicitly recall candidates and re-check them against the current repository.
How it works
A learning can move through six explicit stages from initial discovery to durable, revisable project context.
- 1
Learn
Your AI discovers a gotcha, pattern, or architecture decision during work.
- 2
Persist
trw_learn() stores the discovery in the project memory layer under .trw/ with tags and metadata.
- 3
Recall
The agent explicitly calls session start or recall to retrieve ranked candidates.
- 4
Re-check
The agent validates recalled context against the current repository before reuse.
- 5
Update
Recording a correction with trw_learn(learning_id=...) updates an entry; stale entries can be superseded or retired.
- 6
Preserve
The durable store remains available after context compaction and across later sessions.
Learning lifecycle
Every learning goes through a managed lifecycle. This is not a flat key-value store - it is a managed knowledge system with scoring, decay, feedback, and retirement.
- Stage
- Recording
- What happens
- AI calls
trw_learn()with summary, detail, and tags - Mechanism
- Structured entry stored in the project learning store under .trw/
- Stage
- Scoring
- What happens
- Relevance, time decay, and recall-frequency decay shape ranking
- Mechanism
- Persisted utility fields
- Stage
- Recall
- What happens
- Future sessions retrieve relevant learnings through configured search
- Mechanism
- BM25 keyword search; optional dense vector similarity
- Stage
- Decay
- What happens
- Query-time utility applies retention decay without rewriting stored impact
- Mechanism
- Ebbinghaus-inspired retention factor
- Stage
- Feedback
- What happens
- A learning recorded again decays more slowly; frequent recall lowers importance to a floor
- Mechanism
- Frequency-based decay is applied during recall ranking
- Stage
- Consolidation
- What happens
- Related learnings merged, stale ones pruned
- Mechanism
- Jaccard dedup + semantic clustering
| Stage | What happens | Mechanism |
|---|---|---|
| Recording | AI calls trw_learn() with summary, detail, and tags | Structured entry stored in the project learning store under .trw/ |
| Scoring | Relevance, time decay, and recall-frequency decay shape ranking | Persisted utility fields |
| Recall | Future sessions retrieve relevant learnings through configured search | BM25 keyword search; optional dense vector similarity |
| Decay | Query-time utility applies retention decay without rewriting stored impact | Ebbinghaus-inspired retention factor |
| Feedback | A learning recorded again decays more slowly; frequent recall lowers importance to a floor | Frequency-based decay is applied during recall ranking |
| Consolidation | Related learnings merged, stale ones pruned | Jaccard dedup + semantic clustering |
Impact scoring
Not all learnings are equally useful for a query. TRW composes effective utility from four runtime inputs and uses that score as one signal in recall priority.
- Factor
- Stored utility
- Weight
- High
- Description
- Recall ranking uses relevance with time decay and recall-frequency decay.
- Factor
- Retention decay
- Weight
- Medium
- Description
- Age reduces effective utility at query time without silently rewriting stored impact.
- Factor
- Access boost
- Weight
- Medium
- Description
- Recall frequency affects decay; it does not independently establish correctness.
- Factor
- Source boost
- Weight
- Low
- Description
- Configured provenance or source signals can adjust effective utility.
| Factor | Weight | Description |
|---|---|---|
| Stored utility | High | Recall ranking uses relevance with time decay and recall-frequency decay. |
| Retention decay | Medium | Age reduces effective utility at query time without silently rewriting stored impact. |
| Access boost | Medium | Recall frequency affects decay; it does not independently establish correctness. |
| Source boost | Low | Configured provenance or source signals can adjust effective utility. |
Scores range from 0.0 to 1.0. A high score affects ranking but does not copy a learning into a client instruction file. Low-value or stale entries can become consolidation or retirement candidates under the configured policy.
Instruction files and memory are separate
Learnings remain in the memory store and surface through trw_session_start() or trw_recall(). CLI trw-mcp instructions sync refreshes the TRW protocol in the selected client instruction file; it does not promote arbitrary learning content into that file.
Benchmark evidence and claim boundary
What each test shows, and where it stops. None of them is a promise about your repository, your model or your coding tool.
LOCOMO search
Right message in the top 10 for 85.8% of 1,540 questions (95% interval 83.9% to 87.4%), top 50 for 92.7% (91.3% to 93.9%)
Search hit rate with no AI grading, from the Python library on the trw-memory 4.0.0 release candidate. Not comparable with the AI-graded answer scores other memory products publish.
LongMemEval search
Right message in the top 10 for 93.8% of 470 questions (95% interval 91.3% to 95.7%), top 50 for 97.4% (95.6% to 98.5%)
Cleaned dataset, answerable questions only, a single run on trw-memory 2.0.0.
Head to head with Mem0
88.9% of 1,540 answers judged correct against 84.1% for Mem0: +4.8 points, paired 95% interval +2.9 to +6.8, McNemar p < 0.0001, ahead in all ten conversations. No AI calls to store the conversations, against one per turn for Mem0
Mem0’s own harness on all ten LOCOMO conversations, top 10 memories, same reader and judge (gpt-4o-mini). trw-memory 2.0.0 against self-hosted mem0ai 2.0.20; the embedders differed.
Keyword + meaning search
Right note in the top 10 for 93.8% of 889 queries, against 91.4% and 86.9% for each alone
Our own engineering notes, trw-memory 0.9.12; point estimates, significance not assessed.
Repeat-work check
Earlier note findable in 94.3% of 175 re-learned cases [89.8, 96.9], against 72.0% with keywords [64.9, 78.1]
Non-overlapping 95% intervals; trw-memory 0.9.12.
Memory across sessions
58 of 58 tasks finished with memory, 0 of 50 without
Paired McNemar p = 3.6×10⁻¹⁵ over 49 matched pairs, replicated on a second model family. The tasks were built to need a fact from an earlier session.
Memory tools
Four common MCP tools cover session startup, recording, retrieval, and updates. The agent or client invokes them explicitly; optional hooks are additive reminders, not the memory lifecycle itself.
- Tool
- trw_session_start
- What it does
- Load relevant project context and recover an active run.
- When to use
- As the first TRW action of a session
- Tool
- trw_learn
- What it does
- Record a discovery with summary, detail, and tags.
- When to use
- Errors, gotchas, patterns, architecture decisions
- Tool
- trw_recall
- What it does
- Search past learnings by keyword, tags, or impact tier.
- When to use
- Before starting unfamiliar work or revisiting a domain
| Tool | What it does | When to use |
|---|---|---|
| trw_session_start | Load relevant project context and recover an active run. | As the first TRW action of a session |
| trw_learn | Record a discovery with summary, detail, and tags. | Errors, gotchas, patterns, architecture decisions |
| trw_recall | Search past learnings by keyword, tags, or impact tier. | Before starting unfamiliar work or revisiting a domain |
See the Tools Reference for the complete list of all 15 MCP tools.
Code examples
Here is what the memory system looks like in practice across a typical session.
trw_learn# AI discovers a gotcha during implementation:
trw_learn(
summary="FastAPI dependency overrides must be reset in teardown",
detail="Without resetting app.dependency_overrides in test teardown, "
"overrides leak between tests causing flaky failures.",
tags=["fastapi", "testing", "fixtures"]
)
# -> Learning recorded
# -> Impact score: 0.51
# -> Stored in the project learning store under .trw/trw_recall# Next session: AI is about to write FastAPI tests
trw_recall("fastapi testing fixtures")
# -> 3 relevant learnings found:
#
# [0.72] FastAPI dependency overrides must be reset in teardown
# tags: fastapi, testing, fixtures
#
# [0.65] TestClient requires app factory pattern for isolation
# tags: fastapi, testing
#
# [0.41] pytest-asyncio auto mode conflicts with sync fixtures
# tags: pytest, async, testingtrw_deliver# End of session: deliver checks policy and persists delivery state
trw_deliver()
# -> Build gate: PASS (caller-reported project checks)
# -> Delivery state persisted
# -> Run closed: api-tests-refactorProject and user tiers
Every checkout on a machine uses one store, at ~/.trw, served by the memory daemon. Learnings live in one of two namespaces in it. The project tier is the default — repo-specific knowledge in the checkout's own namespace, which install pins as project_namespace and grants to that checkout. The user tier is the user:local namespace that every checkout on the machine shares, so portable knowledge follows you instead of being relearned in each project.
- Tier
- Project
- Store
this checkout's project namespacescope=scope="project"- Holds
- The default. Repo-specific learnings, in the namespace pinned by project_namespace in .trw/config.yaml.
- Tier
- User
- Store
user:localscope=scope="user"- Holds
- Machine-local, never pushed. Portable learnings — operator preferences, cross-cutting patterns, workflow knowledge — that apply to every repo on your machine.
| Tier | Store | scope= | Holds |
|---|---|---|---|
| Project | this checkout's project namespace | scope="project" | The default. Repo-specific learnings, in the namespace pinned by project_namespace in .trw/config.yaml. |
| User | user:local | scope="user" | Machine-local, never pushed. Portable learnings — operator preferences, cross-cutting patterns, workflow knowledge — that apply to every repo on your machine. |
Routing a learning
trw_learn() takes a scope argument. "auto" (the default) classifies portability and routes accordingly: a finding with a repo-relative path or local symbol stays in the project tier, while a cross-cutting preference or workflow rule goes to the user tier. Passing "project" or "user" overrides the classifier.
trw_learn# Repo-specific gotcha -> stays in the project tier (.trw/)
trw_learn(
summary="Reset app.dependency_overrides in test teardown",
detail="Leaks between tests in src/api/conftest.py cause flaky failures.",
tags=["fastapi", "testing"]
) # scope="auto" -> project (a repo-local path was detected)
# Cross-cutting preference -> routes to user:local
trw_learn(
summary="Prefer path-limited git commits to avoid index races",
detail="Holds across every repo; not tied to one codebase.",
tags=["workflow", "git"]
) # scope="auto" -> user (portable, no repo-local signal)
# Force a tier explicitly when you know better than the classifier
trw_learn(summary="...", detail="...", scope="user")Recall across tiers
trw_recall() reads the project and user tiers into one ranked result, so a single query surfaces relevant learnings from both. A precise project hit keeps its rank; user-tier hits are bounded by recall_user_tier_cap (default 5) so a busy user store can never bury project precision. Pass include_tiers=["project"] to restrict a recall to the project tier only.
Memory routing
TRW memory and a coding client's native memory can coexist. Use TRW when you need an explicit MCP lifecycle and per-project retrieval contract; use client memory according to that client's documented scope and loading behavior.
- Dimension
- Control surface
trw_learn()- Explicit MCP learn, recall, update, and forget operations
- Native auto-memory
- Defined by the active coding client
- Dimension
- Default scope
trw_learn()- One namespace per project in a store on your machine, plus a machine-wide user namespace
- Native auto-memory
- Client-specific project or user scope
- Dimension
- Retrieval
trw_learn()- Keyword path by default; optional dense and graph expansion
- Native auto-memory
- Client-specific indexing and loading behavior
- Dimension
- Lifecycle
trw_learn()- Explicit updates and retirement with configurable scoring
- Native auto-memory
- Client-specific editing and retention behavior
- Dimension
- Best for
trw_learn()- Gotchas, patterns, build tricks, architecture decisions
- Native auto-memory
- Commit style, communication preferences
| Dimension | trw_learn() | Native auto-memory |
|---|---|---|
| Control surface | Explicit MCP learn, recall, update, and forget operations | Defined by the active coding client |
| Default scope | One namespace per project in a store on your machine, plus a machine-wide user namespace | Client-specific project or user scope |
| Retrieval | Keyword path by default; optional dense and graph expansion | Client-specific indexing and loading behavior |
| Lifecycle | Explicit updates and retirement with configurable scoring | Client-specific editing and retention behavior |
| Best for | Gotchas, patterns, build tricks, architecture decisions | Commit style, communication preferences |
Where learnings live
TRW memory is local-first. The store is a SQLite file on your machine, served by the trw-mcp memory daemon, with one namespace per project, so the base workflow does not depend on a hosted service. Your repo's .trw/ directory holds the project's settings and a YAML copy of each learning, not the searchable store.
- Path
.trw/- Contents
- Project settings, run state, the checkout’s memory grant and a YAML copy of each learning, managed by TRW. The searchable store is not here.
- Path
.trw/config.yaml- Contents
- Project-level settings, including the project_namespace pin that names this project’s namespace in the store, recall thresholds and sync behavior.
- Path
~/.trw/memory/memory.db- Contents
- The memory store the trw-mcp daemon serves: one SQLite file per machine, with a namespace for each project and a machine-wide user:local namespace. XDG_DATA_HOME or TRW_USER_DIR moves it.
| Path | Contents |
|---|---|
.trw/ | Project settings, run state, the checkout’s memory grant and a YAML copy of each learning, managed by TRW. The searchable store is not here. |
.trw/config.yaml | Project-level settings, including the project_namespace pin that names this project’s namespace in the store, recall thresholds and sync behavior. |
~/.trw/memory/memory.db | The memory store the trw-mcp daemon serves: one SQLite file per machine, with a namespace for each project and a machine-wide user:local namespace. XDG_DATA_HOME or TRW_USER_DIR moves it. |
Some memory artifacts are human-readable, while the retrieval layer is optimized for local search performance rather than hand-editing every internal file. Treat .trw/ as project state managed by TRW, and use the memory tools for normal day-to-day updates.
Audit log durability: fsync_on_append
MemoryConfig accepts a fsync_on_append boolean (default false). When enabled, each audit log write is flushed to disk with fsync before returning - preventing log loss on unexpected process exit. Enable this in environments where audit durability is required. It reduces the window for audit-log loss at the cost of write latency; it is not a guarantee against storage-device or filesystem failure.
SQLite corruption auto-recoveryv0.6.1+
If trw-memory detects a corrupt SQLite database on open, it attempts the configured recovery path:
- Renames the corrupt file to
<original>.corrupt.bak - Salvages any recoverable rows into a fresh database
- Cleans up stale
-waland-shmsidecar files - Retries the original operation
When salvage or cold rebuild succeeds, the operation can retry and a warning records the backup path. Under the strict default, unrecoverable salvage/rebuild failure is raised rather than hidden; inspect the backup and restore from known-good state.