perf: fast freshness checks, cross-index search, and tantivy 0.27
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_stampcolumn. 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 --verifyignores 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)
| Measurement | master | this PR |
|---|---|---|
| Warm CLI search | 483 ms | 197 ms |
| Cold CLI search | 7.9 s, 1034 MB read | 3.6 s, 278 MB read |
| First MCP search | 529 ms | 260 ms |
update, no changes | 756 ms, 660 MB RSS | 130 ms, 77 MB |
update, 10 changed | 945 ms | 217 ms |
update, 1000 changed | 11.9 s, 1579 MB | 6.5 s, 789 MB |
update, 5000 changed | 13.3 s | 12.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.
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_stampscolumn; unchanged files skip being read for bothvera updateand stale-index checks. Old indexes gain the column without a rebuild, andvera update --verifyignores stamps to hash every file. - Adds
vera search "q" --also <dir>and an MCPreposargument 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. --timingreports end-to-end phases for search, grep, and structural commands, including index opening measured separately.- MCP servers and
repoarguments 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 suggestvera 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 --verifyto 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.