Lossless Changelog
product

A search that admits it is still thinking

The results panel looked like it was answering. It was showing the previous answer — confidently, for several seconds.

Michael StatonMusic Editoraugmented with Claude Code on Claude Opus 5 (1M context)

A search that admits it is still thinking

Why Care?

The screenshot was meant to be a progress report. It was a bug report.

The new results panel had been driven, tested and shipped against a corpus with a search index, where a query is answered in under a tenth of a second. The operator opened it against reach-edu, which has no index, typed Grant Application, and photographed eight results that had nothing to do with grant applications.

Nothing was broken in the way bugs are usually broken. The panel was showing the rows it was already holding — the unfiltered list — because the actual search, which on an unindexed corpus reads all 832 files, had not come back yet. For several seconds it looked exactly like a finished search returning wrong answers.

That is the worst failure mode a search has. An empty result is honest. A slow result is tolerable. A confident wrong one costs the reader their trust in every correct result that follows.

What's New?

  • The panel says Searching… until this query's rows land.

  • Excerpts no longer repeat the title back at you.

  • Both were found in a single frame of a real corpus.

The panel now waits

The same search panel one keystroke into the query Grant Application, showing only the word Searching rather than any results, while the count line behind it still reads 832 sources

One flag, set on the keystroke and cleared by whichever request actually delivers the rows. What makes it correct rather than decorative is that a superseded request does not clear it: requests already carry a monotonic token so a stale answer is dropped, and the flag belongs to the newest query rather than to the last response to arrive.

Measured against reach-edu afterwards: at 400ms in, the panel reads Searching… and holds nothing. When it settles, Grant Application returns one result — Grant Application and Information | Truist Foundation — which is the right answer, and was never among the eight.

The underlying cost is the real story, and it is already fixed elsewhere: with a search index that query is one read instead of 832. The pending state is what keeps the app honest in the window before somebody runs corpora reindex, and on every corpus that never does.

An excerpt that repeated the title

The same frame showed every other card reading:

Zeffy | 100% Free Fundraising Software
Title: Zeffy | 100% Free Fundraising Software

A body captured before the fetcher's preamble parser existed still carries its Key: value header, and Title: <the title> clears the 40-character bar that is supposed to separate real prose from a stray caption. So the excerpt rule picked it, faithfully, and printed the title a second time directly beneath itself.

An excerpt that repeats the title is worse than no excerpt — it spends the one line that answers what is this on the answer already given above it. The rule now skips a known set of preamble keys.

An explicit set, not the Key: value shape, because prose does that too: "Education matters: here is why" is a sentence. The narrower rule is the one that cannot eat a real sentence, and a test asserts exactly that alongside the Jina case.

What it looks like working

The corpora search panel open under the search box for the query apprenticeship, showing 64 matches: each result is a headline such as Youth Apprenticeship Academy Launched with 4 Million in Support from Bloomberg Philanthropies, a two-line summary beneath it, and a magenta strategy tag reading Frontier Job Demand or Workforce Development

Sixty-four matches for apprenticeship, eight shown, each a headline, a summary that is now actually a summary, and the strategy it is filed under. The rest stay in the list below.

What the picture also shows

Two things visible here that this entry does not fix, recorded because a screenshot of real client data is the cheapest audit anybody gets:

Every result appears twice — Youth Apprenticeship Academy… under Frontier Job Demand and again under Workforce Development. A first draft of this entry called those duplicates and asked whether to merge them. They are not duplicates, and the question was wrong.

Each is a ~1.1KB pointer: the canonical source_uuid, status: metadata-only, the lede, and its own empty # Extracts skeleton, carrying the single domains: value that names the folder it sits in. The body is elsewhere — canonically in SurrealDB, which is why corpus_path is optional. A filing into a second strategy is a second usage, with its own annotations.

That is deliberate, and the reason is the product: a corpus that will get very large has to hand an agent a scoped set of sources when it drafts, because accuracy and attribution are the whole point. A source bearing on two strategies belongs in both scopes. The pointer is what makes that cheap.

Measured across reach-edu afterwards: 79 sources are filed in two or more folders, 126 extra pointers, one source in six. So a panel of eight really can be four sources — and the fix is not to merge anything but to group by source_uuid and show one row carrying every folder it is filed in, which turns the repetition into the scope information it actually is.

No highlighting. The terms are not marked because reach-edu has no search index; marking comes from the ranked path. The panel deliberately works without one — a surface that only appeared after somebody ran reindex would look broken rather than unindexed — but the difference is visible, and it is the clearest argument yet for indexing the corpus.

Under the hood

Neither bug was reachable from the test suite as written, and both were obvious within one second of a person looking at the surface.

The pending state is not something a unit test would have caught, because the tests run against a fixture where the answer arrives immediately — the race needs a slow backend to exist at all. The title-echo needed a real body from a real fetcher; every fixture in the suite has a clean one, because fixtures are written by people who know what the field means.

The standing practice here is that a browser drive comes before a human walk-through. This is the counterexample that keeps the second rung: the drive proved the buttons worked, on a corpus chosen because it made the drive fast. The corpus that made the drive convenient is the one that hid the bug.

What's Next

  • Index reach-edu. One read instead of 832 removes the window the pending state exists to cover, and turns these results ranked and highlighted.

  • Grouping results by source_uuid is available and deliberately not scheduled (operator, 2026-08-23). It would make one source filed in six strategies a single row carrying six tags. Flat markdown is fast and easy at this size, the fan-out is what makes a scoped read one list() call with no joins, and 126 extra pointers is ~140KB. Revisit if a fan-out ever makes a panel unreadable, not before.

  • Sources with no body still render with no summary at all. Honest, and thin.

  • changelog/2026-08-23_02.md — the manifest, Pagefind, and the panel itself

  • context-v/specs/Ranked-Search.md — the panel's contract

  • context-v/reminders/The-Sidecar-Port-Is-Adopted-Not-Owned.md — the other thing this session's screenshots exposed