Skip to content

fix: FTS query tokenization and daemon/foreground DB contention (v0.9.1) - #86

Merged
ashu17706 merged 3 commits into
mainfrom
release/v0.9.1
Aug 25, 2026
Merged

ashu17706 merged 3 commits into
mainfrom
release/v0.9.1

Conversation

@ashu17706

Copy link
Copy Markdown
Contributor
  • fix(db): let QMD own busy_timeout and WAL so cold-open DDL is protected
  • fix(search): tokenize FTS queries instead of interpolating them raw
  • chore(release): 0.9.1

createStore() runs the WAL migration and the FTS trigger DDL before it
returns, so the busy_timeout Smriti set on the returned handle arrived
after the only section that needed it. That DDL raced at bun:sqlite's
default of 0.

The daemon makes this reachable rather than theoretical: defaultFlushAgent
opens the store, ingests and closes it per flush, so a watching daemon
re-runs createStore() on every debounced change. flushChain serializes
flushes only within the daemon process, and there is no cross-process
lock, so any overlap with a foreground recall/embed/ingest failed on
contact with 'database is locked'.

Upstream moved busy_timeout and a retrying WAL migration into
openDatabase(), the only place that runs before the DDL. Bumps the qmd
submodule to that (155 commits, v2.1.0 -> v2.8.3).

Six concurrent cold opens on one fresh DB: 1/6 succeeded before, 6/6 after.

Claude-Session: https://claude.ai/code/session_01HWzCvpW1yLZD3SJTXEojvR
searchFiltered pushed the user's query straight into the FTS5 MATCH
expression, so punctuation was parsed as FTS5 grammar rather than as
text. 'smriti search node-llama-cpp' failed with 'no such column: llama'
and 'smriti search qmd 2.8.3' with 'fts5: syntax error near "."'.
Hyphenated names are everywhere in these transcripts, so this hit
ordinary queries, not edge cases.

buildMemoryFTS5Query had the matching defect on the recall path: it
stripped punctuation rather than splitting on it, collapsing '2026.4.10'
to '2026410' while the porter unicode61 tokenizer had indexed '2026',
'4' and '10'. Silent zero-hit rather than an error.

Both now split on the same boundaries the tokenizer uses and AND the
parts, so a query tokenizes the way the indexed text did. The builder is
exported and shared, and searchFiltered parenthesises the group so the
column filter binds to all of it.

Same class as QMD upstream #563, which does not reach Smriti because
these are Smriti's own query builders.

Claude-Session: https://claude.ai/code/session_01HWzCvpW1yLZD3SJTXEojvR
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Benchmark Scorecard (ci-small)

Bench Scorecard (ci-small)

threshold: 20.00%

metric baseline current (median) delta status
ingest_throughput_msgs_per_sec 1735.800 436.300 -74.86% WARN
ingest_p95_ms_per_session 6.960 25.584 +267.59% WARN
fts_p95_ms 0.410 0.696 +69.76% WARN
recall_p95_ms 0.436 0.981 +125.00% WARN

Summary: WARN (4 metrics)

v0.9.1 was already tagged on 2026-08-02 (pointing at eaf82b8), so the
next stable version is 0.9.2. Also realigns package.json, which the
auto-release job does not bump and which still read 0.9.0 at v0.9.1.

Claude-Session: https://claude.ai/code/session_01HWzCvpW1yLZD3SJTXEojvR
@ashu17706
ashu17706 merged commit bfc1fdb into main Aug 25, 2026
10 checks 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