Trove / Get started
How it works
Trove from first principles: what a coding agent forgets, the constraints that follow, how files, layers and budgets answer them, and where it breaks.
On this page
This page explains why Trove is built the way it is. It starts from what a coding agent lacks at the start of a session and follows the consequences through the design. The guides cover how to use each part; this page covers why each part exists. Numbers on this page are defaults in the current source or results from the repository’s own evaluation in evals/BASELINE.md.
The problem
A coding agent works through a context window: a fixed number of tokens it can read at once. Everything outside that window does not exist for it. Two kinds of knowledge are missing every time a session starts:
- Structure. What is in this repository and where it lives. This can be re-derived from the code, but only by reading files, and every file read spends tokens that the task itself needed.
- History. What the team decided and why, which conventions hold here, which traps already caught someone. This cannot be re-derived from the code at all. It lived in a person’s head, a pull request (PR) thread or a chat that ended.
Without help, an agent rediscovers structure at full price each session and never learns history.
The constraints
- Tokens are scarce. Tokens spent on orientation are not spent on the change. The default budget for
trove askis 1,500 tokens; the default fortrove queryis 200,000. - Sessions start cold. Nothing carries over unless it is on disk and something loads it.
- Agents differ. Claude Code has skills and hooks. Other agents, such as Codex, Cursor and pi, load context in their own ways, but every one of them can read a Markdown file in the repository.
- Code is often private. Retrieval has to work on the machine, without a network. Anything that does leave the machine has to be stripped of secrets first.
- Knowledge goes stale. Files move, decisions get reversed, a gotcha gets fixed.
- People paste secrets into notes. A memory that is committed to Git or sent to a model provider must refuse them.
What follows from them
- Store memory as plain files, one fact per file, with a one-line index. Files are diffable, reviewable in a PR and readable by any agent. The index is small enough to load every session; full entries are opened only when they matter.
- Load the cheap part automatically and the rest on intent. A SessionStart hook prints the indexes. A project trove is rendered into three skills whose descriptions name the situations they help with, so Claude Code loads one only when the task calls for it.
- Index code once, into layers that get smaller as they get broader. Symbols, then one summary per file, then subsystems, then one architecture summary. Retrieval starts at the top and adds detail only while a budget allows.
- Retrieve deterministically and offline. Ranking is lexical: keyword overlap for
trove queryand Okapi Best Matching 25 (BM25) fortrove ask. A language model is optional and only writes the final answer from sources that were already retrieved. - Guard every boundary. Secrets are refused when an entry is written, redacted before a prompt leaves the machine, and checked again before handoff docs are written, where a surviving secret stops the run.
The rest of this page is those five rules turned into code.
The mechanism
your notes your code
| |
trove remember / skills trove index
| |
.claude/trove/ ~/.claude/trove .trove/ (symbols, modules,
(one file per fact + INDEX.md) subsystems, architecture, graph)
| | |
+------+-------+--------+---------+
| |
SessionStart hook, trove ask (ranks every source together)
rendered skills trove query (walks the layers top-down)
| |
the agent's context window, within a token budget
Memory: one fact per file
An entry is a Markdown file with front matter (title, slug, type, created, tags) or a JavaScript Object Notation (JSON) file with the same fields plus data. Each INDEX.md holds one line per entry, newest first, below a <!-- entries below --> marker. One fact per file keeps entries small enough to update or delete without touching others, and the slug doubles as the deduplication key: trove remember refuses a slug that already exists unless you pass --update.
There are two places memory lives. The personal trove at ~/.claude/trove follows you across projects and has a flat entries/ folder. A project trove at <repo>/.claude/trove lives in the repository and is split into three sections, because an agent needs different knowledge at different moments:
conventions/: how code is written here. Needed when writing or reviewing code.memory/: what was decided or learned, and why. Needed when changing behavior or debugging.context/: where things live. Needed when orienting. Most of it is generated from the engine index.
Each section is rendered into .claude/skills/<project>-<section>/SKILL.md, and an AGENTS.md block points other agents at the same files. See Project troves.
Structure: layers that shrink as they widen
trove index parses source with tree-sitter and writes four layers into .trove/:
- L1 symbols: functions, classes, structs and similar, with a signature line.
- L2 modules: one summary per text file: symbol counts, exports, imports and flags such as network or database access.
- L3 subsystems: files grouped by their top-level folder.
- L4 architecture: one summary of the whole repository.
Each layer costs fewer tokens than the one below it, so the top of the stack fits any budget. Summaries are built by fixed rules, not by a model, so the same code always produces the same summaries. See Indexing a repository.
Retrieval: two paths for two questions
trove querywalks the layers in a fixed order (architecture, subsystems, modules, symbols, then imported trove entries) and stops each step when its share of the budget is used. It answers “give me an orientation for this task”. See Retrieval levels.trove askputs every source into one corpus (personal and project entries, repository Markdown split by heading, the engine index and the installed tool catalog), ranks them together with BM25, and packs the best hits into the budget with afile:linecitation each. It answers “where is the thing I am asking about”. See Asking questions.
The redaction boundary
- On write,
trove rememberruns the shared secret detectors and refuses the entry. The plugin’strove.sh guarddoes the same for entries written by the skills. - Before a provider call,
trove askredacts secrets (always) and other private categories (by default) from the prompt, scans the result again and sends nothing if a secret survived. - Before handoff docs are written,
trove shipredacts every document, renders the output, and scans the exact bytes about to be written. A surviving high-confidence secret stops the run with exit code 2 and nothing is written. See Handoff docs with trove ship.
Trade-offs
- Rule-based summaries instead of model summaries. They are free, offline and repeatable, but shallow: a module summary lists names and flags; it does not explain intent.
- Lexical ranking instead of embeddings. It is fast (the 16-query evaluation, over a 46-source fixture, runs in about 14 milliseconds for
ask) and needs no model, but it misses synonyms. In the baseline,askfinds the expected item in its top five for every exact-term and symbol query, for half of the synonym queries, and for three of four “why” questions. - Level-ordered output for
trove query. Orientation always comes first, but imported trove entries come last: in the baseline they land at ranks 12 to 15. Usetrove askwhen you want the best match first. - Files instead of a database. Easy to share, review and edit by hand. There is no locking, and structure is a convention that the tools follow rather than a schema anything enforces.
- Small skills. A rendered skill inlines entries until it reaches about 24 kilobytes, then lists the rest by path. Context stays small; older entries need one more read.
- Two implementations of the guard. The Bash
trove.sh guard, which the skills run, checks fewer shapes than the Rust detectors behindtrove remember,askandship: known token prefixes, private keys and secret assignments. The Rust set also catches bearer tokens, passwords inside web addresses, Stripe and SendGrid keys and high-entropy strings, among others. An entry written by a skill therefore gets a narrower check than one written withtrove remember.
Failure modes
- Stale memory. An entry reflects what was true when it was written. The recall skill and the memory skill both tell the agent to check that named files and commands still exist. Generated context entries are rebuilt on
/trove:index. - Full rebuilds on every index run. The incremental check compares a stored summary hash with a file content hash, which never match, so every file is rebuilt every time. See Indexing a repository.
- Running from a subdirectory.
index,statusandqueryuse the current directory as the repository unless you pass--repo. Run insrc/,statusandqueryreport no index and leave an empty.trove/there, andindexindexes onlysrc/.askandremembersearch upward for the repository root. See Troubleshooting and limits. - Words that do not appear in the source. Lexical ranking cannot match “throttle” to a file that only says “rate limit”. Rephrase with the identifiers the code uses.
- A secret in a hand-edited entry. Nothing scans a file you edit by hand until it is rendered, sent with
ask --provider, or shipped. Each of those steps redacts or refuses it; runtrove.sh guard <file>to check sooner. - A provider error.
trove askfalls back to the retrieved sources and prints the error in the footer.
What follows for your setup
- Commit
.claude/trove/,.claude/skills/andAGENTS.md; keep.trove/out of Git. - Re-run
/trove:index(ortrove indexplustrove.sh context) after structural changes, so the context section matches the code. - Write entries that name the identifiers and files they are about. That is what lexical retrieval matches on.