Source: https://velofy.co/trove/how-it-works/

[Trove](https://velofy.co/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.

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 ask` is 1,500 tokens; the default for `trove query` is 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

1.  **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.
2.  **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.
3.  **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.
4.  **Retrieve deterministically and offline.** Ranking is lexical: keyword overlap for `trove query` and Okapi Best Matching 25 (BM25) for `trove ask`. A language model is optional and only writes the final answer from sources that were already retrieved.
5.  **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](https://velofy.co/trove/project-trove/).

### 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](https://velofy.co/trove/indexing/).

### Retrieval: two paths for two questions

*   **`trove query`** walks 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](https://velofy.co/trove/retrieval/).
*   **`trove ask`** puts 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 a `file:line` citation each. It answers “where is the thing I am asking about”. See [Asking questions](https://velofy.co/trove/ask/).

### The redaction boundary

*   On write, `trove remember` runs the shared secret detectors and refuses the entry. The plugin’s `trove.sh guard` does the same for entries written by the skills.
*   Before a provider call, `trove ask` redacts 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 ship` redacts 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](https://velofy.co/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, `ask` finds 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. Use `trove ask` when 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 behind `trove remember`, `ask` and `ship`: 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 with `trove 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](https://velofy.co/trove/indexing/).
*   **Running from a subdirectory.** `index`, `status` and `query` use the current directory as the repository unless you pass `--repo`. Run in `src/`, `status` and `query` report no index and leave an empty `.trove/` there, and `index` indexes only `src/`. `ask` and `remember` search upward for the repository root. See [Troubleshooting and limits](https://velofy.co/trove/troubleshooting/).
*   **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; run `trove.sh guard <file>` to check sooner.
*   **A provider error.** `trove ask` falls back to the retrieved sources and prints the error in the footer.

## What follows for your setup

*   Commit `.claude/trove/`, `.claude/skills/` and `AGENTS.md`; keep `.trove/` out of Git.
*   Re-run `/trove:index` (or `trove index` plus `trove.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.
