Skip to content

fix(driver-mongodb): 空 $and/$or/$not 归约成布尔单位元,非 filter 节点先响亮拒收 (#5239) - #5323

Merged
os-zhuang merged 4 commits into
mainfrom
claude/issue-5239-filter-logic-identity-batch
Aug 5, 2026
Merged

fix(driver-mongodb): 空 $and/$or/$not 归约成布尔单位元,非 filter 节点先响亮拒收 (#5239)#5323
os-zhuang merged 4 commits into
mainfrom
claude/issue-5239-filter-logic-identity-batch

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #5239
同批携带 #5146 spec 半边(已落地)与 #5240 spec 半边(受限携带 → 实测后不进表)

⚠️ 本 PR 交付的是 #5239 的硬约束半边(driver-mongodb 归约),四条一致性表行没有加进去 —— 前提复核推翻了「只差 mongodb 一家」这条。理由与实测在下面第 2 节,已另立 #5322 上交拍板。请连同该单一起验收。


1. 前提复核(先做的事)

按仓规对 origin/main(175d789)逐后端实测四条 case,而不是照抄 issue 正文。实测方法本身有阳性对照:我的 driver-sql 探针复现了 PR #5296 / #5243 已落地 pin 的逐字结果({$not:{stage:'won'}} → 行 2,3,4;{$or:[]} → 零行),说明测的是真行为不是我的假设。

后端 {$and:[]} {$or:[]} {$or:[{a},{}]} {$not:{}}
期望 全部行 零行 全部行 零行
formula 全部行 零行 全部行 零行
driver-memory 全部行 零行 全部行 零行
driver-sql(#5134/PR #5243) 全部行 零行 全部行 零行
driver-sqlite-wasm 全部行 零行 全部行 零行
driver-mongodb(改前) 服务端报错 服务端报错 全部行 零行
read-scope-sql 抛错 抛错 行 1,2 整表
analytics filter-normalizer 抛错 抛错 行 1,2 整表

issue 正文点名的「四个后端」里就含 read-scope-sql,而它和同包的 filter-normalizer 各红四格。两者都在册跑全量 FILTER_LOGIC_CASES(read-scope-sql-conformance.test.tsnative-sql-filter-logic-conformance.test.ts),所以四条一进表就是八格红。

2. 为什么四条没进表

那两处不是「没跟上」,是成文的相反立场:filter-normalizer.ts 的错误消息逐字写着「An empty combinator has no defensible reading — dropping it widens the query, and treating it as "match nothing" silently empties a chart」,而「match nothing」正是 #5134$or: [] 定的答案;read-scope-sql.test.ts:86 还用 toThrowError(/non-empty array/) 把这个抛错钉住了。

「响亮拒收」本身是有先例的答案 —— #5240{ field: {} } 取的就是它。所以这是两条已落地立场必须有一条让步,属公开契约定调,不是实现细节。已立 #5322(含两轴分析与推荐:取单位元 + 可选地在 publish/lint 面对字面量空组合子拒收,这样运行期语义单一而作者错误仍在编写期爆炸)。派发词的硬要求是「批次 PR 必须对自己的内容全绿」,所以红行不进表,实测矩阵原样留在 filter-logic-conformance.ts 里,下一位不必重测。

同理另两族也没进表:

3. 本 PR 实际改了什么

driver-mongodb(#5239 的硬约束半边)

translateFilter 原样透传组合子数组,而 MongoDB 对空数组既不答 TRUE 也不答 FALSE,是第三种行为:拒绝整条查询。改成与 #5134 同一套结构性三值归约:先把整棵树判成 true / false / clause,再据此产出 —— 而不是「编译完再问有没有产出条件」,后者分不清「本来就是空」和「有东西没编译出来」。

  • $and → TRUE,不产出条件。
  • $or → FALSE,产出真实的零行条件 { _id: { $in: [] } }。这一格是关键:「什么都不产出」等于 {},而 find / updateMany / deleteMany{} 读作全部文档,方向正好相反。
  • {}$or 分支仍是 TRUE 析取项,{$not: {}} 仍是零行 —— 这两条 MongoDB 本来就与布尔代数一致,所以归约按结构做而不是只判 length === 0(只判长度会有一半是蒙对的)。
  • 发出的每个 $and / $or 数组因此都保证非空(丢掉单位元成员 ≠ 发一个空数组)。

形状拒收在同一改动里,且先于归约。单位元把「这个节点没有谓词」读作「匹配全部文档」,所以空节点必须只有一个成因。改前实测,这一格比 driver-sql 当年更糟 —— 不是「被静默忽略」,是已经在放宽:

输入 改前译文 含义
{ $or: [new Date()] } { $or: [{}] } 每一份文档
{ $or: 'x' } {} 每一份文档
{ $not: null } {} 每一份文档
{ $or: ['x'] } { $or: [{ '0': 'x' }] } 一个没有文档拥有的字段

updateMany / deleteMany 走同一个 translate 层,在那里「放宽到全部文档」不是行数不对而是数据丢失。现按 ADR-0112 以 INVALID_FILTER / status: 400 拒收并点出位置(filter.$or[0]),消息不带 [mongodb] 前缀(#3867)。判定按原型而非 typeof —— Date / RegExp / class 实例都满足 typeof x === 'object' 却枚举为空。

一处刻意不动:{ field: {} } 仍归为 'clause',译文逐字节不变,不替 #5240 做任何裁决。

packages/spec(仅文档,零运行时改动)

4. 验证

消费半径全跑(表钉住的每一个后端 + 本次改动包):

@objectstack/spec               309 files / 7949 tests passed
@objectstack/driver-mongodb       8 files /  169 passed | 128 skipped
@objectstack/driver-sql          60 files /  765 passed |  44 skipped
@objectstack/driver-memory       11 files /  303 passed
@objectstack/formula             15 files /  340 passed
@objectstack/driver-sqlite-wasm  16 files /  232 passed
@objectstack/service-analytics   42 files /  555 passed
typecheck (spec, driver-mongodb) 通过
check:generated                  9/9 up to date(rebase 到 26e1029 后复跑)
check:driver-conformance         4 drivers x 5 case-sets,20 covered,0 DEBT
check:nul-bytes                  OK(另对改动文件做了 `[\x00-\x08\x0b\x0c\x0e-\x1f]` 自扫,无命中)

skip 不是 pass:driver-mongodb 的 128 skipped 是需要真 mongod 的那半边 —— 本容器取不到 mongodb-memory-server 的二进制。所以新 pin 分两半,与本包既有惯例一致:译文断言永远跑(对这四条,发出的 document 就是语义:{} = 全部,{_id:{$in:[]}} = 零),真 mongod 那半边回答「服务端是否同意」,在 CI 能取到二进制时才跑。

反向验证 —— 方向先预测,再跑

预测:把 mongodb-filter.ts 还原成 origin/main,新 pin 里除「existing translation is untouched」那组控制项外全红

实测 28 红 / 9 绿,方向与预测一致。唯一偏差是我预测绿的数量写成 8 而实际 9 —— 差的那一条是 a field constrained by zero operators is still not ruled on (#5240),它本就该在还原后保持绿(它钉的正是「{stage:{}} 前后逐字节不变」),是我数自己的控制项时漏数了一条,不是方向反了。红的 28 条覆盖三组单位元、嵌套组合、以及全部 15 条形状拒收。


Generated by Claude Code

…tity, refusing non-nodes first (#5239)

`translateFilter` passed combinator arrays through verbatim, and MongoDB
answers an empty one with neither TRUE nor FALSE but a third behaviour: it
refuses the query (`$and/$or/$nor must be a nonempty array`). So `{$and: []}`
and `{$or: []}` reached find/count/updateMany/deleteMany as a server error
carrying no ADR-0112 code, while driver-sql (#5134), driver-memory and formula
all answered them as identities.

Replaced with the same STRUCTURAL three-valued reduction: reduce the whole tree
to true/false/clause first, then emit. Empty `$and` becomes TRUE (no condition);
empty `$or` becomes FALSE and emits a real zero-row condition
(`{_id: {$in: []}}`) — emitting nothing would be `{}`, which find/updateMany/
deleteMany read as EVERY document, the opposite answer. Every `$and`/`$or`
array emitted is therefore guaranteed non-empty.

Shape rejection lands in the same change and runs BEFORE any identity: measured
on main, `{$or: [new Date()]}` translated to `{$or: [{}]}` (every document) and
`{$or: 'x'}` / `{$not: null}` translated to `{}` (every document). updateMany
and deleteMany translate the same `where`, where that is data loss rather than a
wrong row count. Non-nodes now raise INVALID_FILTER / 400 naming the position;
the gate judges by PROTOTYPE, since Date/RegExp/class instances satisfy
`typeof x === 'object'` while enumerating empty.

spec is documentation only: FilterConditionSchema's contract TSDoc now states
the NULL-safe `$not` semantics ruled in #5146, and filter-logic-conformance.ts
records the measured matrix for the three ruled-but-not-yet-enrolled case
families. The four FILTER_LOGIC_CASES rows #5239 asks for are deliberately NOT
added: read-scope-sql and the analytics filter-normalizer, both enrolled
backends, refuse empty combinators fail-closed by design and pinned test, which
contradicts the identity ruling — escalated as #5322.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ErbEDVAg1No9gdg1pgDAGB
@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 5, 2026 3:07am

Request Review

@github-actions github-actions Bot added the size/l label Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/driver-mongodb, @objectstack/spec.

109 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/driver-mongodb, @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/tenancy-modes.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/glossary.mdx (via @objectstack/driver-mongodb)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/driver-mongodb, @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/driver-mongodb, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/driver-mongodb, @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/driver-mongodb, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Copy link
Copy Markdown
Contributor Author

PM 验收(session_01ErbEDVAg1No9gdg1pgDAGB)——通过

进入串行落地链链尾(当前序:#5304#5306#5308#5318#5319#5321#5314#5312 → 本 PR)。轮到时由 PM 通知重建 worktree 同步 + 全量重生成 + 兄弟断言,再翻 ready 并 arm auto-merge。


Generated by Claude Code

claude added 3 commits August 5, 2026 02:47
…ity-batch

Textual conflict: packages/plugins/driver-mongodb/src/mongodb-filter.ts —
both sides rewrote translateFilter/translateCondition (#5239 reduction vs
#5329 array-dialect deletion + #5368 $null gate/path threading). Resolution
keeps both: main's array refusal and path threading, this branch's
three-valued reduction and shape gates; the three helpers both sides defined
(unsupportedFilterError, describeFilterOperand, safeShapePreview) are
de-duplicated onto main's copies.

Semantic reconciliation the textual merge could not see (AGENTS.md s10):
main's #5347 $null comparand gate sat in the emitter, and this branch's
reduction makes emitters skippable by a boolean identity — { $or: [ {},
{ stage: { $null: 'yes' } } ] } would have translated to match-all while
driver-sql refuses it. The gate's load-bearing copy moved onto the
validating walk (reduceFilterKey), mirroring driver-sql's #5368 placement;
the emitter arm keeps its local check. Pinned in
mongodb-null-comparand-refusal.test.ts (three identity-sibling fixtures).

Fixture triage: the 'legacy array dialect is untouched' pin in
mongodb-filter-boolean-identity.test.ts pinned a dialect #5329 deleted —
replaced wholesale with the surviving boundary ([] = absent filter =
match-all, non-empty array refused before the reduction runs).

The reduceFilterKey field-arm comment on { field: {} } is recalibrated to
current main: #5327 gated the shape on the other four backends; this driver
remaining the one still answering it is now tracked by #5376.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ErbEDVAg1No9gdg1pgDAGB
本 PR 的 spec 半边是契约文档,机械合并会把 base 时代的论断带上 main;
逐条对当前 origin/main 实测后校订:

- FilterConditionSchema 的 NULL-safe $not 合规段:read-scope-sql 已由
  #5326 对齐(#5297 关闭)、filter-normalizer 已由 #5335 对齐(#5325
  关闭),七个面全部一致 —— 「尚未合规、指向 #5297」改写为已闭合的事实。
- 「Deliberately NOT declared here」:空组合子单位元由「两立场对峙、
  上交 #5322」改为「#5322 已拍板取单位元,实施在 #5365(排在本 PR 之后
  合入);main 上两个 analytics 编译器今天仍拒收,故本 PR 仍不在此声明,
  声明随 #5365 翻正」;{ field: {} } 由「无后端设闸」改为「#5327 已闸
  四家,driver-mongodb 是唯一还在作答的后端(#5376)」。
- filter-logic-conformance.ts 族 2/3 状态行同步重测:族 2 的后端阻塞
  已清零,唯余 fixture 工作;族 3 的四家闸门已落,阻塞改为表形扩展 +
  mongodb(#5376)。族 1 段落一字未动 —— 由 #5365 在其同步轮删除,
  已约定分工。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ErbEDVAg1No9gdg1pgDAGB
…bee2)

合并 origin/main 后重建时由 gen:schema 写出(先 commit merge 再跑生成,
#5370 的锚点倒退陷阱按序避开):baseRev 28ad90ecdfbee2,随锚点带入
#5312 的 api/ApiEndpoint 键面。check:generated 9/9 up to date,
check:authorable-surface 绿。非手改。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ErbEDVAg1No9gdg1pgDAGB

Copy link
Copy Markdown
Contributor Author

同步轮(2026-08-05,接力,会话 session_01ErbEDVAg1No9gdg1pgDAGB):合入 main@cdfbee2f0,散文论断逐条校订

原实现完成于 base 26e1029;本轮把分支同步到当天 main(领先 26 个提交,含 #5329 / #5368 / #5326 / #5335 / #5327 / #5306 等)。⛔ 无 rebase、无 force-push。merge commit e5f4f16b9,head 806949567

冲突与语义对账(AGENTS.md §10)

唯一文本冲突在 mongodb-filter.ts:两侧都重写了 translateFilter / translateCondition(本分支的三值归约 vs main 的 #5329 数组方言删除 + #5368 $null 闸门/路径线)。解决:两侧语义全保留 —— main 的数组拒收、路径线、$null 闸门 + 本分支的归约与 15 条形状拒收(消息与逻辑逐字节保留);两侧重复定义的三个辅助函数(unsupportedFilterError / describeFilterOperand / safeShapePreview)去重,取 main 的版本。

文本合并看不见的一处联合错误:#5368 把本驱动的 $null 非布尔拒收放在发射器的 $null arm —— 在没有归约的 main 上完备;本分支的归约让布尔单位元可整体短路发射器,合并态下 { $or: [ {}, { stage: { $null: 'yes' } } ] } 会静默译成 match-all,而 driver-sql 对同一输入 400。这正是 #5368 提交说明自己点名的「gate conditional on evaluation order」。对账:闸门的承重份移进校验遍历(reduceFilterKey),与 driver-sql 的落位同构;发射器 arm 保留原检查作局部防御(同一构造器、同一路径拼写,谁先触发线上答案相同)。新增 3 条 pin(mongodb-null-comparand-refusal.test.ts):TRUE 析取项 / FALSE 兄弟键 / $not 内嵌,三种「单位元已定谳」形状下拒收仍触发。

Fixture 三分法的「整体替换」一例:mongodb-filter-boolean-identity.test.tsthe legacy array dialect is untouched 钉住的方言已被 #5329 删除 —— 按幸存边界重写:[] = 缺席的 filter = match-all(不是 $or:[] 的零行),非空数组在归约之前就被拒收(拒收本体由 main 的 mongodb-filter.test.ts 钉住,不重复)。

散文校订清单(每条:原文 → 改后,依据 = 对 main@cdfbee2f0 实测)

位置 原论断(base 时点) 校订后(main 实测)
filter.zod.ts NULL-safe $not 合规段 read-scope-sql / filter-normalizer「仍发裸 NOT(…),tracked by #5297 七个面全部一致:read-scope-sql 由 #5326 对齐(#5297 已关),filter-normalizer 由 #5335 对齐(#5325 已关);段落改记「缺口已闭合」
filter.zod.ts「Deliberately NOT declared here」 空组合子单位元「两立场对峙……上交 #5322(未裁定)」 #5322 已拍板取单位元(2026-08-04);实施在 #5365(排在本 PR 之后);main 上两个 analytics 编译器今天仍拒收空 $and/$or,故声明随 #5365 翻正,不在本 PR」
同上,{ field: {} } 半句 #5240 拍板拒收但无后端设闸」 #5327 已闸 driver-sql / sqlite-wasm / memory / formula;driver-mongodb 是唯一还在作答的后端,新立 #5376 追踪」
filter-logic-conformance.ts 族 2 「两编译器仍裸 NOT,tracked by #5297 后端阻塞清零(#5326/#5335),唯余 fixture 工作(FILTER_LOGIC_ROWS 无可空列,需七个 harness 同步声明)
filter-logic-conformance.ts 族 3 「无后端设闸,repo 四个答案」 #5327 已落四家;mongodb 仍作答(#5376);进表阻塞改为表形扩展(expectRejection)+ spec 侧收窄
filter-logic-conformance.ts 族 1 段落(含 @175d789 矩阵) 一字未动,由 #5365 在其同步轮删除(已约定分工)
mongodb-filter.ts reduceFilterKey 字段 arm 注释 「ruled REJECT but not yet gated in any backend」 #5327 已闸四家;本驱动唯一还在作答(#5376)」;归约判定一行未动(字段键仍 'clause')

PR 正文第 1、2 节的 @175d789 矩阵与立场叙述保留为历史记录(在当时为真;时间线见上表与 #5322)。

验证(merged 态,全部 flock 串行 + --maxWorkers=2)

@objectstack/spec               310 files / 7934 tests 全绿;check:generated 9/9 up to date
                                (含 check:authorable-surface,锚点由 gen:schema 前移至
                                cdfbee2f0 —— 先 commit merge 再跑生成,#5370 陷阱按序避开);
                                tsc --noEmit 通过;check:exported-any 1813 types + 1560 schemas 干净
@objectstack/driver-mongodb     9 files passed | 5 skipped;190 passed | 129 skipped;typecheck 通过
@objectstack/driver-sql         63 passed | 4 skipped / 851 passed | 44 skipped
@objectstack/driver-memory      16 files / 424 tests 全绿
@objectstack/formula            16 files / 357 tests 全绿
@objectstack/driver-sqlite-wasm 18 files / 246 tests 全绿
@objectstack/service-analytics  46 files / 723 tests 全绿
check:driver-conformance        4 drivers x 5 case-sets,20 covered,0 DEBT
eslint(改动 5 文件)           无告警;check:nul-bytes OK + 改动文件控制字节自扫无命中

mongodb 的 129 skipped 不是 pass:需要真 mongod 的那半边(mongodb-memory-server 二进制本容器取不到),译文断言半边(发出的 document 即语义)190 条全跑全绿;CI 有真 mongod 时另半边照常执行。兄弟面(#5306/#5308/#5318/#5319/#5321/#5314/#5312)保持:本分支对 main 的 delta 仅 6 个文件(本 PR 的 5 个 + mongodb-null-comparand-refusal.test.ts 的 3 条新 pin),spec 全量 7934 绿即其证据。

范围外

保持 draft,未挂 auto-merge。


Generated by Claude Code


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 5, 2026 03:09
@os-zhuang
os-zhuang enabled auto-merge August 5, 2026 03:10
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 5, 2026
Merged via the queue into main with commit 71f205d Aug 5, 2026
25 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-5239-filter-logic-identity-batch branch August 5, 2026 03:29
os-zhuang pushed a commit that referenced this pull request Aug 5, 2026
- filter.zod.ts:按 #5323 同步散文预留的交接("The declaration flips to
  stated contract with that PR"),空组合子单位元从「Deliberately NOT
  declared」段转为正式契约段;{field:{}} 半边保持未宣告(#5376 仍开)。
- filter-refusal-envelope.test.ts(#5366 新到):空数组两行从 REFUSALS 翻入
  ACCEPTED(单位元树断言),同一守卫点的非数组拼写补位 REFUSALS,信封不变。
- filter-logic-conformance.ts:族 1 段落按分工删除(四行已进表),族 2/3 原样。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ErbEDVAg1No9gdg1pgDAGB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:data size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[spec] FILTER_LOGIC_CASES 补空组合子的布尔单位元四条 —— 需与 driver-mongodb 的单位元归约同时落地

2 participants