Repository navigation
[finding] driver-sql's JSON-column refusal is about 800 characters and is cut at the REST envelope's 500, so no caller reads the sentence saying the field and operator were withheld #21067
Description
Activity
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsTriage: first grade —
bug·priority:p2·domain:engine·area:api·pm:blocked. Size the sentence under the envelope's bound, after #21007 moves itTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-01T06:11Z. ⛔ Not a claim, ⛔ not a dispatch.Blocked-by: #21007
Why p2. It is the precedent's grade (#20869, the same class, p2). The caller never reads the remedy or the "withheld" disclosure.
Why blocked. #21007 (open, dispatched; read at this write) moves the sentence byte-identically into its shared home. One edit there serves the
wheredoor and the per-aggregation position.Direction. It is the card's own scope, confirmed: the public sentence fits under
CLIENT_MESSAGE_MAX, with the remedy and the "withheld" disclosure inside the bound. Pin: the wire message is under the bound and carries the remedy spelling, on SQLite and PostgreSQL.
Generated by Claude Code
- addedarea:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsThe API a customer can call, and integrations — REST, connectors, webhooks, jobsbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3and removed
on Oct 1, 2026 objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsUnlocked:
pm:blocked→pm:queue— #21007 closed as completeddomain:engine#2(seat post #20966; runs the lane queue by the maintainer's order recorded on #6367) ·session_01Ujdtvqs7ree7WyQmEDwEnG· 2026-10-01T08:26Z. ⛔ Not a claim.- The condition: triage's transition 5925795692 blocked this card on [finding] a per-aggregation
filter$ninon a multi-valued field counts the rows it was asked to exclude, and$incounts none, where the samewhereis refused 400: the aggregation evaluator has no JSON-column equality gate #21007 (Blocked-by: #21007). [finding] a per-aggregationfilter$ninon a multi-valued field counts the rows it was asked to exclude, and$incounts none, where the samewhereis refused 400: the aggregation evaluator has no JSON-column equality gate #21007 is closed as completed: PR fix(objectql)!: a per-aggregation filter refuses a scalar comparison on a declared JSON-stored field, in where's words #21097 merged asa11faeecb(landed record 5927642384). - The double check: the newest transition is 5925795692, and no PR has merged on this card since. Re-derived: no new blocker is named on the thread.
- What the dispatch reads first: the shared home now exists on
mainaspackages/core/src/utils/json-column-operator-refusal.ts(the refused setJSON_COLUMN_INCOMPATIBLE_OPERATORSand the sentence builder). The dispatch re-verifies the premise againstmainas it stands then.
Generated by Claude Code
- The condition: triage's transition 5925795692 blocked this card on [finding] a per-aggregation
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsCarried note from
domain:engine#2: the shared sentence's mechanism clause isdriver-sql's, and two more faces now print itdomain:engine#2(seat post #20966) ·session_01Ujdtvqs7ree7WyQmEDwEnG· 2026-10-01T10:57Z. ⛔ Not a claim. The card stayspm:queue, serial behind #21009 (the same module).- From [finding] driver-memory answers the equality and ordering family per element on a multi-valued field (
$eq/$in/$nin/$gton amultiple: truelookup), where driver-sql refuses all ten with 400 INVALID_FILTER #21066's os-dev-report 5929893869,out_of_scope_findings[2]:jsonColumnOperatorRefusalText(@objectstack/corejson-column-operator-refusal.ts) explains the refusal withdriver-sql's mechanism ("a field this driver stores as a JSON TEXT column", "$in/$eqmatched nothing"). PR fix(objectql)!: a per-aggregation filter refuses a scalar comparison on a declared JSON-stored field, in where's words #21097 shipped it to objectql's per-aggregation face, and PR fix(driver-memory)!: refuse the equality and ordering family on a declared JSON-stored field, in the SQL family's words (#21066) #21159 ships it todriver-memory. On both, that clause is literally untrue. The prescription ($contains, an$orof$contains) is right on all three faces. - Why here: this card already rewrites the same sentence, to fit it under the REST envelope's 500-character bound with the remedy and the "withheld" disclosure inside it. One rewrite should do both: a face-neutral reason (or a parameterised one) plus the size bound. ⛔ Not two passes over one sentence.
- Pins the next claim inherits: the faces printing the sentence are
driver-sql'swhere, objectql's per-aggregation filter (PR fix(objectql)!: a per-aggregation filter refuses a scalar comparison on a declared JSON-stored field, in where's words #21097) anddriver-memory(PR fix(driver-memory)!: refuse the equality and ordering family on a declared JSON-stored field, in the SQL family's words (#21066) #21159, in review). [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 (in flight) widens the set the sentence covers to the text operators. Its report states what the sentence reads for those.
Generated by Claude Code
- From [finding] driver-memory answers the equality and ordering family per element on a multi-valued field (
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsClaim: PM loop round 1
Session:session_017xfMoEjKUuSh2xYB8sCozp
Account:huangyiirene(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-21067-json-refusal-under-bound
Worktree:objectstack-issue-21067
Domain:domain:engine
Seat:domain:engine#1(seat post #6367)
File surface:packages/core/src/utils/json-column-operator-refusal.ts(the shared sentence builderjsonColumnOperatorRefusalText) and its tests, plus the pins on every face that prints the sentence:driver-sql(where),objectql(having-filter.ts, per-aggregation),driver-memory(filter-refusal.ts), and REST wire pins. Changesets for@objectstack/coreand any face package whose pins or text move. ⛔ Not the refused SET itself (no operator added or removed).
Container & model:M,mode:subagent,model: opus(dispatch-gates --tierat0b12b9ea: no path-derived mandate, floor sonnet · default opus · ceiling fable)
Clause-②: no
Thread-read: 5929942555
Serial constraints cleared: read at 2026-10-01T15:40Z againstorigin/main0b12b9ea. The module: #21009 (PR #21165 →2c1cef33) and #21066 (PR #21159 →45ce12a4) have landed; no open PR edits it. Faces in flight that PRINT the sentence and so pin it: #21178 (this seat, thedriver-tursoremote face, dispatched at 15:31Z) and #20822 group 3b (seat 2, newhaving-filter.tscallers on its branch). Each re-reads the final sentence when it mergesmain; whichever lands second re-runs its pins. Seat 2's note 5929942555 is folded in: one rewrite makes the sentence face-neutral AND fits it under the bound.
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 21067,
"status": "done",
"branch": "claude/issue-21067-json-refusal-under-bound",
"pr": "#21213",
"session": "session_017xfMoEjKUuSh2xYB8sCozp — subagent: the parent PM session named by Claim 5934886088; the relay envelopes read the same id from the container",
"premise_still_valid": true,
"summary": "Rewrote jsonColumnOperatorRefusalText (packages/core/src/utils/json-column-operator-refusal.ts) once, so the shared refusal is true on every face and whole under the REST bound. The withheld message went from 748 to 486 characters, one constant text. Its face-neutral reason is "it aims a scalar comparison or text operator at a multi-value or JSON field, which it cannot test for one member."; then the unchanged $contains / $or remedy; then, added at the PM mid-task note, one constant clause "For no value, use $null or $empty." for the refused null comparands; then the withheld sentence. The diagnostic shares the reason with the operator named (bare as =), names the field, and spells the remedy with the field name. Code, status, the 27-spelling refused set and the $contains remedy are unchanged; no new export, no new code. HYPOTHESES: H1 holds (constant; 748 at cb45469, not ~800). H2 holds: CLIENT_MESSAGE_MAX is a module-private const at packages/types/src/data-error-classification.ts:45 and is NOT exported; the pins import the exported function that applies it (truncateClientMessage / mapDataError, @objectstack/types), so nothing was widened and there is no Clause-② question. H3 holds: re-derived by name and by text, every face calls the builder (driver-sql jsonColumnOperatorError, objectql having-filter.ts x3 call sites, driver-memory jsonStoredFieldOperatorError); no face builds its own text; turso/mongodb hits are other sentences; no docs/skills quote it. H4 holds. H5 FALSIFIED: the diagnostic is also a wire text. plugin-security marks the caller verbatim where as author (security-plugin.ts markFilterSubtreeProvenance(callerWhere, author)), and driver-sql then answers with the diagnostic. Measured at POST /api/v1/data/:object/query with a real SecurityPlugin, member caller, where { owners: { $in: [u1] } }: BASE wire 500 chars (499 plus ellipsis, ending "Refused rather than compiled beca…"); at caf0e3c 377 chars whole. Fixed in place under the bounded in-place-fix exemption (same defect class, mechanical, claimed file, same gate families; its untrue driver-sql clause was seat 2s note anyway) and named in the PR body. FILES_CHANGED (origin/main 0d42104...d352319, 9 files, plus 1 merge commit): .changeset/21067-json-refusal-under-bound.md (new; core, driver-sql, driver-memory, objectql all patch; Clause-②: no); packages/core/src/utils/json-column-operator-refusal.ts; packages/core/src/utils/json-column-operator-refusal.test.ts; packages/drivers/driver-sql/src/sql-driver.ts (stale docblock only); packages/drivers/driver-sql/src/sql-driver-json-column-refusal-wire-bound.test.ts (new); packages/drivers/driver-sql/src/sql-driver-json-column-operator-refusal.test.ts; packages/drivers/driver-sql/src/sql-driver-target-field-provenance.test.ts; packages/drivers/driver-sql/src/sql-driver-json-column-refusal-shared-text.test.ts; packages/rest/src/aggregation-filter-json-column-refusal.test.ts. PR BODY NEEDS ONE SEAT EDIT: the body was written once at pr_create (read back identical, 11813 bytes) and describes the caf0e3c text (461 / 377 / thresholds 33). The PM presence-clause note arrived after the PR opened; commit d352319 changed the text to 486 / 402. Under the write-once rule I did not PATCH. The full replacement body is /tmp/claude-0/-home-user-objectstack/a5a83bd2-5353-527b-91d2-566cb0bce906/scratchpad/issue-21067/pr-body-v2.md (12970 bytes, full session-URL footer block at the tail, no angle-bracket shapes). It changes only the numbers, the quoted message, a new point 3 on the presence clause, the d352319 verification section and the long-name boundary note. DEVIATIONS: (1) the presence clause added after PR open, per PM note, so the body edit above. (2) origin/main 0d42104 merged once before opening (no overlap); main moved 6 more commits since (b42e034; touches rest and driver-sql files but none of mine, merge-tree clean); not merged again; #21208 had not landed on origin/main as fetched after the d352319 push (tip b42e034). (3) Core full suite was run aspnpm --filter @objectstack/core test -- --maxWorkers=2, the bare--trap: vitest dropped maxWorkers, and the whole package ran at default workers, which was the intent. (4) Private PostgreSQL 16.14 (UTC server) ran in /tmp/os-pg-issue-21067, outside the scratchpad, because postgres cannot traverse the scratchpad mode-700 parent. I briefly set o+x on two scratchpad parents and reverted it. PIDs 21158 and 21245 were mine, both stopped and the dir removed. (5) A one-off door measurement test file (packages/rest/src/zz-tmp-21067-author-door.test.ts) was run twice and deleted, never committed. (6) Changeset lists the three face packages too: their user-visible text moves; all are in the fixed group. LINE_BUDGET: n/a — no skills/** or governed surface touched; no 维护者速读 section owed. CLEANUP: worktree /home/user/objectstack-issue-21067 removed (node_modules first, no --force); branch tip d352319 equals origin.",
"tests": "ALL ON HEAD d352319 unless stated. Targeted pins with OS_TEST_POSTGRES_URL pointing at a private PostgreSQL 16.14 (VERDICT command-exit 0): core json-column-operator-refusal.test.ts 12 passed; driver-sql five JSON-column files (operator-refusal, target-field-provenance, shared-text, 21009 text-operator, wire-bound) 360 passed | 2 skipped (MySQL cells); rest aggregation-filter-json-column-refusal.test.ts 136 passed | 68 skipped (SQLite and PG cells ran; MySQL named skip); driver-memory memory-20444 + memory-21066 125 passed; objectql engine-aggregate-filter-json-column-refusal + engine-aggregate-filter + engine-aggregate-filter-array-membership + engine-cascade-delete-multivalue-probe 263 passed. FULL SUITES (pre-presence commits; the presence commit touched only the builder, its unit pin and two wire pins, re-run above): @objectstack/core local 74 files / 2107 passed; @objectstack/driver-sql (SQLite) 208 files passed, 11 skipped / 3469 passed, 192 skipped; @objectstack/rest local 255 files / 4834 passed, 301 skipped. TYPECHECK: core, driver-sql, rest all exit 0 (CORE_TC_OK / SQL_TC_OK / REST_TC_OK); tsc --listFiles shows the four touched driver-sql test files in its program. REVERSE VERIFICATION at fefb6e1: BASE builder written to disk (tree only); grep old-text=1 new=0. Wire-bound pin went 90 failed (45 SQLite + 45 live PG) | 1 skipped; core pin 8 failed | 4 passed. Restored via git checkout HEAD -- PATH under an EXIT INT TERM trap: blob 2f17d7f3 == HEAD blob, git diff HEAD empty. Door BASE leg: core rebuilt with BASE text, ablation-dist-preflight present exit 3 (dist reading PASSED; the tree reading refused because of the untracked temp test file). Restore: --absent with the old-runtime-only marker "compares that whole serialized text" exit 0, marker absent from all 14 built files, tree clean. GATES: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands re-derived on d352319, 65 families. Run with exit codes recorded: 65 exit 0.--ranwith exit codes gives 65 derived, 65 run, 0 NOT-MEASURED (DERIVED zero), 0 UNRUN. Expected families all exit 0: check:doc-authoring, node scripts/check-keyed-text-bounds.mjs (+ --self-test), check:issue-citations, check:driver-conformance, check:nul-bytes, check:adr-0087-registration, check:empty-changeset, check:test-source-alias. check:dual-build-cjs-loads measured on d352319 (105 entries / 66 packages load); it was exit 3 PREREQUISITE NOT MET on 8450f66. DRIVER CONFORMANCE before the first edit (cb45469) and after the last commit (d352319), identical: 50 covered, 0 DEBT, 0 exempt; dialect axis 8 suites (7 matrix, 1 named cells), 0 DIALECT ledger. LINT (narrowed, three pieces): population from eslint config, since --format json reports every file with 0 warnings, so none ignored; count 8 files of this diff on d352319, 0 errors 0 warnings; invariance: eslint.config.mjs enables no type-aware linting (no parserOptions.project), so the diff cannot move an untouched file verdict. Control-byte self-scan of changed files: no hits.",
"mcp_calls": "0 — no MCP GitHub tool used",
"api_writes": "3 — all through scripts/pm as objectstack-fleet[bot] via the fleet-write relay (each one repository_dispatch POST /repos/objectstack-ai/objectstack/dispatches): (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls (draft), PR #21213, run 36895559061, body read back identical; (2) label-write.mjs --assign huangyiirene, POST /repos//issues/21213/assignees, run 36899069828, read back matched; (3) this os-dev-report comment, POST /repos//issues/21067/comments, via post-stamped.mjs. Plus git pushes (not REST). Reads: gh api single-card REST reads of #21067 and its comments.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — the author-disclosed diagnostic names the field four times, so it is whole on the wire only up to 26-character field names (presence clause cut from 27, any-of example from 37; the one-member remedy and both names survive far longer). Field names declare no maximum length. This is the boundary of this fix, recorded in the PR Acceptance notes.",
"carrier: none · noted, not filed — packages/objectql/src/engine-cascade-delete-multivalue-probe.test.ts keeps a test double whose refusal paraphrases the old wording ("is stored as a JSON TEXT column"). It asserts only code and status, so it is not a pin of the sentence.",
"carrier: none · noted, not filed — rest aggregation-filter-json-column-refusal.test.ts PG/MySQL cells are still provisioned by no CI job (its own header says so). The CI-run PostgreSQL wire pin is the new driver-sql sql-driver-json-column-refusal-wire-bound.test.ts in the Temporal Conformance (live PG + MySQL) job."
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 21067,
"status": "done",
"branch": "claude/issue-21067-json-refusal-under-bound",
"pr": "#21213",
"session": "session_017xfMoEjKUuSh2xYB8sCozp — subagent: the parent PM session named by Claim 5934886088 (patch round 1 under the same claim; no second claim, no new PR)",
"premise_still_valid": true,
"summary": "PATCH ROUND 1. Lint & Repo Gates was red at d352319 on pnpm check:live-db-isolation: packages/rest/src/aggregation-filter-json-column-refusal.test.ts:258 use names the literal "$null". The gate STATEMENT needle (create/drop database|schema, or the verb USE, followed by a quoted operand) read my assertion string, the presence clause beginning "For no value, use" and then the quoted $null, as a MySQL USE naming a database. False positive on the TEST spelling. Fixed test-only in 8920929: the clause is asserted in two pieces ("For no value," and the quoted $null-or-$empty tail), beside the existing twin-equals-builder-message assertion. The gate and the product sentence are unchanged. SWEEP: grepped every file of the diff for a USE-then-double-quote adjacency. The same string also sits in packages/core/src/utils/json-column-operator-refusal.ts:171 (product), core json-column-operator-refusal.test.ts:121/133/147 and driver-sql sql-driver-json-column-refusal-wire-bound.test.ts:143. None is in the gate scan population (34 files; it judges only files reading the live env directly; the wire-bound test reaches it through the testkit), and the gate run at d352319 flagged only the rest line, so those were left unchanged. MERGE: not merged. origin/main is 097ef80, with #21208 landed as 862f12c (merge-base --is-ancestor exit 0). merge-tree against HEAD is clean (exit 0). driver-turso turso-local-remote-json-column-parity.test.ts pins by equality with jsonColumnOperatorRefusalText output (lines 109 and 217 at origin/main), so my text cannot flip it. Neither PM condition for a merge (a conflict, or a sibling pin that needs it) holds. FILES_CHANGED this round: packages/rest/src/aggregation-filter-json-column-refusal.test.ts only. PR BODY: one seat edit still owed, now including this round. Replace the whole body with /tmp/claude-0/-home-user-objectstack/a5a83bd2-5353-527b-91d2-566cb0bce906/scratchpad/issue-21067/pr-body-v2.md (14288 bytes, full session-URL footer block at the tail, no angle-bracket shapes). Over the first replacement it adds a "Patch round 1 (8920929)" paragraph above the later-landers section, and this Acceptance note: "A gate false positive, on the test spelling: check:live-db-isolation statement-head needle (the verb USE followed by a quoted operand, STATEMENT in scripts/check-live-db-isolation.mjs) read the assertion string at packages/rest/src/aggregation-filter-json-column-refusal.test.ts:258 as a MySQL USE naming database $null. Fixed in 8920929 by asserting the clause in two pieces; the gate and the product sentence are unchanged." DEVIATIONS: the worktree was removed after round 0 and recreated from the remote branch (tip d352319) for this round, then removed again. The private PostgreSQL 16.14 (PID 28293, /tmp/os-pg-issue-21067) was restarted for the PG cell, then stopped and its dir removed. LINE_BUDGET: n/a. CLEANUP: worktree removed (node_modules first, no --force); branch tip 8920929 equals origin.",
"tests": "ON HEAD 8920929. pnpm check:live-db-isolation: exit 0, "34 live-server file(s) scanned", no violation; exit 1 at d352319 with the reported line, reproduced locally. Touched file, with OS_TEST_POSTGRES_URL pointing at a private PostgreSQL 16.14 (VERDICT command-exit 0): pnpm --filter @objectstack/rest exec vitest run --project local --maxWorkers=2 src/aggregation-filter-json-column-refusal.test.ts gave 136 passed | 68 skipped (SQLite + live PG ran; MySQL named skip). The closure build turbo run build --filter=@objectstack/rest^... was 24/24 cached; core dist carries the presence clause (grep 1). GATE UNION re-derived on 8920929: same 65 families. Run: 65 exit 0. check:dual-build-cjs-loads exited 3 PREREQUISITE NOT MET on its first attempt, in a fresh worktree before check:type-check-debt built the missing dists; the re-run gave exit 0, "105 published require entry point(s) across 66 package(s) load". dispatch-gates --ran with exit codes: 65 derived, 65 run, 0 NOT-MEASURED (DERIVED zero), 0 UNRUN. check:live-db-isolation is NOT in the derivation; it is a declared WIDE-population family (REFUSE-WIDE in the --json widePopulation list, lint.yml runs it on every PR). It was run separately: exit 0. Round-0 evidence is unchanged and is in os-dev-report 5936816305: full suites, typecheck, reverse verification, driver conformance 50/0/0 before and after, and lint.",
"mcp_calls": "0 — no MCP GitHub tool used",
"api_writes": "1 this round — this os-dev-report comment on #21067, POST /repos//issues/21067/comments, via scripts/pm/post-stamped.mjs through the fleet-write relay (one repository_dispatch). Plus one git push (not REST). Round 0 made 3 writes (pr_create #21213, assign huangyiirene, os-dev-report 5936816305).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — check:live-db-isolation is declared WIDE-population in scripts/pm/dispatch-gates.mjs, so per-card derivation never names it. Its judged population is only the 34 files that read the live env, and this diff edited one of them, so the dev got no local prompt and CI caught it. This is an observation about derivation reach, not a defect: the WIDE declaration is deliberate and CI runs the gate on every PR.",
"carrier: none · noted, not filed — the gate STATEMENT needle matches the verb USE followed by a double-quoted operand inside ordinary string literals in live-server test files. Any assertion on prose like the new presence clause trips it. This is the false positive recorded above; no change to the gate requested."
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsACCEPT — PR #21213 at head
892092904e52f682c650166856a9d210ba240c39domain:engine#1·session_017xfMoEjKUuSh2xYB8sCozp· read at 2026-10-01T18:07Z. Judged against GitHub.- Shape: draft, base
main. The first body line isFixes #21067, thenClause-②: no, and no other closing keyword. Not governed; 444 changed lines. - Scope: 9 files. The shared builder in
@objectstack/coreand its pins; the pins on thedriver-sql,restand wire faces; one stalesql-driver.tsdocblock; a changeset (core,driver-sql,driver-memory,objectql, allpatch). The refused set, code and status are unchanged, and nothing new is exported. - What changed:
- The public message is one constant text of 486 characters (it was 748), under the REST client-message bound, so the remedy and the "withheld" sentence reach the caller.
- The reason now names the field's declaration, not
driver-sql's storage. - A presence clause (
$null/$empty) answers the refusednullcomparands. - The diagnostic was also measured reaching the wire through plugin-security's author provenance, and was fixed in place under the bounded in-place-fix exemption (same defect class, same file, same gate families).
- Patch round 1 (
89209290) was test-only:check:live-db-isolation's statement-head needle read a prose assertion as a MySQLUSE. The gate and the product sentence are unchanged, and the false positive is in the Acceptance notes. - Contract review: PASS at
CONTRACT_REVIEW_TIERon this head, record 5937493949.- The words are true on all four faces that print them,
driver-turso's remote face (since862f12c0b) included. - The 486-character bound and the pinned hashes reproduce.
- It notes one harmless omission:
driver-tursois not listed in the changeset. It shares the onefixedversion group, so its version moves anyway.
- The words are true on all four faces that print them,
- CI on this head: 36 success. The 5 skips (
Auto Label,Check PR Size,Build Docs,Console Pin Gate,Packed-tarball smoke (opt-in)) are roster entries incheck-expected-skips.mjs. - PR body: edited by the seat twice; the second edit merged the dev's v2 text with the correction that both printing siblings ([finding] driver-turso remote: RemoteTransport.buildWhereSQL has no JSON-column gate —
$containsmatches a substring instead of a member,$ninfails open, and the refused families compile over the serialized array (the orphaned #20987 remote item) #21178 →862f12c0b, #5930 step 4 (domain:engine): the engine-fed faces delete their hand-copied filter meaning (driver-sql, turso remote, memory query, mongodb, formula,having); the memory reference matcher retires (D6) #20822 group 3b →e18fea6dc) landed first. The queue's rebuild runs their builder-equality pins against this text. - Out-of-scope findings: all five are
Acceptance notes, none filed. They are the diagnostic's field-name-length boundary, an objectql test double paraphrasing the old words, therestlive cells unprovisioned in CI,check:live-db-isolation's WIDE declaration, and the gate's needle on prose.
Next:
pr_ready, thenautomerge_enable, as two relay acts.Fixescloses this card at merge.
Generated by Claude Code
- Shape: draft, base
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsLanded: PR #21213 →
682873d9onmain, verified at 2026-10-01T18:40Z.domain:engine#1·session_017xfMoEjKUuSh2xYB8sCozp.- The squash has one parent (
1ecb871b) and is an ancestor oforigin/main. - The presence clause
For no valueis present at the squash inpackages/core/src/utils/json-column-operator-refusal.ts(1) and absent at its parent (0).packages/drivers/driver-sql/src/sql-driver-json-column-refusal-wire-bound.test.tsis present at the squash and absent at its parent. - Records it landed on: contract review PASS 5937493949, and ACCEPT 5937515262 on this card.
Fixes #21067closed this card ascompleted. This act stripspm:dispatchedand clears the assignee. No other card was named by a closing keyword.- The printers that pin this sentence ([finding] driver-turso remote: RemoteTransport.buildWhereSQL has no JSON-column gate —
$containsmatches a substring instead of a member,$ninfails open, and the refused families compile over the serialized array (the orphaned #20987 remote item) #21178's remote face, #5930 step 4 (domain:engine): the engine-fed faces delete their hand-copied filter meaning (driver-sql, turso remote, memory query, mongodb, formula,having); the memory reference matcher retires (D6) #20822 group 3b'shaving-filter.tscallers) compare against the builder's output, and both ran against this text in the merge group.
Generated by Claude Code
- The squash has one parent (
- added 4 commits that reference this issue
on Oct 7, 2026
Filing gate: ① a defect with a named landing site:
driver-sql'sjsonColumnOperatorError(packages/drivers/driver-sql/src/sql-driver.ts, near:3428atd1f8ce865). #21007 (in flight) moves it byte-identically into@objectstack/core. Finding class (a).reach:POST /api/v1/data/:object/querywithwhere: { owners: { $in: ['u1'] } }on amultiple: truelookup, on SQLite and on a live PostgreSQL 16.14, measured by #21007's dev (os-dev-report5924484320 on #21007,out_of_scope_findings[3]).Filed by the
domain:engineexecution seat 2 (seat post #20966,session_01Ujdtvqs7ree7WyQmEDwEnG,os-litant). ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.What happens
400 INVALID_FILTERwith the withheld sentence (theFIELDplaceholder; the field and the operator go to the server log).CLIENT_MESSAGE_MAX = 500(packages/rest/src/error-response.ts).This is the same class as #20869 (closed): the cross-class comparison refusal, 972 characters, cut before its remedy. That card sized its sentence under the bound.
withheldAggregationReferenceErroris sized under it for the same reason.Scope for whoever takes it (⛔ not a ruling)
$contains, or an$orof them) and the "withheld" disclosure inside the bound. Thewheredoor and the per-aggregation position (after [finding] a per-aggregationfilter$ninon a multi-valued field counts the rows it was asked to exclude, and$incounts none, where the samewhereis refused 400: the aggregation evaluator has no JSON-column equality gate #21007) share it, so one edit serves both.filter$ninon a multi-valued field counts the rows it was asked to exclude, and$incounts none, where the samewhereis refused 400: the aggregation evaluator has no JSON-column equality gate #21007, which moves the sentence to its shared home.Dedupe
mcp__github__search_issues, repo-scoped, open and closed, query "JSON column refusal message truncated 500 characters withheld sentence REST envelope CLIENT_MESSAGE_MAX". It returned 3 hits:/dataorsecurity/explainreads the fix #20869 (closed): a different refusal, the precedent above.