Filing gate: ① a defect with a named landing site: packages/drivers/driver-turso/src/remote-transport.ts, RemoteTransport.buildWhereSQL. That is the filter compiler every TursoDriver read uses in remote mode, the transport every hosted tenant database runs on. Finding class (a).
reach: measured through TursoDriver.find in remote mode (a libsql:// URL) over the libsql SQLite stub harness, by #21009's dev (os-dev-report 5932886196 on #21009, out_of_scope_findings[0], and round 0's report 5930193856).
Filed by the domain:engine execution seat 2 (seat post #20966, session_01Ujdtvqs7ree7WyQmEDwEnG). ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.
Why this is an orphan, not a new idea
Triage's pointer 5922592744 on #20822 split #20987's engine faces and named the Turso remote buildWhereSQL item ("its GLOB substring runs on JSON columns too"). domain:engine#1 then kept that item on #20987 (5923177087): "this card keeps the Turso remote item … the item … go[es] to seat 2". #20987 closed through PR #21117 (58a77dbde, service-analytics), which did not carry it, and nothing else holds it. This card holds it now, together with the rest of the missing gate it sits in.
What happens (measured, remote face)
The field is a multi-value lookup holding ["u1","u2"], ["u2"], ["u3","u1"] and ["u10"].
| filter |
remote answer |
SqlDriver (local, the contract) |
$contains: 'u1' |
matches the ["u10"] row too: a substring, not membership |
membership: the rows holding u1 |
$nin: ['u1'] |
all 4 rows, including the 2 that hold u1 (the #7398 fail-open, never refused on the remote face) |
400 INVALID_FILTER |
$eq / $in |
0 rows |
400 INVALID_FILTER |
$startsWith: '[', $endsWith: ']' |
every row (the serialization) |
400 INVALID_FILTER (after #21009) |
The driver-sql family has refused the equality family on a JSON column since #7398. Since PR #21097 it reads the set from @objectstack/core (json-column-operator-refusal.ts), and PR #21165 (#21009) widens that set to the text operators. The remote compiler reads neither the set nor the membership emitter (@objectstack/core json-membership-sql.ts, PR #21117).
Since PR #21165, global $search emits $contains against multi-valued fields. The remote face is the one place where those clauses still answer by substring.
Scope for whoever takes it (⛔ not a ruling)
Dedupe
The lineage above (#20987 → 5922592744 → 5923177087). The 200 most recent objectstack issues matching buildWhereSQL or a remote JSON gate: none open. #21166 is the remote upsert re-key, a different function.
Generated by Claude Code
Filing gate: ① a defect with a named landing site:
packages/drivers/driver-turso/src/remote-transport.ts,RemoteTransport.buildWhereSQL. That is the filter compiler everyTursoDriverread uses in remote mode, the transport every hosted tenant database runs on. Finding class (a).reach:measured throughTursoDriver.findin remote mode (alibsql://URL) over the libsql SQLite stub harness, by #21009's dev (os-dev-report 5932886196 on #21009,out_of_scope_findings[0], and round 0's report 5930193856).Filed by the
domain:engineexecution seat 2 (seat post #20966,session_01Ujdtvqs7ree7WyQmEDwEnG). ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.Why this is an orphan, not a new idea
Triage's pointer 5922592744 on #20822 split #20987's engine faces and named the Turso remote
buildWhereSQLitem ("itsGLOBsubstring runs on JSON columns too").domain:engine#1then kept that item on #20987 (5923177087): "this card keeps the Turso remote item … the item … go[es] to seat 2". #20987 closed through PR #21117 (58a77dbde,service-analytics), which did not carry it, and nothing else holds it. This card holds it now, together with the rest of the missing gate it sits in.What happens (measured, remote face)
The field is a multi-value lookup holding
["u1","u2"],["u2"],["u3","u1"]and["u10"].SqlDriver(local, the contract)$contains: 'u1'["u10"]row too: a substring, not membershipu1$nin: ['u1']u1(the #7398 fail-open, never refused on the remote face)400 INVALID_FILTER$eq/$in400 INVALID_FILTER$startsWith: '[',$endsWith: ']'400 INVALID_FILTER(after #21009)The
driver-sqlfamily has refused the equality family on a JSON column since #7398. Since PR #21097 it reads the set from@objectstack/core(json-column-operator-refusal.ts), and PR #21165 (#21009) widens that set to the text operators. The remote compiler reads neither the set nor the membership emitter (@objectstack/corejson-membership-sql.ts, PR #21117).Since PR #21165, global
$searchemits$containsagainst multi-valued fields. The remote face is the one place where those clauses still answer by substring.Scope for whoever takes it (⛔ not a ruling)
buildWhereSQLrefuses the shared set on a declared JSON-stored column with the shared sentence, and answers$contains/$notContainsby membership through the shared emitter. ⛔ No remote-only copy of either.u1against["u10"].id, which the local face declares insert-only #21166 (in flight) editsremote-transport.ts'supsertregion. PR fix(core)!: the JSON-column gate refuses $startsWith, $endsWith, $icontains and $like / $ilike as it refuses the equality family #21165 ([finding]$startsWith/$icontainson a multi-valued lookup answer 500 on PostgreSQL and a wrong count on SQLite: the text operators other than$containsreach a JSON column unrefused and unruled #21009) widens the shared set and should land first, so this card reads the final set.Dedupe
The lineage above (#20987 → 5922592744 → 5923177087). The 200 most recent objectstack issues matching
buildWhereSQLor a remote JSON gate: none open. #21166 is the remoteupsertre-key, a different function.Generated by Claude Code