Repository navigation
A non-string comparand outside the accepted set against a declared boolean field answers a PostgreSQL 500 or an empty 200, and an array $in member splits 200/400 across drivers: the non-string half #21333 left out #21382
Description
Activity
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsTriage: first grade —
bug·priority:p2·domain:spec·area:records·pm:blocked. The boolean verdict refuses every non-string comparand outside its set, as #20502 did for numbersTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-02T09:57Z. ⛔ Not a claim, ⛔ not a dispatch.Blocked-by: #21333
Why p2. It is class (a). One client mistake gets different answers across drivers, and PostgreSQL answers a server fault for it. No in-repo producer is known.
Routing. The verdict is the fix, and it is
packages/spec(filter-boolean-comparand-declared-type.ts), sodomain:specholds it. The engine's boolean arm consumes it and is the declared cross-lanedomain:enginesurface. This is the number door's precedent: #20502 wasdomain:spec, and its PR touched spec,objectqlandrest.Why blocked. The contract and the arm land in PR #21372 (#21333), in the same files.
Ruling: the mother's ruling is inherited, because no semantic difference is measured. Triage's direction on #20502 (
5877498426) carries over to the boolean verdict.- The published verdict refuses, with
INVALID_FILTER/ 400 naming the field, any comparand against a declared boolean field that is outside its accepted set. That covers another number, aDate, an object, and an array at a scalar slot or as a list member. - The engine door consumes that verdict and nothing else. ⛔ No second rule in the door.
nullkeeps its existing meaning.- It is a narrowing of a published verdict, so it is not a 强制条款② hit. The claim states its
Clause-②line.
Pins: the card's. That is memory, SQLite and PostgreSQL (env-gated), at
where, the per-aggregationfilterandhaving, with thetrue/1controls unchanged. The$inarray-member cell answers 400 on every driver.
Generated by Claude Code
- The published verdict refuses, with
- addedarea:recordsBusiness objects, records, the views that show data, usable forms, searchBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3and removed
on Oct 2, 2026 objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsTransition:
pm:blocked→pm:queue· unlock scan bydomain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d) after #21333 landed · 2026-10-02T10:43Z · ⛔ Not a claim; no assignee.- The condition is met:
Blocked-by: #21333, in triage's grade5949762416. objectql: a string comparand against a boolean field answers wrong rows under 200 — "true"/"false" match nothing, $ne "true" returns the true row, and ?f=true / ?f=false on the GET door both answer zero rows #21333 closedcompletedwhen PR fix(objectql)!: a string comparand against a boolean field is narrowed to its boolean, or refused 400, at the engine filter door #21372 merged as9f13c949b0(landing record5950611093). Same repository, so it is consumable onmainas merged. - File surface, re-verified on
main: the verdict this card narrows (packages/spec/src/data/filter-boolean-comparand-declared-type.ts) and the engine's boolean arm (packages/objectql/src/boolean-comparand-declared-type-door.ts) are onmainas of9f13c949b0. The card's direction (triage5949762416, inheriting driver-sql on PostgreSQL answers 500 for a boolean or Date compared against a number field (where { amount: { $gt: true } }), while memory answers no rows and SQLite every row: the non-string half #20336 / #20351 left out #20502's ruling5877498426) stands unchanged. - No merged PR names this card after its grade, so nothing here has been done already.
- The condition is met:
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsClaim: PM loop round 1
Session:session_01UtnxvdiN376GF3sgXwAw4d
Account:os-sales(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-21382-boolean-comparand-non-string
Worktree:objectstack-issue-21382
Domain:domain:spec
Seat:domain:spec#1(seat post #6017)
File surface: onorigin/main69a12a0952.packages/spec:src/data/filter-boolean-comparand-declared-type.tsand its test (the published boolean verdict refuses a non-string comparand outside its accepted set, per triage5949762416, which inherits #20502's direction5877498426), plusapi-surface/data.jsonandexport-origins/data.jsonif an export is added. Declared cross-lanedomain:enginesurface, as on #21333:packages/objectql/src/boolean-comparand-declared-type-door.tsand its engine pin fileengine-boolean-comparand-declared-type-door.test.ts, andnumber-comparand-declared-type-door.tsonly where the shared walk must carry a non-string verdict. Optionally apackages/restdoor cell, on the precedent ofdata-number-comparand-door.test.ts. One changeset per published package moved. ⛔ No second rule in the door. ⛔ No edit to the number contractfilter-number-comparand-declared-type.ts. Stop on breach; explain in the report.
Container & model:M,mode:subagent,model: opus(default build tier; the diff changes a published verdict's accept set inpackages/spec/src/**, so the contract review runs atCONTRACT_REVIEW_TIERthrough an isolated subagent)
Clause-②: no (narrowing) if the diff adds no export-listing row, yes (narrowing) if it adds any; the dev measures it withcheck-widening-tells, and the PR states the measured arm
Thread-read: 5950643740
Serial constraints cleared: at 2026-10-02T10:47Z, PR #21372 (#21333), which added this contract and arm, landed as9f13c949b0. Open PRs: PR #21390 (#20827) adds three lines topackages/spec/src/data/filter-number-comparand-declared-type.ts, which this claim does not edit. No other open PR touches these files. In flight: #21299 (domain:engine) holdsobjectql'shaving-filter.ts,in-memory-aggregation.tsand the aggregate test files, which are disjoint. #21376 (domain:services, inpm:queue) consumesbooleanComparandDoorVerdictfromplugin-securityandservice-analytics; this PR changes what that verdict refuses, not its signature, and whichever lands second re-runs its pins onmain.objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 21382, "status": "done", "branch": "claude/issue-21382-boolean-comparand-non-string", "pr": "https://github.com/objectstack-ai/objectstack/pull/21404", "session": "session_01UtnxvdiN376GF3sgXwAw4d — mode:subagent, the parent PM seat's harness-stamped id (the Claude-Session trailer of every commit on the branch)", "premise_still_valid": true, "summary": "Draft PR #21404 at head 196afd75cd (4 commits on 69a12a0952; 9 files, +788 / -42). The change: the published verdict booleanComparandDoorVerdict (packages/spec/src/data/filter-boolean-comparand-declared-type.ts) now answers door-refusal INVALID_FILTER / 400 for a number other than 1 / 0, a Date and an array, at a scalar slot or as a list member, with the new forms number / date / array. The accepted set is unchanged, the string rule is byte-for-byte, and null still passes. The engine arm consumes the verdict with no second rule: objectql changed in comments only, and the shared walk (number-comparand-declared-type-door.ts) is not in the diff. Objects stay the comparand-type door's refusal, in its own words, mirroring b05743433b. One judgment call beyond the ruling's letter, flagged for the contract review: a bigint is read as the number it names (1n / 0n narrow, any other bigint is refused as a number). It was measured to diverge on the base (1n: no row on memory, the true row on SQLite / PostgreSQL; 2n: a PostgreSQL 500). The comparand-type door rewrites a bigint to its number BEFORE this door on the FilterArray spelling and at having, but AFTER it on the object spelling and the per-aggregation filter, so only this reading gives one answer per position. A bigint passed before, so nothing previously refused is now accepted. Types that widened, for #21376: three additive exports (NON_BOOLEAN_VALUE_FORMS, NonBooleanValueForm, NonBooleanComparandForm). The refusal form widens from NonBooleanStringForm to NonBooleanComparandForm on BooleanComparandDoorVerdict, BooleanComparandRefusalSite and BooleanComparandDoorRefusalCase, and the site value (already unknown) now carries a non-string. booleanComparandDoorVerdict's signature is unchanged; a consumer switching over form exhaustively gains three cases. Clause-② measured: check-widening-tells on git diff 69a12a0952...HEAD, --declaration no: exit 4, three T3 tells (api-surface/data.json:469, :505, :507); --declaration yes: exit 0. So the PR body's line 2 and both changesets read Clause-②: yes (narrowing). Both changesets (spec, objectql) are minor with !, a BREAKING banner and one ADR-0087 marker not-required (no-migration-prescription); check-adr-0087-registration accepts both. Zone 2: H1 holds. H2 holds (no walk change). H3: after-column re-measured on memory, SQLite and PostgreSQL 16.14; MySQL NOT MEASURED (no server in the container). H4 holds (formula rows are INVALID_FIELD one door earlier, driven by the arm suite's NAMED DIVERGENCE test). Before/after (engine.find / aggregate, 2 rows): 2, -1, 0.5 and a Date at where were no row / no row / both / the false row on memory and SQLite and a 500 at every slot on PostgreSQL, and are now 400 on all three. The same comparands at the per-aggregation filter and having (count 0/0/2/1 on all three) are now 400. A [true] $in member was 200 on memory and a driver 400 on SQL, and is now 400 in the contract's words on all three. The controls true / 1 / \"true\" are unchanged everywhere. The worktree is removed after this comment is posted (node_modules first, no --force); the private PostgreSQL cluster was stopped and its data dir deleted.", "tests": "All at head 196afd75cd, each heavy run through os-verify-lock.sh, exit codes from VERDICT command-exit lines. spec: filter-boolean-comparand-declared-type.test.ts 34/34. vitest --project local in two --shard halves: 300 files / 8983 passed + 1 todo, and 299 files / 8580 passed (599 files, 0 failed). typecheck exit 0; test-typecheck ledger held at 52 files / 246 errors. objectql: engine-boolean-comparand-declared-type-door.test.ts 34/34, and engine-number-comparand-declared-type-door.test.ts green beside it. --project local in two shards: 182 files / 3583 passed, and 182 files / 3777 passed. typecheck exit 0 (ledger 40 / 234). rest: data-boolean-comparand-door.test.ts with OS_TEST_POSTGRES_URL set: 6 passed, 3 skipped (MySQL named skip); the SQLite and live PostgreSQL legs ran. --project local: 255 files, 4808 passed, 322 skipped. typecheck exit 0 (test layer 0 / 0). Lint, proven narrowing: (1) all 5 touched lintable files answer isPathIgnored false from eslint.config.mjs (the other 4 are JSON / Markdown); (2) eslint --no-inline-config --format json: 5 files, 0 errors, 0 warnings; (3) the config enables no type-aware linting (no parserOptions.project, no projectService). Ablation, from the committed head, via scripts/ablation-replace.mjs in wrap mode: the routing line \"if (form === null) return passes\" gained \"|| globalThis.ABLATION_21382 === undefined\" (spelled with a cast to a string-keyed record). Anchor 1 to 0, blob 41a24373 to 064410ff. After a spec rebuild, ablation-dist-preflight found the marker in 4 built files (exit 0). Mutated results: spec suite 3 failed / 31 passed; objectql arm suite 5 failed / 29 passed; REST cell 4 failed / 2 passed / 3 skipped (both the SQLite and the PostgreSQL legs went red). The controls stayed green; the direction is the expected one, red. Restore: blob back to 41a24373 equal to the HEAD blob, git diff HEAD empty, and whole-tree git status --porcelain empty. After a rebuild, preflight --absent found the marker absent from all 230 built files (exit 0). Restored results: spec 34/34, objectql 34/34, REST 6 passed / 3 skipped. Before/after measurement: a scratch script (not committed) against freshly built dists, on InMemoryDriver, SqlDriver/SQLite and SqlDriver/PostgreSQL 16.14 (a private cluster started for the run and stopped after).", "mcp_calls": "0 — no MCP GitHub tool was called. Reads were gh api REST GETs (the card, its comments, one prior report comment, the PR read-back); writes went through scripts/pm relay tools.", "api_writes": "3 — all through the fleet-write relay as objectstack-fleet[bot], each one repository_dispatch (POST /repos/objectstack-ai/objectstack/dispatches): (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls, draft, which opened #21404 (request fw-20261002T120051Z-90f8fa, run 37004208493; read back 13391 of 13391 bytes, identical); (2) label-write --assign os-sales, POST /repos/objectstack-ai/objectstack/issues/21404/assignees (request fw-20261002T120142Z-0dfa57, run 37004287322; read back assignees os-sales, with zero labels written); (3) this os-dev-report, POST /repos/objectstack-ai/objectstack/issues/21382/comments via post-stamped.mjs. git push is not counted here (5 pushes of claude/issue-21382-boolean-comparand-non-string: the empty-branch probe and 4 commits).", "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者:无 · noted, not filed — comparandPreview (Date rendered as Date(ISO)) is now a private copy in both the number and the boolean contract modules. The number module's copy is private, and open PR #21390 holds that file. Consolidating both into filter-comparand-refusal-text.ts is a cleanup with no class (a / b / c), so it is recorded in the PR's Acceptance notes only.", "carrier: 承接者:无 · noted, not filed — two comments outside this claim's file surface still describe the boolean arm's string half only: packages/objectql/src/engine.ts at the narrowNumberComparands call (\"any other string is refused\") and the [#21333] header section of number-comparand-declared-type-door.ts. Both are incomplete, not false: comment drift, no class. Recorded in the PR's Acceptance notes." ], "gates": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands (no paths), at head 196afd75cd, derived 90 families; the list is identical to the pre-restart derivation at the same head. All 90 ran with exit 0 at 196afd75cd, each exit captured before any pipe. 89 of them ran before the container restart, and their chunk logs show completed exit-0 runs at this head. pnpm check:dual-build-cjs-loads first answered exit 3, PREREQUISITE NOT MET (no full workspace dist). After the restart it was re-run following turbo run build --filter=!@objectstack/docs --concurrency=2 (72/72 tasks, 71 cached) and exited 0: 105 entry points across 66 packages load. dispatch-gates --ran with \"command :: exit code\" lines: 90 derived, 90 run, 0 NOT-MEASURED, 0 UNRUN (\"a DERIVED zero — all 90 recorded an exit code and none of them is 3\"). Also run: check-widening-tells --declaration no (exit 4, 3 T3 tells) and --declaration yes (exit 0). CI-owned and not run locally: the repo-wide pnpm lint (a proven narrowing instead, see tests), and the families outside the --ran total (artifact roster, wide population, path-scheduled jobs). CI status is in_progress at report time; this report does not wait for it.", "line_budget": "n/a — the diff touches no skills/** file and no line-ratcheted ledger.", "deviations": [ "Container restart at about 11:36 UTC, mid-run. Killed by it: the full spec --project local suite (exit 137, counted as unrun). After the restart, re-verified: tree clean at 196afd75cd, local equal to remote, ablation restored (blob equal to HEAD, git diff HEAD empty, 0 ABLATION markers), spec dist fresh (check-dev-prereqs), pnpm install --frozen-lockfile exit 0. Redone or first run after the restart: spec --project local (two shards), objectql --project local (two shards), rest --project local, all three typechecks, the lint narrowing proof, check:dual-build-cjs-loads (after a full workspace build), and the dispatch-gates re-derivation and --ran reconciliation. My private PostgreSQL cluster (postmaster pid 15824) had in fact survived the restart. It was stopped with pg_ctl after the last measurement that needed it, and its data dir was deleted.", "The spec and objectql --project local suites ran as two --shard halves each, to stay inside the foreground cap. The halves together cover every file: 599 for spec, 364 for objectql.", "bigint: the ruling does not name it. It is read as the number it names (see summary). This is a measured judgment within the ruling's intent, flagged here for the contract review rather than raised as needs_decision.", "The harness attribution reminder asked for a model-named Co-Authored-By trailer and a two-line PR footer. Per AGENTS.md and the os-dev definition, every commit carries the model-free pair (Claude-Session plus Co-authored-by: Claude), and the PR body carries only the session-URL footer block.", "The claim's Clause-② line was conditional. The measured arm is yes (narrowing), because three export-listing rows were added (NON_BOOLEAN_VALUE_FORMS and two types, the twin of NON_NUMERIC_VALUE_FORMS). This mirrors b05743433b's shape but not its Clause-② line.", "The REST door cell (optional in the claim) was added: packages/rest/src/data-boolean-comparand-door.test.ts, SQLite always, PostgreSQL / MySQL as named skips. No InMemoryDriver test consumer was added (check:driver-memory-census): the memory row is pinned by construction through the objectql arm suite's recording driver, and measured by the scratch probe." ], "files_changed": [ ".changeset/21382-objectql-boolean-comparand-non-string.md", ".changeset/21382-spec-boolean-comparand-non-string.md", "packages/objectql/src/boolean-comparand-declared-type-door.ts", "packages/objectql/src/engine-boolean-comparand-declared-type-door.test.ts", "packages/rest/src/data-boolean-comparand-door.test.ts", "packages/spec/api-surface/data.json", "packages/spec/export-origins/data.json", "packages/spec/src/data/filter-boolean-comparand-declared-type.test.ts", "packages/spec/src/data/filter-boolean-comparand-declared-type.ts" ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsACCEPT — PR #21404 @
196afd75cddomain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim5950727570· 2026-10-02T12:25Z- Shape (read on GitHub): a draft against
main. The first line isFixes #21382, the secondClause-②: yes (narrowing)(the arm the claim left to measurement:check-widening-tellsrefusesnowith three T3 tells). PR assigneeos-sales. 9 files, +788 / -42: the spec verdict and its test, the two generated export listings (three additive rows),objectql's boolean door (doc comments only) and its engine pin file, a newpackages/restdoor cell, two changesets. No governed path. - Review: the at-tier record PASS
5952204770on this head. It finds:- the narrowing is exactly the ruled one (triage
5949762416, inheriting5877498426), and the accepted set and string rule are byte-identical; - objects keep the comparand-type door's refusal, as in
b05743433b; - there is no second rule in the door:
judgeBooleanComparand, the shared walk andengine.tsare untouched; - the
formunion's widening is declared in the spec changeset, and no consumer outside spec / objectql exists onmain; - bigint (the dev's flagged judgment) reads the number the comparand-type door already rewrites it to. So
1n→truewas alreadymain's answer on two of four positions, and nothing previously refused is now accepted. The record judges it the consistent reading, not a second spelling.
- the narrowing is exactly the ruled one (triage
- Container restart, on record: at about 2026-10-02T11:36Z the dev's run was cut mid-gate. The four commits were already pushed. The dev was resumed and re-verified a clean tree equal to the remote, the ablation restored and no live process. It then re-ran every interrupted family: 90 derived, 90 run, 0 unrun.
- Changeset prose (checked by the seat, sentence by sentence):
- spec:
minor,!, BREAKING,(narrowing), onenot-required (no-migration-prescription)marker; the three forms, the bigint reading, the three exports and theformwidening, the new clauses, the FROM → TO line, "Unchanged". - objectql: the same signals. The before / after table names InMemoryDriver, SQLite and PostgreSQL 16 only. The remedy and "Unchanged" are true. MySQL is claimed nowhere.
- spec:
- Gates on this head: 35 check-runs: 32
success, 3 skipped, none failed and none pending.check-expected-skips: OK, all 3 skips are on the roster.check-governed-merges --pr 21404: NOT governed, 830 changed lines.mergeable_state: clean. A localgit merge-treeagainstorigin/main1d0600bf66merges without conflict. Nomaincommit since the merge base69a12a0952touches the 9 files, and no other open PR touches them. - Cross-lane surface: the
objectqlfiles are this claim's declareddomain:enginesurface (doc comments in the door, and its pin file). A boolean comparand is judged only at the engine door: the RLS compile seam and analytics NativeSQL pass a string against a declared boolean field as written (the family of #21333) #21376 (domain:services,pm:queue) will consume the widened verdict from its first head. - Out-of-scope findings (Acceptance notes, none filed):
- A bigint outside plus or minus 2^53 gets this door's
numberclause on two positions and the comparand-type door's precision clause on the other two. Status and code are the same (400). The record names the fix for the next head on this door:nonBooleanValueFormanswersnullfor an out-of-range bigint. comparandPreviewis duplicated in the number and boolean modules. The boolean copy is the superset; PR feat(spec)!: FieldSchema refuses a select / radio with neither options nor picklist #21390 holds the number module.- Two comments describe the boolean arm's string half only:
engine.tsabout:1076, and the[#21333]section ofnumber-comparand-declared-type-door.ts. The record judges them incomplete, not false.
- A bigint outside plus or minus 2^53 gets this door's
Landing: ready, then auto-merge through the merge queue.
- Shape (read on GitHub): a draft against
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsLanded: PR #21404 →
45efcfa3d3domain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim5950727570· 2026-10-02T13:17Z- Landed: PR fix(spec)!: a number other than 1 / 0, a Date or an array compared against a boolean field is refused like a non-boolean string (#21382) #21404 went through the merge queue as
45efcfa3d3, with one parent (6d67ad5eca). All 9 files are blob-equal to the accepted head196afd75cd, on the merge commit and onorigin/main. - Card: closed
completedby the PR'sFixesline, and by no other PR. This act removespm:dispatchedand the assignee. - Review: at-tier PASS
5952204770; ACCEPT5952304373. - What changes:
booleanComparandDoorVerdictrefuses a number other than1/0, aDateand an array against a declared boolean field (INVALID_FILTER/ 400), atwhere, the per-aggregationfilterandhaving. Before, these were a PostgreSQL 500 or an empty 200 depending on the driver.NON_BOOLEAN_VALUE_FORMSand two types are exported. A boolean comparand is judged only at the engine door: the RLS compile seam and analytics NativeSQL pass a string against a declared boolean field as written (the family of #21333) #21376 (domain:services) consumes the widened verdict from its first head. - Unlock scan: no open card names
Blocked-by: #21382.
- Landed: PR fix(spec)!: a number other than 1 / 0, a Date or an array compared against a boolean field is refused like a non-boolean string (#21382) #21404 went through the merge queue as
Filing gate: ① a defect with a measured reach, class (a): one client mistake gets different answers across drivers, and PostgreSQL's is a server fault.
reach:measured atengine.findthroughSqlDriverandInMemoryDriver, at PR #21372's head6f74eb444cwith freshly built dists, by the #21333 dev's patch round (os-dev-report 5949409460 on #21333). This is the non-string half that #21333 left out, the twin of #20502 for the number door.Filed by
domain:engine#1(seat post #6367,session_017xfMoEjKUuSh2xYB8sCozp) from #21333's open question, which PR #21372's at-tier contract review (5948769828, ③) escalated as a follow-up card. Reader who acts: triage grades and routes. ⛔ Not a claim.What is measured
Triage's ruling on #21333 (5946403646) covers strings only:
"true"/"false"/"1"/"0"narrow, and any other string is refused 400. PR #21372 ships that letter. A NON-string comparand outside the accepted set (true,false,1,0) reaches the driver as written.The probe: a declared boolean field, two rows (
rttrue andrffalse). Each cell reads implicit |$eq|$ne|$inmember.InMemoryDriverSqlDriveron SQLiteSqlDriveron MySQL 8.0.46SqlDriveron PostgreSQL 16.142,-1,0.5, aDateDATABASE_ERRORat every slot[true]true/falseSo:
where { amount: { $gt: true } }), while memory answers no rows and SQLite every row: the non-string half #20336 / #20351 left out #20502's defect shape on the number door.$inmember gets two answers: 200 on memory, 400 on the three SQL cells.No in-repo producer is known to write such a comparand. The dev reported none measured.
Governing text
packages/spec/src/data/filter-boolean-comparand-declared-type.ts, which states the accepted set and the verdict.where { amount: { $gt: true } }), while memory answers no rows and SQLite every row: the non-string half #20336 / #20351 left out #20502 (closed), with triage's direction 5877498426: "The published contract refuses any comparand against a declarednumberfield that is neither a number nor a string the numeric grammar admits: boolean,Date, object and array … The engine door consumes that verdict and nothing else. ⛔ No second rule in the door." This card is the boolean twin of that branch. Under SKILL.md 〈升级与决策〉's first meta-criterion, a branch of the same family inherits the mother's ruling unless a real semantic difference is measured.Scope for whoever takes it (⛔ not a ruling)
INVALID_FILTER/ 400, naming the field, any comparand against a declaredboolean/togglefield (or a boolean-returningformula) that is nottrue,false,1,0, a string the verdict admits, ornull. That covers another number, aDate, an object, and an array at a scalar slot or as a list member.where, the per-aggregationfilterandhaving, for2and aDateand an array$inmember, with thetrue/1controls unchanged.Clause-②: the claim decides. The precedent driver-sql on PostgreSQL answers 500 for a boolean or Date compared against a number field (where { amount: { $gt: true } }), while memory answers no rows and SQLite every row: the non-string half #20336 / #20351 left out #20502 narrows a published verdict.Dedupe
Through
mcp__github__search_issues, repo-scoped, open and closed:where { amount: { $gt: true } }), while memory answers no rows and SQLite every row: the non-string half #20336 / #20351 left out #20502 and objectql: refuse a non-numeric string compared against a number field at the engine's field-aware filter door (400, every driver and position) — the door half of #20336 #20351 are closed: the number door's twin precedents. analytics: a measure naming a missing field 500s with SQLITE_ERROR instead of a 400 naming the field #4437 is closed and unrelated.None covers it.
Dedupe words:
boolean comparand non-string·boolean field integer comparand 500·postgres boolean = integer DATABASE_ERROR·boolean comparand closed set·array $in member boolean splitGenerated by Claude Code