CodeNomad/docs
Pascal André 8e8ea0653e
fix(history): search recent history first, cover more of it and search further back (#1182)
## Summary

Follow-up to #1161 and #1164. In a large project, the ranked project
search covered only the **oldest** messages: the scan walked rowids
upward under a 1.5 s budget, so recent conversations were never reached,
and identical searches covered 5,000 to 7,000 messages depending on
load. Each 1,000-row statement also sorted and evaluated its whole chunk
before returning its first row, blocking the daemon for about 70 ms at a
time.

- **Newest first:**
- The scan streams 128-row ranges from an O(1) horizon, without a
temporary sort.
  - It covers a deterministic window of the 16,384 most recent messages.
- **Cheaper per row:**
- A necessary UTF-8 byte check on the raw row rejects messages that
cannot contain a query term before any JSON is decoded.
  - Only possible matches pay for the exact readable-text mask.
  - The existing time, candidate, session and judge guards remain.
- **40 results** in the project search window; the agent tool keeps 10
by default and 20 at most.
- **Search further back:**
- When older history remains, it ranks the next older window for the
same query and options through an authenticated per-location
continuation.
- The continuation is bound to scope, query, options and the original
horizon, so later appends never enter it.
- Older windows replace the list, because ranking scores are
window-local.
  - The coverage note names the examined range in all ten locales.
- Query, scope or option changes, closing and leaving the session reset
it.
- The conversation scope is unchanged.

## Measurements (synthetic 40,000-message corpus, `node
scripts/benchmark-ranked-history.mjs 681b85486`)

| Metric | Before | After |
|---|---:|---:|
| Messages scanned | 19,001–22,001, oldest first | 16,384 each run,
newest first |
| Scan duration | 1,503–1,550 ms | 650–739 ms |
| First-row latency | 50–76 ms | 0.8–1.8 ms |
| Longest synchronous step | 70–82 ms | 1.4–1.9 ms |
| Rows fully decoded | 30,000–34,500 | 3,276 |

## Validation

- Superset property checks against the exact mask: 12,547 cases,
including Unicode case crossings, escapes and surrogate pairs.
- Deterministic coverage and streaming latency regressions.
- Cursor tampering, binding and excluded appends; store lifecycle.
- Session-pruning and history routes 155/155; native bundle 1/1; UI unit
44/44.
- Browser: history 3/3; search-highlight 12, plus 1 optional benchmark
skipped.
- Help 9/9; both typechecks.
- Isolated native history fixture on OpenCode 2.2.0: 26 checks.

Oversized file touched: `message-section.tsx` (~1,823 lines).
2026-10-28 19:26:40 +01:00
..
features/wake-lock fix(wake-lock): allow display sleep during active work 2026-04-21 20:58:40 +01:00
guides build: ship the Linux deb from Electron and the Windows installer without a ZIP (#955) 2026-10-14 16:45:49 +02:00
help fix(history): search recent history first, cover more of it and search further back (#1182) 2026-10-28 19:26:40 +01:00
screenshots docs: refresh README and workspace screenshot for 0.20 (#782) 2026-09-26 04:13:30 +02:00