Skip to content
VelofyTrove

Trove / Guides

Asking questions

How trove ask searches troves, repository docs, the code index and installed tools, ranks and cites hits within a token budget, and adds an optional answer.

On this page
  1. First principles
  2. Which repository
  3. Sources
  4. Ranking
  5. The budget
  6. Reading the output
  7. Written answers
  8. What is sent, and what is not
  9. The interactive prompt
  10. Getting better results

trove ask answers a question with ranked, cited sources from everything Trove can see. It runs offline by default. A written answer from a language model is opt-in, and it only ever sees the sources that were already retrieved, with secrets removed.

trove ask "how does the retrieval budget work"
trove ask --json "where is the tool catalog cached"
trove ask --budget 400 "freshness"

First principles

The answer to a question about a codebase can live in very different places: a decision someone wrote down, a section of the README, a function signature, or the man page of a tool installed on the machine. Searching each place separately means the agent has to decide where to look before it knows the answer.

So ask puts every source into one corpus and scores all of them with one function. The best evidence wins whatever its kind, with small priors that trust curated notes a little more than generated summaries. Each hit carries a file:line citation, so the agent or you can open the exact place. Hits are then packed into a token budget, because a short list of the right lines is worth more to an agent than a long list it has to skim. A language model, when you ask for one, sees only those packed sources and is told to answer from them and cite them.

Which repository

With --repo, that folder is the repository. Without it, ask starts in the current directory and walks up to the nearest folder that holds a .trove/ directory or .git. So trove ask works from any subdirectory. (index, status and query do not search upward.)

Sources

  • personal: entries of your personal trove, ~/.claude/trove, flat or sectioned.
  • project: entries of the repository’s project trove, <repo>/.claude/trove, including the conventions/, memory/ and context/ sections.
  • doc: Markdown files at the repository root and under docs/ (up to three folders deep), split at every heading outside code blocks so each section is its own source. Files over 256 kilobytes and names that start with a dot are skipped.
  • symbol, module, subsystem, arch: the engine index in .trove/. Imports, variables and symbols with an empty name are left out, and mod declarations rank lower. If the repository has not been indexed, a footer line says there is no engine index and suggests running trove index.
  • tool: the installed tool catalog, the same one trove tools uses. --no-tools leaves it out. The first run builds the catalog; later runs reuse its cache. See Tool catalog.

Ranking

Text is split into lowercase word tokens. camelCase and PascalCase identifiers also yield their parts, snake_case splits on the underscore, simple plurals are folded (entries matches entry), and common words such as “the”, “how” and “use” are dropped.

Each source is scored with Okapi Best Matching 25 (BM25), with these additions:

  • A query term that appears in the source’s title adds extra weight.
  • The score is scaled by coverage, the share of query terms the source contains, so a source matching every term beats one matching a single term many times.
  • A prior per kind: personal and project entries 1.25, docs 1.1, architecture, subsystem and module summaries 1.0, symbols 0.9, tools 0.6.

From the ranked list, ask keeps at most --limit hits (default 12), at most 6 of any one kind and at most 3 tools, so one kind cannot crowd out the rest.

The budget

--budget sets the token budget, 1,500 by default. A token is estimated as four bytes of text. Hits are kept in rank order while they fit; a hit that does not fit is skipped and smaller hits after it may still fit. The top hit is always kept, so a tiny budget still answers something.

What a hit costs depends on the mode:

  • Retrieval only: the citation, title and matched line, which is what gets printed.
  • With a provider: an excerpt of up to 1,600 characters of the source text, which is what gets sent.

Reading the output

 1 project   .claude/trove/memory/entries/wal-gotcha-bulk-inserts.md:9  WAL gotcha: bulk inserts
   Bulk inserts must run inside one transaction, or WAL replay splits them.
 2 module    src/bulk-insert.js
   - runBulkInsert (function)
 3 symbol    src/bulk-insert.js:2  runBulkInsert
   function runBulkInsert(client, rows) {
-- 3 of 7 matches | ~84/1500 tokens | offline retrieval; add --provider for a written answer

That is trove ask --no-tools --limit 3 "why do bulk inserts need a transaction" in a small sample repository with a project trove.

  • Each hit shows its rank, kind, citation and title, then the line with the most query terms.
  • The footer shows how many hits were printed out of how many sources matched at least one term, the estimated tokens used out of the budget, and the mode.
  • With no match it prints no matches for "<question>" in <n> sources.

With --json, the same result comes back as one JavaScript Object Notation (JSON) object with query, mode (retrieval or llm), sources (each with kind, cite, title, snippet and score), tokens, budget, matches and searched, plus provider, answer, answer_error, notes and redaction when they apply. In JSON the architecture kind is spelled architecture.

Written answers

Retrieval never needs a model. To get a written answer that cites the sources as [n], choose a provider:

  • none (default): retrieval only, fully offline.
  • anthropic: the Anthropic Messages application programming interface (API). Needs ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN; ANTHROPIC_BASE_URL changes the endpoint. The model defaults to claude-opus-5-5; change it with --model.
  • ollama: a local Ollama server at OLLAMA_HOST (default http://localhost:11434), with the model from --model, then OLLAMA_MODEL, then llama3.2.
  • cmd: any command that reads the prompt on standard input and prints the answer. The command is TROVE_LLM_CMD, default claude -p. With --model, the command also gets TROVE_MODEL in its environment.
trove ask --provider anthropic "why do bulk inserts need a transaction"
trove ask --provider cmd "where is the retry logic"     # runs claude -p

TROVE_PROVIDER and TROVE_MODEL set defaults for --provider and --model. Requests to Anthropic and Ollama go through the system curl, with a 300-second timeout. API keys reach curl on standard input, never on its command line, and the request body goes through a private temporary file that is deleted afterwards.

What is sent, and what is not

Before any provider call, the prompt (the question plus the packed excerpts) is redacted:

  • Secrets are always replaced with placeholders such as [REDACTED:secret-1]. There is no option to turn this off.
  • Other private categories (emails, phone numbers, internal hosts, Internet Protocol (IP) addresses, local paths and customer names) are replaced too. --no-redact-nonsecret keeps those, never secrets.
  • The redacted prompt is scanned again. If a secret-shaped string survives, nothing is sent and the result falls back to retrieval only.

The footer then reports what was removed, for example -- redacted before send: 3 (1 email, 2 secret), and --json adds a redaction object with total and by_category.

If the provider fails (no key, no server, a refusal, an empty reply), ask still prints the sources and shows the error in the footer, for example retrieval only (set ANTHROPIC_API_KEY (or ANTHROPIC_AUTH_TOKEN) to use --provider anthropic).

The interactive prompt

Run trove with no arguments to open a prompt that loads the sources once and answers each line you type:

trove: ask anything about /path/to/repo
-- 6 project, 5 doc, 1 arch, 2 subsystem, 20 module, 10 symbol, 1925 tool | :help for commands
trove> where is the tool catalog cached

The counts line lists how many sources of each kind were loaded. Commands:

  • <question>: ask.
  • :tools <terms>: search installed tools. :tool <name>: describe one.
  • :json: toggle JSON output.
  • :budget <tokens>: set the budget.
  • :provider <name>: none, anthropic, ollama or cmd.
  • :reload: reload the sources, for example after trove index or new entries.
  • :help, and :quit or Ctrl-D to exit.

When standard input is not a terminal, the prompt prints no banner and reads questions line by line, so you can pipe questions in.

Getting better results

  • Use the words the code uses. Ranking is lexical, so “rate limit” finds rate-limit.js and “throttle” does not.
  • Run trove index first. Without the engine index, symbols and modules are missing.
  • Name things in your entries. An entry that mentions fetchWithRetry and src/retry.js is found by either.
  • Raise --limit or --budget when the footer shows many more matches than hits.