perf: fast freshness checks, cross-index search, and tantivy 0.27

Merged
LE
2d ago
+3173-1014

Faster freshness checks and updates, end-to-end timing, safer MCP index roots, and cross-index search. Also upgrades tantivy to 0.27 to clear the new zstd advisories that fail cargo deny and cargo audit on master.

Freshness and vera update

  • Each indexed file gets a metadata stamp (size, mtime, ctime, inode; on Windows LastWriteTime, ChangeTime, volume serial, file index), stored in a new nullable file_hashes.file_stamp column. A matching stamp skips the read; anything else is read and hashed as before.
  • Stamps are captured before and after the read on the same handle, and are never stored when the file changed during the read, changed within 3 s of the read starting, looks binary, is reStructuredText (includes), or was deferred or failed.
  • Old indexes gain the column without a rebuild (best-effort, non-blocking backfill during freshness checks; read-only indexes still work). No index format bump.
  • Discovery walks directories in parallel and skips the binary sniff for files whose stamp matches.
  • vera update --verify ignores stamps and hashes every file.

--timing: search, grep and structural report index lookup, freshness, setup, search stages, output and the wall-clock total.

MCP index roots: the server and the repo argument resolve the nearest indexed ancestor instead of creating a nested index; auto-indexing refuses / and $HOME.

Cross-index search: vera search "q" --also <dir> (repeatable) and repos on MCP search_code, up to 8 indexes. Per-index rankings are merged by rank with a one-position head start for the primary (scores are not comparable across corpora). JSON adds repo, file_path stays repo-relative, markdown shows absolute paths for extra repos. Never auto-indexes, rejects git scopes, expands --deep queries once, and reports secondary failures as warnings. Single-repo output is byte-identical to master.

Dependencies: tantivy 0.26.2 -> 0.27.0 (zstd 0.13.3 -> 0.14.3, zstd-safe 8.2.0, zstd-sys 2.1.2, lru 0.18.5; drops the lru ignore in deny.toml). Index format and compression are unchanged; an index written by the previous build was searched, grepped and updated by the new build with identical search JSON for 5 queries. Tantivy's new Snowball stemmer stems 12 of 11,213 code words differently (for example "added" -> add instead of ad); release notes suggest vera index . for full consistency.

Benchmarks (51k-file keyword-only index of the Cargo registry, Ryzen 7 9800X3D, old and new binaries interleaved)

Measurementmasterthis PR
Warm CLI search483 ms197 ms
Cold CLI search7.9 s, 1034 MB read3.6 s, 278 MB read
First MCP search529 ms260 ms
update, no changes756 ms, 660 MB RSS130 ms, 77 MB
update, 10 changed945 ms217 ms
update, 1000 changed11.9 s, 1579 MB6.5 s, 789 MB
update, 5000 changed13.3 s12.3-12.5 s (index writes dominate)

Checks: fmt, clippy -D warnings, cargo test --workspace (1,700 passed), cargo doc -D warnings, cargo deny, cargo audit, cargo machete. The Windows stamp code was checked against windows-sys 0.61 definitions but not compiled locally; CI's Windows job runs clippy on vera-core, which compiles it.

Docs: README, both package READMEs, features, how-it-works, mcp, architecture, troubleshooting, configuration, query guide, skill files, CLI help, and v2.3.0 release notes.


Devin Review


Summary by cubic

Speeds up freshness checks during updates and searches, adds cross-index search, and upgrades tantivy to 0.27 to clear zstd advisories.

  • Records a per-file metadata stamp (size, mtimes, file identity) in a new nullable file_stamps column; unchanged files skip being read for both vera update and stale-index checks. Old indexes gain the column without a rebuild, and vera update --verify ignores stamps to hash every file.
  • Adds vera search "q" --also <dir> and an MCP repos argument to search up to 8 existing indexes. Per-index rankings are merged by rank with a one-position head start for the primary; deep-search expansion is prepared once from the primary, and an index with no deep hits returns an empty list instead of failing, so other indexes' results are kept. The search-store LRU is sized to the cross-index limit; nothing is ever auto-indexed, and single-repo output stays byte-identical to master.
  • --timing reports end-to-end phases for search, grep, and structural commands, including index opening measured separately.
  • MCP servers and repo arguments resolve the nearest indexed ancestor instead of creating a nested index; auto-indexing refuses / and $HOME.
  • Upgrades tantivy 0.26.2 → 0.27.0 (zstd 0.13.3 → 0.14.3), dropping the lru advisory ignore from deny.toml. Index format is unchanged; the new Snowball stemmer stems 12 words differently, so release notes suggest vera index . for full consistency.

Migration

  • No index rebuild required. To guarantee identical stemming on the new build, run vera index ..

Summary by CodeRabbit

  • New Features
    • Search up to eight indexed repositories in one CLI or MCP query, with repository information included in multi-repository results.
    • Use vera update --verify to hash every file rather than relying on recorded metadata.
  • Performance
    • File discovery and incremental updates can skip unnecessary work using parallel processing and file metadata.
  • Improvements
    • Timing reports now separate search and output stages for search, grep, and structural commands.
    • MCP searches can use an existing index from a repository or a directory inside it; MCP does not automatically index filesystem roots or home directories.