Memory and knowledge
This is the memory engine inside TRW's engineering operating layer. Discoveries can persist outside one conversation and be retrieved by explicit session-start or recall calls. Recalled entries are candidates to re-check, not automatic truth or guaranteed outcome improvement.
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
Explicit feedback can update utility; 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
- Stored impact and Q-value provide base utility inputs
- 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
- Explicit outcome correlation may update stored utility fields
- Mechanism
- Persisted Q-value update outside query-time scoring
- 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 | Stored impact and Q-value provide base utility inputs | 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 | Explicit outcome correlation may update stored utility fields | Persisted Q-value update outside query-time scoring |
| 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
- Impact and Q-value provide the durable base; explicit outcome feedback can update Q-value.
- Factor
- Retention decay
- Weight
- Medium
- Description
- Age reduces effective utility at query time without silently rewriting stored impact.
- Factor
- Access boost
- Weight
- Medium
- Description
- Recorded access history can boost ranking; frequency alone does not establish correctness.
- Factor
- Source boost
- Weight
- Low
- Description
- Configured provenance or source signals can adjust effective utility.
| Factor | Weight | Description |
|---|---|---|
| Stored utility | High | Impact and Q-value provide the durable base; explicit outcome feedback can update Q-value. |
| Retention decay | Medium | Age reduces effective utility at query time without silently rewriting stored impact. |
| Access boost | Medium | Recorded access history can boost ranking; frequency alone does not 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(). trw_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
These measurements establish retrieval behavior on named surfaces. They do not establish a universal improvement rate for arbitrary repositories, tasks, models, or coding clients.
Retrieval gold set
Hybrid Recall@10 0.938 on n=889 typed queries
Same-harness retriever ablation; not an end-to-end coding benchmark.
Rediscovery readout
Hybrid PRR 0.943 vs BM25 0.720 on n=175 near-duplicates
Measures whether recall could surface prior content, not whether an agent uses it correctly.
Controlled recall dependency
58/58 with memory vs 0/50 without on H1-MEMORY-BENCH
The required fact is absent by construction in control; broad coding-task lift remains separate.
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
- trw_learn_update
- What it does
- Mark learnings as resolved, obsolete, or update their content.
- When to use
- When an issue is fixed or context changes
| 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 |
| trw_learn_update | Mark learnings as resolved, obsolete, or update their content. | When an issue is fixed or context changes |
See the Tools Reference for the complete list of all 45 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
Learnings live in one of two tiers. The project tier is the default — repo-specific knowledge stored under .trw/ in the project namespace. Whether that state travels with the codebase depends on repository policy. The opt-in user tier is a machine-local store at ~/.trw (or your XDG data dir) that every repo on the same machine shares, so portable knowledge follows you instead of being relearned in each project.
- Tier
- Project
- Store
.trw/ in the reposcope=scope="project"- Holds
- The default. Repo-specific learnings stay in the project namespace; whether project state is versioned follows repository policy.
- Tier
- User
- Store
~/.trw on your machinescope=scope="user"- Holds
- Opt-in, machine-local. Portable learnings — operator preferences, cross-cutting patterns, workflow knowledge — that apply to every repo on your box.
| Tier | Store | scope= | Holds |
|---|---|---|---|
| Project | .trw/ in the repo | scope="project" | The default. Repo-specific learnings stay in the project namespace; whether project state is versioned follows repository policy. |
| User | ~/.trw on your machine | scope="user" | Opt-in, machine-local. Portable learnings — operator preferences, cross-cutting patterns, workflow knowledge — that apply to every repo on your box. |
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 when one is present. 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 the user tier (~/.trw) when enabled
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() federates 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 project-local 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()- Project-local store; optional machine-local user tier
- 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 | Project-local store; optional machine-local user tier | 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 project-local and travels with your repo. The runtime uses a local storage layer under .trw/, so the base workflow does not depend on a hosted service.
- Path
.trw/- Contents
- Project-local learning store, run state, and supporting memory artifacts managed by TRW.
- Path
.trw/config.yaml- Contents
- Project-level settings that shape recall thresholds, sync behavior, and related memory defaults.
- Path
~/.trw or XDG data- Contents
- Optional machine-local user tier when explicitly enabled; separate from the project store.
| Path | Contents |
|---|---|
.trw/ | Project-local learning store, run state, and supporting memory artifacts managed by TRW. |
.trw/config.yaml | Project-level settings that shape recall thresholds, sync behavior, and related memory defaults. |
~/.trw or XDG data | Optional machine-local user tier when explicitly enabled; separate from the project store. |
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.
Next steps
Next steps