Repository navigation
[spec] FILTER_LOGIC_CASES 补空组合子的布尔单位元四条 —— 需与 driver-mongodb 的单位元归约同时落地 #5239
Description
Activity
分诊(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
认领:PM 循环第 4 批(spec 车道,batch:5;维护者 B 级合批指令 —— 本单锚定,同批携带 #5146 与 #5240 的 spec 半边)
会话:session_01ErbEDVAg1No9gdg1pgDAGB
分支:claude/issue-5239-filter-logic-identity-batch
Worktree: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
交付进展(会话
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
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
- added a commit that references this issue
on Aug 17, 2026
由 #5134 的实现单移交给 spec 车道(#5134 的文件面明令
packages/spec/**零改动,故一致性表扩条不在那一单内)。要做什么
在
packages/spec/src/data/filter-logic-conformance.ts的FILTER_LOGIC_CASES里补四条:{ $and: [] }{ $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—— 四条由 SqlDriver.applyFilterCondition 丢弃编译成空的 $and/$or 子过滤器,而不是套用布尔单位元 —— 与同仓 matchesFilterCondition / driver-memory 相反 #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 侧的做法,可直接照搬的两点:
true/false/clause三值,再据此产出。$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 语义,待维护者拍板)。