Skip to content

test(search): search-everywhere latency and qmd on local documents - #38

Merged
leemour merged 7 commits into
mainfrom
docs/search-everywhere-and-qmd
Oct 13, 2026
Merged

leemour merged 7 commits into
mainfrom
docs/search-everywhere-and-qmd

Conversation

@leemour

@leemour leemour commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Why

The 2026-10-12 field test (tg, memo and drive on a real project) raised two measurements. Both now live here, under the new rule that every measurement of a WireCat CLI lands in cli-testing and opens with why it was run.

What

  • performance/search/everywhere/: a bare search word now also looks in voice transcripts, file names and file text (feat(search): a bare word looks in transcripts, file names and file text cli-core#1025). At 100k messages, the first build cost ~270 ms per search, because it read every file name. A word index of file names brought this to 15–40 ms over message text alone. The script moves here from that PR.
  • performance/search/local-documents/: qmd 2.8.3 against memo and drive on the owner's notes and Drive documents, with 50 known-answer queries. drive finds only 2 of 15 paraphrases, typos and questions in its top 3; qmd's vectors find 11, and so does memo. qmd takes 10–25 s per one-shot query and needs 2.2 GB of models. Conclusion: give drive memo's search rather than adopt qmd. Totals only; the queries and per-query ranks stay in cli-private.
  • CLAUDE.md: a "Where results live" section. biome.json lets the new script print.
  • TOOL-RESEARCH.md and PROCESS.md link both pages.

Checks

pnpm lint and pnpm docs:check pass. No suite or src/ change.

🤖 Generated with Claude Code

everywhere/: what a bare word costs once it also looks in transcripts, file
names and file text (cli-messaging #1025), at 100k messages, on three builds.

local-documents/: qmd 2.8.3 against memo and drive on the owner's notes and
Drive documents, 50 known-answer queries. Totals only; queries and per-query
ranks stay in cli-private.

CLAUDE.md: every measurement of a WireCat CLI lands here, opening with why it
was run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
leemour added a commit to WireCatLabs/cli-core that referenced this pull request Oct 13, 2026
It lives at cli-testing performance/search/everywhere/ (WireCatLabs/cli-testing#38),
with the results and why it was run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… had none

The first run searched drive's documents by words alone: they were synced without --embed,
while search answered by: "words and meaning". After embedding, drive gets 0.68 first and
0.80 in the top 3 in 1.3 s; qmd's best is 0.56 and 0.80 in 11-25 s.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
leemour added a commit to WireCatLabs/cli-core that referenced this pull request Oct 13, 2026
…ext (#1025)

* fix(speech): make kept voice transcripts searchable, shown and reused

Transcripts were already kept in message_transcripts, but nothing else read
them: `messages show` did not show them, `content:` search never saw them,
and `messages transcribe` heard the message again every time.

- A kept transcript becomes the voice attachment's text (extractor
  `speech:<source>`), so `content:` and the file word index find it. A
  transcript made before its message was stored is copied when the message
  arrives; `store reindex` fills in transcripts kept before this change.
  Agent-written attachment text still wins.
- `messages show` and `messages context` read kept transcripts like
  `messages list` does.
- `messages transcribe` answers a kept transcript, and hears again only when
  a local model other than the one that heard it is asked for.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* wip: a bare search word looks in transcripts, file names and file text

Tests green; latency at 100k messages not measured yet, lint not re-checked.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(search): import MatchPlace through store.ts

Services reach the store through store.ts only (Biome noRestrictedImports).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* perf(search): find file names through a word index (store version 5)

A bare word read every stored file name into JavaScript on each search: at 100k
messages and 50k files a search took ~390 ms instead of ~120 ms, even with no
match. attachment_name_words is an FTS5 index kept by triggers and filled once
on upgrade. The triggers fold й and ё the way normalize() does, since unicode61
folds only Latin accents (owner, NEED-993 A).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(search): file names stored before version 5 are found; bench results

everywhere-results.md keeps the 100k-message latency of a bare word on three
builds: before #1025, names read in JS, and the name index.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(search): move the search-everywhere bench to cli-testing

It lives at cli-testing performance/search/everywhere/ (WireCatLabs/cli-testing#38),
with the results and why it was run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs(search): help names transcript: beside content: and filename:; regenerate the field table

The search help #1015 added named content: and filename: only. A bare word now looks in four places,
so messages' help says so and lists the four fields; search all's help names transcript: too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(search): content: no longer claims voice transcripts in the field table

Merging main brought back #1010's wording, since the squash of #1010 left the merge base behind it. A merge
with the squash commit as its base gives this file exactly; the rest of the tree already matched.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs(changelog): keep the search-everywhere and store version 5 entries the merge dropped

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs(changelog): restore the search-everywhere, store version 5 and sheet rows entries

Merging main dropped them again; #1016 reached main without its entry, so it is added back here.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
leemour and others added 5 commits October 13, 2026 17:54
… limits of both

Adds to the local-documents page: a side-by-side of the two pipelines (stemming,
vector model, fusion, qmd's query expansion and reranker), why memo and drive
put the right document first more often while qmd's hybrid wins on paraphrases,
what reranking we already have (a rule reranker in message search, a measured but
unshipped cross-encoder) and what is worth taking from qmd. "Not measured"
becomes "Limits of this test" with the size, labelling and model caveats.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…wen3 over memo and drive

mmarco lifts memo's notes from 0.72 to 0.84 first place and every paraphrase into
the top 3 at ~2 s a query in a warm process; on the Drive documents the gain is
within noise. Qwen3 (qmd's) is no better and three times slower. Scripts run
read-only against the CLIs and keep the owner's data outside the repository.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…f the reranker run

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ded; rerank none

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@leemour
leemour merged commit 6a9aee5 into main Oct 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant