Documentation
Brain, decisions and recall
Durable memory, approved decision records and project-scoped recall.
On this page
Three layers of memory
TDE separates memory into three things that are often conflated:
| Layer | Question it answers | Where it lives |
|---|---|---|
| Brain | What do we know? | ~/.tde/brain/brain.db |
| Decisions | What did we commit to, and who approved it? | The same database, its own tables |
| Recall | What in this project is relevant right now? | ~/.tde/context-index/<project>.db |
All three are local-first. No external server is required, and nothing is sent anywhere to make search work.
TDE Brain
Brain is a wiki-shaped memory: SQLite with an FTS5 full-text index and an HNSW approximate-nearest-neighbor index alongside it. The ANN graph is persisted, so reopening TDE reuses it instead of rebuilding it from scratch — the first search of a session costs the same as the tenth.
Pages are the durable unit — a project id, a wiki path, a title, a body, a
tier, a pinned flag and an optional task reference. Four tiers exist:
Working, Episodic, Semantic (the default) and Procedural.
Observations are append-only: a session capture, a pipeline distillation or a manual note, optionally attached to a page and a session.
Edges are directed links between pages, with a kind. They turn a pile of pages into a graph.
Hybrid search
A query runs three ways at once and the results are fused with reciprocal-rank fusion:
- Lexical — the FTS5 index, with the query's tokens quoted and OR-joined.
- Vector — cosine similarity over the ANN index.
- Graph boost — the neighbors of the top few lexical hits get a partial score, so a page that never mentions your words but sits next to one that does still surfaces.
The vector half degrades silently: if embeddings are unavailable, you get lexical plus graph results rather than an error.
The Brain MCP tools
Brain exposes an MCP server so agents read and write memory through tools rather than files:
| Tool | Parameters |
|---|---|
brain_query | query (required), project_id, limit (default 10, max 50) |
brain_read_page | project_id, path (both required) |
brain_write_page | project_id, path, title, body (required), tier |
brain_recent | project_id, limit (default 20, max 100) |
brain_query returns both raw hits and a ready-to-paste context_block, which
is what makes it cheap for an agent to use at the start of a task.
Decisions
A decision record is a commitment with an audit trail. It carries a stable key,
a scope, a title, a rationale, structured constraints, evidence, links, a
version and an append-only event history.
Its lifecycle is explicit:
| Status | Meaning |
|---|---|
proposed | Filed, not in force. |
accepted | In force. Only one accepted decision may exist per project, key and scope. |
rejected | Declined. Can be reactivated. |
deprecated / superseded / withdrawn | No longer the live answer. |
Evidence attaches a kind, a summary, an optional URI and a content hash.
Links point a decision at a Brain page or at a task. Constraints are the
enforceable part — must, must not, prefer and numeric limit — and a
violation surfaces as a constraint-enforcement error rather than a silent pass.
Applicability
The point of a decision graph is that the right decisions reach the right run
without anyone remembering to paste them. decision_list_applicable filters
accepted, non-tombstoned decisions for a project by:
- task — decisions with no task link at all are global; decisions linked to a task apply only to that task.
- path — decisions with no page link are global; decisions with one apply to that path and anything beneath it. When no path is supplied, decisions carrying a page link are excluded rather than assumed relevant.
- stage — the decision's scope must match the stage, or be empty.
Each applicability query records a recall pulse, so you can see which decisions are actually reaching runs and which are dead weight.
The Decisions MCP tools
| Tool | What it does |
|---|---|
decision_propose | Create a proposed decision. Never auto-accepted. |
decision_get | One decision with constraints, evidence and links. |
decision_query | Text search across records. |
decision_add_evidence | Attach structured evidence. |
decision_link_memory | Link the decision to a Brain page. |
decision_list_applicable | The filtered set above, plus a recall pulse. |
decision_request_approval | Link a proposal to a task so the human Loop gates it. |
decision_events | The append-only history. |
The panel is the ◆ Decisions entry in the My Loop rail, badged with the number
of open proposals plus unresolved conflicts.
Recall
Recall is project-scoped working memory for agents: an incremental index of the project's code plus a per-task overlay, searched together with Brain.
File chunks. Every indexed file is split into overlapping line windows of
about 1800 characters. Files are skipped by directory (.git, node_modules,
target, dist, build, .next, .turbo, coverage, .venv, __pycache__,
.tde), by extension (images, archives, binaries, lockfiles) and by size.
Task overlay. Diffs, logs, agent summaries and extracted task attachments (PDF, DOCX, XLSX, XLS, ODS) are indexed against a task reference, so recall for a running task sees what that task has already done and the documents attached to it. Attachment text is chunked (about 1800 characters per row, capped per file) with a self-identifying header; re-attaching the same path replaces the previous chunks instead of duplicating them.
Incremental by content hash. A file whose SHA-256 is unchanged is skipped entirely. Scans are budgeted — a few hundred files per background slice, with cooperative pauses — and a filesystem watcher debounces live edits, with a periodic full reconcile in between.
Search adapts to the query. A literal string search skips vectors entirely, a symbol lookup weights them lightly, and a conceptual question weights them fully. Two extra indexes back partial identifiers: exploded camelCase/snake_case subtokens, and trigrams.
With a TDE Pass license, project chunks are also embedded (bge-m3) and the
fused candidate list can be re-ranked by the gateway. Task-overlay hits
participate in the same hybrid search and optional rerank; they stay lexical at
ingest because overlays are task-scoped and short-lived. Offline or without a
license, recall falls back to deterministic lexical search.
Only TDE's canonical clone at ~/.tde/repos/<name> is indexed — never your own
checkout — so the index is stable regardless of what you have open locally.
One pipeline, two doorways
Recall reaches an agent two ways: the pipeline injects it into the prompt before a
stage runs, and the MCP tools below let the agent ask for it directly. Both go
through the same hybrid search and the same ranking. A question asked either way
gets the same answer, and both cite file:start-end line ranges so the agent can
open the exact region rather than reading the file back in whole.
What the index is worth
The Recall panel reports a Context saved line per project:
Context saved 73% less to read · 41 KB of 152 KB · 12 recallsThe baseline is the full size of the files the snippets were drawn from — what an agent without an index would have had to open. It is counted in bytes rather than tokens on purpose: bytes are measured, tokens would be estimated, and an estimate presented as a saving is a number you cannot audit. When snippets overlap and exceed their source, the line reports zero rather than a negative saving.
The Recall MCP tools
| Tool | Parameters |
|---|---|
recall_search | query (required), scope (code, memory, all), limit (1–25, default 8) |
recall_context | query (required) |
Neither takes a project argument: both resolve the project and the task overlay
from the caller's working directory, matching the canonical clone, your imported
checkout, or a recorded task worktree. recall_context returns bounded markdown
— capped at 16,000 characters — with a ## Project code context section and a
## Project memory context section.
Recall's structural half
Recall answers what text is relevant. It does not answer what calls this function, and what breaks if I change it — that is the code graph, a separate structural index with its own CLI. See Code graph.
Use them together: recall to find the region, the graph to find the blast radius.