From the 2026-08 security pass. Low severity, and the code already acknowledges it — filing so it's tracked as a server requirement rather than living only in a source comment.
Problem
The FTS sanitizers (sanitizeFts4Query/sanitizeFts5Query) cap query-grammar complexity (wildcards stripped, NEAR neutralized, paren depth capped) — but not query cost. A syntactically valid search over a large index can still be expensive, and both SQLite engines run synchronously in-process: sql.js is WASM that blocks the JS event loop, and native node:sqlite blocks the calling thread. sanitizeFts4Query's own doc comment states a timeout "is not implementable for a synchronous, in-process SQLite engine … out of scope here."
Fine at personal-stack scale (you're only DoSing yourself). On haverstack/server, one expensive search blocks every other request on that thread.
Direction (server-side, not a core code change)
Nothing to fix in the sanitizers — the mitigation belongs to whoever runs the engine under load:
- Run record-adapter queries off the request/event thread (worker thread per connection, or a worker pool), so a slow query can be interrupted via
sqlite3_interrupt / worker termination and can't stall the loop.
- Apply a per-request query timeout at that boundary.
- Consider a spec sentence under §Queries or the wire format: full-text search is best-effort on cost; a server SHOULD bound query execution time and MAY return a typed error (candidate: reuse
bad_request, or a new timeout code) when it does.
Work item
Cross-refs: security pass 2026-08; #72 (streaming/buffering — same "synchronous in-process engine under server load" theme); the auth/server RFCs #138/#139.
From the 2026-08 security pass. Low severity, and the code already acknowledges it — filing so it's tracked as a server requirement rather than living only in a source comment.
Problem
The FTS sanitizers (
sanitizeFts4Query/sanitizeFts5Query) cap query-grammar complexity (wildcards stripped, NEAR neutralized, paren depth capped) — but not query cost. A syntactically valid search over a large index can still be expensive, and both SQLite engines run synchronously in-process: sql.js is WASM that blocks the JS event loop, and nativenode:sqliteblocks the calling thread.sanitizeFts4Query's own doc comment states a timeout "is not implementable for a synchronous, in-process SQLite engine … out of scope here."Fine at personal-stack scale (you're only DoSing yourself). On
haverstack/server, one expensive search blocks every other request on that thread.Direction (server-side, not a core code change)
Nothing to fix in the sanitizers — the mitigation belongs to whoever runs the engine under load:
sqlite3_interrupt/ worker termination and can't stall the loop.bad_request, or a newtimeoutcode) when it does.Work item
Cross-refs: security pass 2026-08; #72 (streaming/buffering — same "synchronous in-process engine under server load" theme); the auth/server RFCs #138/#139.