由 #5134 的实现单移交给 spec 车道(#5134 的文件面明令 `packages/spec/**` 零改动,故一致性表扩条不在那一单内)。 ## 要做什么 在 `packages/spec/src/data/filter-logic-conformance.ts` 的 `FILTER_LOGIC_CASES` 里补四条: | filter | 期望 | 依据 | |---|---|---| | `{ $and: [] }` | 全部行 | 空合取 = TRUE(AND 单位元) | | `{ $or: [] }` | **零行** | 空析取 = FALSE(OR 单位元) | | `{ $or: [{ a: 'x' }, {}] }` | 全部行 | `{}` 是 TRUE 析取项 | | `{ $not: {} }` | **零行** | `NOT TRUE ≡ FALSE` | 这张表一加,四个后端(`driver-sql`、`driver-memory`、`formula` 的 `matchesFilterCondition`、`read-scope-sql`)就同时被钉住 —— 这正是 #3774 建这张表的理由。 ## 为什么必须和 driver-mongodb 一起落地(否则一定红) 现状实测: - `formula` / `driver-memory` —— 四条**本来就全对**,加进表里直接绿。 - `driver-sql` —— 四条由 #5134 修好(本 issue 的上游),届时绿。 - `driver-mongodb`(`packages/plugins/driver-mongodb/src/mongodb-filter.ts`)—— 把空数组**原样透传**给 MongoDB,而 MongoDB 对空 `$and` / `$or` **直接报错**(`$and/$or must be a nonempty array`)。所以它今天既不是 TRUE 也不是 FALSE,是第三种行为:**抛异常**。 因此扩表的 PR 必须同时给 `mongodb-filter.ts` 的 translate 层加同一套单位元归约(空 `$and` → 不产出条件;空 `$or` → 产出一个匹配零行的条件,如 `{ _id: { $in: [] } }` 或等价的 `$expr: false`;`$not: {}` 同理归约为零行),否则一致性表一加就把 mongodb 的 cell 打红。两者同 PR,或明确排序后连续两 PR。 ## 参考实现与设计约束 #5134 在 driver-sql 侧的做法,可直接照搬的两点: 1. **结构性归约,不要观察式判空。** 「编译完再问后端有没有产出条件」分不清「因为本来就是空」和「因为有东西没编译出来」;先把整棵 filter 树归约成 `true` / `false` / `clause` 三值,再据此产出。 2. **先做形状拒收,再上单位元。** `$or: [null]` / `$or: ['x']` / `$or: [[…]]` / `$or: [new Date()]` 这类非 filter 节点若不先拦掉,单位元会把它们从「被静默忽略」**升级成「匹配所有行」**,比原 bug 更坏。注意 `Date` / `RegExp` / class 实例都满足 `typeof x === 'object'` 却枚举为空 —— 必须用原型判定,不能只判 `typeof`。 关联:#5134(driver-sql 侧,已实现)、cloud#1073(Turso `RemoteTransport.buildWhereSQL` 同一 bug 与同一修法)、#3774(一致性表的由来)、#5146(`$not` 的另一分叉:NULL 语义,待维护者拍板)。
Activity
os-zhuang commentedon Aug 4, 2026
分诊(engine/services 车道 PM,会话
session_01Pbu27iNUfQCHeuS551Rqo7):落点packages/spec(FILTER_LOGIC_CASES)+driver-mongodbtranslate 层,共享契约面归 spec 车道 —— 打domain:spec+pm:queue经队列标签移交,labeling ≠ claiming,本会话不认领。上游 #5134 的 driver-sql 侧已交付(PR #5243,验收中);「与 mongodb 单位元归约同 PR 落地否则表一加即红」的约束请原样进派发词。注意 #5240({field:{}}三答案)拍板后该 case 也应进同一张表 —— 两单排序由 spec 车道自定。Generated by Claude Code
os-zhuang commentedon Aug 4, 2026
认领:PM 循环第 4 批(spec 车道,batch:5;维护者 B 级合批指令 —— 本单锚定,同批携带 #5146 与 #5240 的 spec 半边)
会话:
session_01ErbEDVAg1No9gdg1pgDAGB分支:
claude/issue-5239-filter-logic-identity-batchWorktree:
objectstack-issue-5239域:
domain:spec(跨域合批,维护者已授权)文件面(跨域声明,全量):
packages/spec/src/data/filter-logic-conformance.ts(FILTER_LOGIC_CASES扩条)、packages/spec/src/data/filter.zod.ts(仅FilterConditionSchema的$notNULL 语义契约 TSDoc,#5146 spec 半边;⛔ 不动 #5306 刚落的 FilterArray 声明)、packages/plugins/driver-mongodb/src/mongodb-filter.ts(单位元归约,与表扩条同 PR 的硬约束)及其测试、spec 生成基线(os-regen 四步)、.changeset/*.md合批构成:(1) #5239 四条布尔单位元 + mongodb 归约同落;(2) #5146 spec 半边(NULL-safe 已随 #5296 进 main,表行应即绿);(3) #5240 spec 半边受限携带 —— 拒收 case 仅当可表达为期望拒收且对当前 main 全绿才进表(其 engine 半边四后端闸门未实现,提前进表即打红四格),否则只留契约注记引 #5240,实测定夺并回报。
Generated by Claude Code
os-zhuang commentedon Aug 4, 2026
交付进展(会话
session_01ErbEDVAg1No9gdg1pgDAGB):PR #5323(draft)。硬约束半边已交付:
mongodb-filter.ts的结构性单位元归约 + 形状拒收(先拒收后归约),含 45 条 pin。顺带堵掉三条改前就已经在放宽的:{$or:[new Date()]}→{$or:[{}]}、{$or:'x'}/{$not:null}→{},全都是「每一份文档」,而updateMany/deleteMany走同一个 translate 层。四条表行没有加进去 —— 本单前提部分不成立。 正文点名的四个后端里
read-scope-sql就红四格,同包的filter-normalizer(native-sql-filter-logic-conformance.test.ts在册跑全表)也红四格。实测(origin/main@175d789):两者对空$and/$orfail-closed 抛错、{$not:{}}给整表、{$or:[{a},{}]}给行 1,2。而且这不是「没跟上」——filter-normalizer.ts的错误消息逐字反对「treating it as match nothing」,read-scope-sql.test.ts:86还把抛错钉住了,是两条已落地立场对立。属公开契约定调,已立 #5322 上交拍板(含两轴分析与推荐),本单待其拍板后补表行。同批的另两族也实测后未进表,理由同样记在 PR 与
filter-logic-conformance.ts的实测矩阵里:#5146 spec 半边的契约 TSDoc 已写进FilterConditionSchema(NULL-safe$not),但跨驱动 case 行受同两个后端阻塞(#5297,已在该单补注filter-normalizer.ts是同缺陷第二份拷贝);#5240 除闸门未实现外,FilterLogicCase本身无法表达「期望拒收」(expected是行 id 列表,空列表 = 匹配零行,恰是裁定没取的 FALSE),要进表得先扩表结构,按纪律不擅自发明。Generated by Claude Code
os-zhuang commentedon Aug 4, 2026
PM 记录(session_01ErbEDVAg1No9gdg1pgDAGB):PR #5323 已验收,交付本单的 driver-mongodb 硬约束半边(空组合子结构性归约 + 非节点形状拒收)与 #5146 的 spec TSDoc 半边。
四条一致性表行没有进表 —— 前提复核推翻了「只差 mongodb 一家」:在册后端
read-scope-sql与 analyticsfilter-normalizer对同四条持成文的相反立场(fail-closed 抛错,有 pin 钉住),已立 #5322 上交拍板。追踪拓扑(PM 裁定,如有异议可 reopen):本单随 PR #5323 合并关闭;四条表行的唯一在册追踪是 #5322 —— 裁决落地的 PR 一并加行,
filter-logic-conformance.ts里已留全部实测矩阵与操作指引,不再双开追踪。#5240 的表结构缺口(FilterLogicCase无法表达「期望拒收」)也已记录在同处,归引擎车道四后端闸门时一并定形。Generated by Claude Code
Merge origin/main (cdfbee2) into claude/issue-5239-filter-logic-ident…
docs(spec): 同步轮散文校订 —— 对 main@cdfbee2f0 实测后落笔 (#5239)
fix(driver-sql): 空 $and/$or/$not 按布尔单位元编译,$or: [] 不再返回全表 (objectstack…
fix(driver-mongodb): 空 `$and`/`$or`/`$not` 归约成布尔单位元,非 filter 节点先响亮拒收 (o…
fix(driver-mongodb): refuse malformed $between, undeclared node-level…