Found during the #4371 call-site survey (checking what reaches engine.find unfolded).
packages/runtime/src/action-execution.ts — the action === 'query' || action === 'find' branch:
- Protocol path (normal):
params.query (or the params rest) goes to protocol.findData — where/sort/limit/select all honoured. - ql fallback path (when the protocol service is unavailable):
ql.find(params.object, qlOpts) where qlOpts is only { context }. The caller's query never leaves the function — no where, no orderBy, no limit — and the response is an ordinary-looking { records, total } of the ENTIRE table.
The get/update/delete fallbacks in the same function all build a proper findOpts({ where: ... }); query is the only verb whose fallback forgets the request. Degraded-mode reads silently return more than was asked — the #4226/#4371 'rows are all there and all real' failure shape, plus an unbounded scan on large tables.
Fix sketch: thread the same query the protocol path builds into the ql fallback (fold/lower as needed — the bag may carry wire spellings like sort, which engine.find now rejects per #4371, so the fallback must lower them or reuse the protocol normalizer), or refuse loudly (503) instead of answering with the wrong result set. Refusing may be the honest option: a fallback that cannot reproduce the query's semantics should not pretend to serve it (AGENTS.md route-ownership rule 3: absence must be loud).
Refs #4371, #4226, AGENTS.md PD #10.
Found during the #4371 call-site survey (checking what reaches
engine.findunfolded).packages/runtime/src/action-execution.ts— theaction === 'query' || action === 'find'branch:params.query(or the params rest) goes toprotocol.findData— where/sort/limit/select all honoured.ql.find(params.object, qlOpts)whereqlOptsis only{ context }. The caller's query never leaves the function — nowhere, noorderBy, nolimit— and the response is an ordinary-looking{ records, total }of the ENTIRE table.The
get/update/deletefallbacks in the same function all build a properfindOpts({ where: ... });queryis the only verb whose fallback forgets the request. Degraded-mode reads silently return more than was asked — the #4226/#4371 'rows are all there and all real' failure shape, plus an unbounded scan on large tables.Fix sketch: thread the same
querythe protocol path builds into the ql fallback (fold/lower as needed — the bag may carry wire spellings likesort, whichengine.findnow rejects per #4371, so the fallback must lower them or reuse the protocol normalizer), or refuse loudly (503) instead of answering with the wrong result set. Refusing may be the honest option: a fallback that cannot reproduce the query's semantics should not pretend to serve it (AGENTS.md route-ownership rule 3: absence must be loud).Refs #4371, #4226, AGENTS.md PD #10.