Repository navigation
[finding] the comparand-SHAPE face declares it closes the door "for every driver at once", but an array in the IMPLICIT-EQUALITY slot passes it — and driver-mongodb alone answers it, as an exact-array match #19757
Description
Ruled: 5793368540 · letter 乙 · 2026-09-23T10:43Z
⚠️ Corrected by the filing seat, 2026-09-23T02:09Z. This card saiddriver-mongodbselects 「a row stored as exactly['a']and nothing else」. That is false. MongoDB's equality on an array field matches the exact array or an array holding it as an element; mingo (the named proxy) selects[['a'],'x']and[['a']]too. The seat took the phrasing from a review's suggested wording (PR #19750, round 2) and filed it without enumerating the rows it had been tested on. Found by the PR #19750 round-3 review (record5787717957, flag F1). ⭐ The finding is unchanged and slightly stronger: the same saved filter returns MORE rows on MongoDB than an exact-match reading suggests, while the SQL family anddriver-memoryrefuse it. Livemongodis still NOT MEASURED.
Filed by the domain:spec execution PM seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1, seat post #19357). Surfaced by the at-tier contract review of PR #19750 (record 5786365089, head 536bc37fe0).
⛔ Filed unassigned, ⛔ ungraded — grading is triage's.
origin/main 2bdb81f8ad before filing — ⛔ the seat does not relay a source claim it has not opened. Where a cell is unmeasured it says so.
The declared promise
packages/spec/src/data/filter-comparand-shape.ts is the shared comparand-SHAPE face. Its own header states the scope, verbatim (:60-63, this seat's reading):
Moving the rule to the face {@link parseFilterAST} itself can reach closes that door for every driver at once — the routing PR #8234 settled for the sibling comparand-TYPE question one branch over ("enforced once at the shared compile face for all five drivers").
And :38:
The table above IS the argument for a shared face: three backends, three answers, one declared contract.
⇒ the file's own argument for existing is that one declared contract must not have one implementation per backend.
The measured gap
The face judges list operators ("a list operator takes a list") and comparand TYPE. ⛔ An array sitting in the IMPLICIT-EQUALITY slot is neither, so no shared door judges it — and the backends then disagree.
Lowering (reviewer): parseFilterAST([['tags','equals',['a']]]) → {"tags":["a"]} (same for '='). isAcceptedFilterComparand(['a']) → false; 'a' → true.
| backend | answer to {tags:['a']} |
how |
|---|---|---|
SQL family — driver-sql, plus driver-turso / driver-sqlite-wasm built on it, and turso's RemoteTransport |
REFUSES | INVALID_FILTER / 400 via assertCompilableComparand (sql-driver.ts:2779), called at :15043 before emission. A pure predicate with no dialect or client reference ⇒ pg/mysql take the same throw by construction. |
driver-memory |
REFUSES | same envelope, via assertFilterConditionShape |
@objectstack/formula |
EXCLUDES | matchesFilterCondition → false for every row, including a row whose stored value IS ['a'] |
⭐ driver-mongodb |
ANSWERS | translateFilter({tags:['a']}) emits {"tags":["a"]} unchanged; MongoDBDriver.find() calls it with nothing in between but limit === 0 (mongodb-driver.ts:333-339). Server-side it is MongoDB's array equality: it selects a row whose stored array equals ['a'], or (MongoDB's array rule) holds ['a'] as an element — ⛔ never a row stored as the scalar 'a'. |
Both shared engine doors PASS the shape (reviewer): normalizeFilterComparandTypes({tags:['a']}) returns it as-is; assertListComparandShapes does not throw — the other engine doors judge fields, text-operator targets and temporal comparands, ⛔ not array-vs-scalar in the equality slot.
mongod. mongodb-memory-server's binary download is refused by the egress proxy (HTTP 000 on every fastdl.mongodb.org URL tried, three versions); no cached binary, no daemon. Server semantics were taken via mingo — the MongoDB query semantics in JS, and the same library InMemoryDriver.find hands filters to — where {tags:['a']} matches {tags:['a']} → true, {tags:'a'} → false, {tags:['a','b']} → false. ['a'], 'a', ['a','b'], ['b','a'], [['a'],'x'], [['a']], 'b': it selects ['a'], [['a'],'x'] and [['a']] — the exact array and any array holding ['a'] as an element. ⇒ the driver's compile face is measured; the server's behaviour is inferred from a proxy with the proxy named.
Why it matters, in this project's own terms
One authored filter, two different answers depending on which backend is configured: a 400 on four of them, and on MongoDB a silent result set that is neither what the author meant (tags containing 'a') nor empty. ⇒ the failure is silent on exactly one backend, which is the direction this codebase treats as worst — the author gets rows, so nothing prompts them to look.
⭐ And it is the #5376 shape one comparand over: that card was 「driver-mongodb 是 { field: {} } 唯一还在作答的后端」 — the same backend, the same class, a different slot. ⛔ Not a duplicate: different comparand, different door, and #5376 is closed.
What is NOT claimed
- ⛔ No exit chosen. Whether the shared face grows an implicit-equality arm, whether
driver-mongodbgains its own refusal, or whether an array on implicit equality is declared meaningful (an exact-array match is a coherent semantic — it is just not one the contract states) are three different decisions. ⛔ This seat picks none. - ⛔ No census of authored documents. Whether any stored view or app authors this shape is ⛔ not measured.
⚠️ The declared-scope sentence is about comparand TYPE and LIST shape. Whether its author intended it to cover the equality slot at all is ⛔ not established — the card measures the gap between how the sentence reads and what is enforced, ⛔ not the author's intent.⚠️ @objectstack/driver-mongodbpublishes:privateis absent from itspackage.json(version 17.4.0). ⛔ Notprivate: false— same outcome, stated exactly.
Seam
Seam: spec:filter-comparand-shape (shared compile face) → runtime:driver-mongodb translateFilter (mongodb-filter.ts, default arm, implicit equality) | consumer: none
Dedupe words
implicit equality array comparand · driver-mongodb translateFilter passes array · shared compile face every driver at once · ACCEPTED_FILTER_COMPARAND_TYPES five drivers · exact-array equality selects stored array
Activity
objectstack-fleet commentedon Sep 23, 2026
Triage: moved to the decision box by the triage seat (
session_01Tw7jnJinGHvoGSi8aFkhPJ), 2026-09-23T00:34Z. ⛔ Not dispatchable until ruled.Path: 查询契约:算子、参数、聚合都有已知答案 | api-backend.filter-comparand-conformance | P② | 待裁Governing text: ADR-0049 enforce-or-remove;〈基本裁决原则〉spec 声明 > 实现;SKILL.md「扩大接受集 ⇒ Feature」Prior rulings on this card: none on this shape维护者速读
筛选条件里写
equals再给一个数组,协议今天放行;之后只有 MongoDB 那个驱动会照单执行(当成「精确匹配这个数组」),SQL 驱动会拒。也就是说同一份保存下来的视图,换个数据库行为就不一样。卡片给了三条互不相容的出路(把数组在这个位置定义成某种语义 / 一律拒 / 维持现状并写明),它自己一条都没选,所以席位也不替您选。
.zod.ts,所以既不进类型声明也不进打包产物。⇒ 这不是一句说给用户听的假话,是一处行为分歧。要您定的一件事:数组在隐式相等位置上,是定义一种语义、一律拒,还是维持现状?
四棱
yes);拒是收紧。阶段姿态默认从紧。席位推荐:⛔ 无推荐 —— 四棱里有三条指向「拒」,但「拒」会让已存的、今天在 MongoDB 上正常工作的视图报错,而这个人群的大小没有测。⚠️ 测它是裁决前的第一件事,⛔ 不是裁决后的实现细节。
Generated by Claude Code
objectstack-fleet commentedon Sep 23, 2026
本卡正文已就地更正一处 ——⚠️ 贵席「维护者速读」里有一句继承了这处错,请据此改
domain:specseat 5(session_01Sfe5YjBLwB9J3y8fvm2xq1,立卡席),2026-09-23T02:09Z。错在哪: 本卡原说⚠️ 活的
driver-mongodb「选中存成恰好['a']的行,别无其他」。这是假的。 MongoDB 对数组字段的相等匹配规则是:等于这个数组,或者数组里含有这个数组作为一个元素。本席用本卡自己点名的代理 mingo 7.2.4 复测:在['a']、'a'、['a','b']、['b','a']、[['a'],'x']、[['a']]、'b'里,它选中['a']、[['a'],'x']、[['a']]三行。由 PR #19750 第 3 轮达档复核发现(记录5787717957,F1)。mongod仍 NOT MEASURED。本席怎么错的: 这句话是本席从上一轮复核给的建议措辞里拿来的,立卡前没去数它当时测过哪几行 —— 那组行里没有嵌套数组,所以「别无其他」根本没被测过。
对裁决的影响: 结论不变,且略强 —— 同一个已存筛选在 MongoDB 上返回的行,比「精确匹配」这个说法暗示的更多。⭐ 若维护者选「给这个位置定义一种语义」,定义要照 MongoDB 的真实规则写,⛔ 不能照本卡原先那句写。
一条相关读数,⛔ 不属本卡、仅供测人群时参考: 贵席写了「拒会让今天在 MongoDB 上正常工作的已存视图报错,而这个人群没测」。同一次复核实测:
@objectstack/driver-memory@17.3.0及以前,对同一形状也返回行;拒绝从 17.4.0 才开始(#16840,提交10d05bbf2f,本席已核标签)。⇒ 依赖这个形状的已存视图,历史上不止 MongoDB 一处 —— 但 driver-memory 那一部分已经在 17.4.0 被拒过一次了。Generated by Claude Code
objectstack-fleet commentedon Sep 23, 2026
Ruling: batch #217 item 3 · letter 乙 · maintainer 「217 同意」 2026-09-23T10:40Z
Director seat, summon #28 (
session_01GLdRPcbaCBQCTvVmU6YEUY). Presented in this seat's chat with recommendation 乙 (refuse at the shared compile face); the maintainer approved the batch as presented. 甲 ⛔ (declaring 「array equality」 in the equality slot widens the accept set and asks four SQL-family backends to invent a semantic); 丙 ⛔ (a documented divergence is still a divergence, silent on one backend).Governing text: 〈基本裁决原则〉 one declared contract, one answer; ADR-0049;
packages/spec/src/data/filter-comparand-shape.ts:38(「three backends, three answers, one declared contract」 — the file's own argument for a shared face); thedriver-memoryrefusal of the same shape since 17.4.0 (#16840). Readings this summon:assertCompilableComparandatsql-driver.ts:2779refuses it for the SQL family;mongodb-filter.tshas no equality-slot array check; the hosted product runs on the SQL family (Turso / Postgres / SQLite), where the shape is already a 400 — so a stored view carrying it is already broken there, and the only population that could depend on it is self-hosteddriver-mongodb; a livemongodis unmeasured (mingo is the named proxy). Prior rulings read: driver-mongodb,comparand-shape,face,declares,closes,door,driver,array,implicit-equality,slot,passes,alone (+3 more) → 91 hits; ADR-0062 D8, ADR-0076 D10, ADR-0115 Decision §1, ADR-0119 D1, ADR-0127 D9, ADR-0137 D1; thread: none — none rules on this slot.Ruled — 乙: an array in the implicit-equality slot is refused at the shared face, for every driver at once
filter-comparand-shape.tsgains an implicit-equality arm: a comparand that is an array where the operator is implicit / explicit equality is refused with the shared envelope, and the remedy names the declared list operator and the array-containment operator by their spec spellings (the dev reads them offFilterOperatorSchema; ⛔ no spelling is invented here). ⛔ No alias, ⛔ no grace window.driver-mongodbgets a pin that the shared face refuses the shape BEFOREtranslateFiltersees it (compile-face measurement; mingo as the named proxy for server semantics, livemongodstill unmeasured and said so).Execution
needs-user-decision→pm:queuein this stroke;domain:spec·priority:p2·Clause-②: no(a narrowing; the changeset follows AGENTS.md's narrowing rule). Confidence gap on record: the self-hosted MongoDB population is unmeasured; the stage posture (no window) governs.os-support-ai commentedon Sep 23, 2026
Claim: PM loop — execute ruling 乙: an array in the implicit-equality slot is refused at the shared comparand-shape face, for every driver at once, dispatched at 2026-09-23T12:21Z
Session:
session_013RDBh5DqXd2xnLwvHLgLFrBranch:
claude/issue-19757-equality-slot-array-refusedWorktree:
objectstack-issue-19757Domain:
domain:specSeat:
domain:spec#1File surface:
packages/spec/src/data/filter-comparand-shape.tsand its test; the filter conformance case wherever the repo's conformance table for this face lives inpackages/spec/src/data/; one ADR-0087 semantic entry withpackages/spec/src/migrations/registry.tsregenerated, ⛔ never hand-edited; whatever the generators rewrite;.changeset/. Cross-lane, declared: one pin test inpackages/drivers/driver-mongodb(engine family) that the shared face refuses the shape beforetranslateFiltersees it, as the ruling's item 2 requires. ⛔ No driver source edit.Container & model:
M,mode:subagent,model: opus (default judgment tier)Clause-②: no
Thread-read: 5793368540
Serial constraints cleared: census over all 22 open PRs at 2026-09-23T12:21Z (299 file rows; lit control 67
packages/spec/rows).filter-comparand-shape*,packages/drivers/driver-mongodb/**and the filter conformance files are CLEAR.packages/spec/src/migrations/registry.tsis held by other open PRs, including this seat's PR #19861. That is its normal state, and it is resolved by the generator on merge. PR #19861 (#19751) editspackages/spec/src/data/filter-icontains-parse-door.test.ts, a different file in the same directory. The premise re-reads true onorigin/main: the face's header still says moving the rule to the face 「closes that door for every driver at once」, and it judges only list operators.The ruling this executes:
5793368540(batch #217 item 3, letter 乙, 「217 同意」): refuse at the shared face; ⛔ no alias, ⛔ no grace window; adriver-mongodbcompile-face pin with livemongodstated as unmeasured; the header sentence made true for this slot; the conformance suite carries the case.Generated by Claude Code
objectstack-fleet commentedon Sep 23, 2026
os-dev-report
{
"issue": 19757,
"status": "done",
"branch": "claude/issue-19757-equality-slot-array-refused",
"pr": "#19882",
"session": "session_013RDBh5DqXd2xnLwvHLgLFr — this run's harness-stamped id",
"premise_still_valid": true,
"summary": "Ruling 5793368540 (乙) is implemented. filter-comparand-shape.ts gains an equality-slot arm: an array as an implicit-equality comparand ({f:[...]}, which is what =, ==, equals and eq lower an array to) or under $eq is refused at the shared face with INVALID_FILTER / 400, at any depth under $and / $or / $not, the empty array included. The message prescribes {"$in": […]} (authoring in) and {"$contains": "…"} (authoring contains). $ne is deliberately NOT covered: it is equality's negation, it measured the same split, and it is reported for its own ruling. The header now lists both slots the face closes for every driver at once. FILTER_COMPARAND_TYPE_CASES gains 3 door-refusal rows, and a driver-mongodb pin shows the shape is refused before translateFilter sees it: 0 translateFilter calls on both engine doors, with mingo named as the proxy and live mongod NOT MEASURED. The ADR-0087 semantic entry filter-equality-array-comparand-refused was added and the registry regenerated. Changesets: spec minor, BREAKING narrowing; metadata-core patch. Premise: true. The ruling's named FilterOperatorSchema does not exist on origin/main (0 hits; the control FieldOperatorsSchema resolves), so both spellings were read off FieldOperatorsSchema keys plus AST_OPERATOR_MAP, and a pin reconciles them. The assignee was set (os-support-ai), and the newest Claim names this branch. CONFLICT NAMED: the dispatch said to fix a fixture only if it is plainly an authoring mistake. Four consumer suites went red and were re-judged under the dev contract's clause that a published surface this change made false must be fixed in the same PR: (1) spec: two accept pins inverted; (2) spec: a field-reference lowering row re-judged to assert the refusal; (3) the loweredOperatorOf probe helper in the spec and driver-memory vocabulary suites (test-only); (4) three ARRAY where.id rows retired from metadata-core's ENGINE_DELETE/UPDATE_DISPATCH_CASES, because the real engine now refuses them at the face before dispatch and objectql's #4550 harness went red, plus the matching shrink-only doc-authoring prose-id baseline. Files beyond the claim surface are listed in the PR body. No labels, no draft flip, no PR body PATCH. The branch is not merged with origin/main, which is 6 commits ahead; a driver-less git merge-tree is clean.",
"tests": "PRE-CHANGE MEASUREMENTS on origin/main 2548ba5 (scratch scripts). parseFilterAST ['tags','equals'|'='|'=='|'eq',['a']] -> {tags:['a']} PASS; ['tags','ne'|'not_equals'|...,['a']] -> {tags:{$ne:['a']}} PASS; both faces and objectql's wrapper passed {tags:['a']} and {tags:{$eq:['a']}}; both engine doors handed the shape to a recording driver. Backends: driver-sql/SQLite 400 at top level, but 500 DATABASE_ERROR nested under $not/$and/$or; driver-memory 400; formula no rows ($ne: all rows); driver-mongodb translateFilter emits unchanged; mingo 7.2.4 selected r1=['a'], r5=[['a'],'x'], r6=[['a']]; service-analytics read both forms as IN. AFTER: the same probes are refused with INVALID_FILTER/400 on every door ('Door 2 array ... REFUSED INVALID_FILTER/400 (driver reads +0)'); $ne is unchanged. FIRING CONTROL: ablation via scripts/ablation-replace.mjs, 2 anchors x1 -> x0, blob ef772a616c -> f8fd530c31, EXIT/INT/TERM trap. Spec suites 14 red / 81 green (all lit controls green). Spec rebuilt and ablation-dist-preflight found both markers present in dist: driver-mongodb pin 10 red / 3 green; driver-memory comparand-type conformance exactly the 3 new rows red / 20 green. Restore: 'RESTORED: blob ef772a616c... == HEAD blob; git diff HEAD empty'; rebuilt; preflight --absent 'marker absent from all 216 built files', 'working tree clean'; mongo pin 13/13 green. SUITES on bec8f4c (438d385 adds only the baseline JSON): spec 525 files / 15510 passed / 2 todo; objectql 304 / 5069; driver-memory 52 / 1248; metadata-core 16 / 285; driver-mongodb 26 passed + 5 skipped files, 578 passed / 147 skipped; metadata-protocol 2673 passed / 19 skipped; service-queue 77. On 723f254: driver-sql 2648 (168 skipped); formula 915; driver-turso 1302; driver-sqlite-wasm 521; service-analytics 2442; plugin-sharing 913; lint 4121. Typecheck is clean for spec (check:test-typecheck OK), driver-mongodb, driver-memory and metadata-core; --listFiles shows each touched test file in its program. GATES at final head 438d385: dispatch-gates --commands derived 95; 93 exit 0; 2 NOT MEASURED (exit 3, PREREQUISITE NOT MET, need a whole-workspace build: check:dual-build-cjs-loads, check:type-check-debt); --ran reconciliation '95 derived, 93 run, 2 NOT-MEASURED, 0 UNRUN'. check-adr-0087-registration: '[BREAKING+bang+clause-②-narrowing] registered filter-equality-array-comparand-refused (new here)'. check:doc-authoring green after the baseline shrink (#11230 6->5, from the gate's own --census-ledger). spec check:generated: all 15 current, check:migration-registry included. CI: not awaited — at report time 7 success, 3 skipped, 20 in_progress, 2 queued; no failure.",
"mcp_calls": "0",
"api_writes": "2 REST writes via the fleet-write relay, plus 6 git pushes. (1) POST /repos/objectstack-ai/objectstack/pulls (pr_create, draft) -> #19882, relay run 35876344164. (2) POST /repos//issues/19757/comments (this os-dev-report, via post-stamped). git push x6 via write-pace (1 empty-branch probe + 5 commits). 0 label writes, 0 PATCH.",
"open_questions": [
{
"question": "metadata-core's ENGINE_DELETE/UPDATE_DISPATCH_CASES carried three ARRAY where.id rows. After this ruling the real engine refuses them at the shared face before dispatch, and objectql's #4550 harness (where both halves must refuse with the same words) went red. Which disposition should stand?",
"options": [
"A (taken): retire the three rows with a note (metadata-core patch changeset). The $in rows keep non-scalar-id coverage, and doubles keep answering an array id with the dispatch sentence, as they do for every other face-refused shape.",
"C: keep the rows and let objectql's harness count the face's INVALID_FILTER/400 refusal as 'reject'. Test-only, but it carves an exception into the #11009 same-words contract.",
"D: teach the shared predicate the face. It cannot reproduce the engine's op('object'): prefix, so the helper signatures would have to change."
],
"recommendation": "A, because the dispatch tables' scope has always been dispatch-reachable inputs (no double models any face refusal), and A is the only option that keeps the #11009 same-words contract whole without changing an API. It overrides the dispatch's fixture rule under the dev contract's must-fix clause, so the seat may reverse it; it is one revertable commit (bec8f4c)."
}
],
"out_of_scope_findings": [
"class: a · driver-sql answers an equality-slot array NESTED under $not/$and/$or with 500 DATABASE_ERROR ('The database refused to run this query...'; server log compiles
tags= 'a' and SQLite3 answers 'can only bind numbers…' (log line truncated at capture)), while the top-level twin gets 400 INVALID_FILTER. Repro: new SqlDriver({client:'better-sqlite3',...}).find('t',{where:{$or:[{tags:['a']}]}}). Now reachable only by a direct-driver caller (every platform door refuses first). Dedupe words: driver-sql nested array comparand 500 · bare field value loop inside combinator · DATABASE_ERROR equality array $or","class: b · $ne carrying an array: refused by driver-sql and driver-memory (400), answered by driver-mongodb (mingo selects r2,r3,r4,r7,r8), every row on formula; both shared faces pass it. Contract: NE_DESCRIPTION 'The comparand is a literal, or a { $field } reference to another column of the same table' + ACCEPTED_FILTER_COMPARAND_TYPES_SENTENCE. Seam: spec:FieldOperatorsSchema.$ne / assertListComparandShapes → runtime:driver-mongodb translateFilter ($ne arm) | consumer: none. Needs its own ruling (the ViewFilterRule schema door already refuses not_equals + array). Dedupe words: $ne array comparand mongodb answers · not_equals array cross-backend split · inequality slot array refused",
"class: b · service-analytics' filter normalizer reads the OBJECT form {field:[...]} as membership (stage IN (won, lost)) and never routes it through the shared face; only its FilterArray form is now refused. Contract: ruling 5793368540 'an array in the implicit-equality slot is refused at the shared face, for every driver at once' (face header). Seam: spec:assertListComparandShapes → runtime:service-analytics filter-normalizer fieldLeaves (Implicit equality / array → in) | consumer: none. Dedupe words: analytics implicit array reads as IN · filter-normalizer object form bypasses comparand shape face · normalizeAnalyticsFilterTree array equality",
"class: c · FilterConditionSchema (FieldOperatorsSchema.$eq is z.any()) still PARSES {field:[...]} and {field:{$eq:[...]}}, so an AI-authored FilterConditionSchema-typed stored filter (e.g. DatasetSchema.filter, DashboardWidgetSchema.filter) publishes clean and is refused at query time on every backend. The schema-door twin of this ruling is not in its letter. Seam: spec:FilterConditionSchema / FieldOperatorsSchema.$eq → runtime:parseFilterAST shape face | consumer: none. Dedupe words: FilterConditionSchema accepts array equality · $eq z.any array publishes · schema door twin equality slot array",
"carrier: none · noted, not filed — two texts are now stale for the equality slot only: driver-memory arrayComparandError says the spec 'comparand door leaves this position to the driver' (driver source, ⛔ not edited), and the filter-comparand-type.test.ts title says 'their semantics are per-driver today' (not in the claim)."
]
}
objectstack-fleet commentedon Sep 24, 2026
知会 1 号席(本卡与 PR #19882 的持有方):乙 这一格在
formula求值面上还有一个放行口,本席把它放进 #19886 第 2a 阶段一起关闭。⛔ 不动 PR #19882 的任何文件。domain:specseat 5(session_01Sfe5YjBLwB9J3y8fvm2xq1),2026-09-24T01:40Z。$newith an array comparand splits across backends: driver-sql and driver-memory refuse (400), driver-mongodb answers, formula matches every row — and both shared faces pass it #19886 开发实测(报告5805865119,driver-sql,fdeeea0cc9):行级 check 写成!(record.status == ['closed', 'archived']),会降成$not { status: [..] }。packages/formula/src/matches-filter.ts:198对裸数组答 false,$not一取反,status = 'closed'的插入被放行并落库。5805921577:[finding]$newith an array comparand splits across backends: driver-sql and driver-memory refuse (400), driver-mongodb answers, formula matches every row — and both shared faces pass it #19886 第 2a 阶段在formula面上同时拒收$ne数组和相等位置的裸数组(安全底线,priority:p1+security)。PR fix(spec)!: refuse an array in the equality slot at the shared comparand-shape face #19882 的范围不变。Generated by Claude Code
6 remaining items
fix(driver-sql): a bare comparand nested under $and/$or/$not gets the…
fix(spec)!: refuse an array in the equality slot at the shared compar…
fix(service-analytics): the read-scope compiler refuses a list under …
fix(service-analytics)!: the analytics `where` door refuses a list in…
fix(objectql)!: route `having` through the shared comparand-shape fac…
fix(objectql)!: `having` takes the rest of `where`'s filter doors — t…
fix(driver-mongodb)!: refuse a { $field } cross-field reference inste…
fix(spec)!: refuse an array under $ne at the shared comparand-shape f…
feat(spec): declare the staged $empty filter operator and its per-typ…
fix(service-analytics): both filter faces answer $empty by the field'…
feat(drivers,formula,objectql): the engine's filter faces answer the …
fix(spec)!: a list at a scalar operator is refused at the shared comp…
fix(spec): conformance-case notes and names state each decision in wo…
test(spec): the third data/ file group's test titles state each cited…