Skip to content

test(drivers): filter-logic 标准收编第五个 backend —— driver-mongodb 与 driver-sqlite-wasm 两条 DEBT 同 PR 清账 (#4405) - #4596

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-4405-filter-conformance-mongo
Aug 2, 2026
Merged

test(drivers): filter-logic 标准收编第五个 backend —— driver-mongodb 与 driver-sqlite-wasm 两条 DEBT 同 PR 清账 (#4405)#4596
os-zhuang merged 2 commits into
mainfrom
claude/issue-4405-filter-conformance-mongo

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#4405

问题

FILTER_LOGIC_CASES(#3774)的开篇说自己是「the four independent FilterCondition backends are each checked against」的共享标准。实际上有五个:driver-mongodbtranslateFilter 是完全独立的第五个实现,$and / $or / $not 的翻译跟 SQL 编译器、内存匹配器一行代码都不共用 —— 它是被漏掉的,不是被排除的。而且它是唯一一个目标语言拼不出这套标准的 backend:MongoDB 根本没有文档级 $not(服务端直接回 unknown top level operator: $not),所以否定必须以 $nor 出去,分支自己的 key 必须留在同一个文档里、$and/$or 子句被抬到它旁边。这条路线从来没被共享用例验证过。

driver-sqlite-wasm 继承 SqlDriver 的过滤编译器,但从没让这张表走过它自己的 sql.js 引擎。

scripts/check-driver-conformance.mjs 里的两条 DEBT 就是这两格,本 PR 同时清掉 —— 只删条目不写套件会挂 CONSUMED,写了套件不删条目会挂 RECONCILED,所以必须同一个 PR。

改了什么

driver-mongodb 把这张表跑两遍,拆分是刻意的:

  • mongodb-filter-logic-translation.test.ts —— 无服务器,永远会跑。把每条共享用例喂给 translateFilter,再把它吐出来的 MongoDB 查询文档在共享 fixture 上求值。translateFilter 是纯函数,而 mongodb-memory-server 要从 fastdl.mongodb.org 下 ~123 MB 二进制 —— 「只有能下二进制的机器才抓得到的缺陷」在受限网络上等于没人抓得到,这也正是 test-mongod.tsObjectQL silently drops unsupported predicate keys; findOne then returns the first row #4419 那对套件存在的理由。
    文件里那个进程内的求值器是刻意严格的:任何它没建模的形状一律 throw,而不是悄悄判 true —— 文档级 $not 会带着服务端的原话抛出来。比真实引擎更宽松的替身会把套件变成坏代码的绿灯(ObjectQL silently drops unsupported predicate keys; findOne then returns the first row #4419 点名的那个坑),所以它自己的判别力也被钉住了:有几条用例要求「被放宽的文档必须让它所放宽的那条用例失败」,这样「全绿」就不可能等于「求值器对什么都点头」。
    filter-logic conformance 少了两个 backend:MongoDB 的 translateFilter 从来没被 #3774 的标准收编 #4405 点名的两个风险区还额外有字面 wire-shape 断言:$not$nor(且与同分支的兄弟 key 以 $and 相连)、$or 分支里的嵌套 $and 保持嵌套而不是被摊平。
  • mongodb-filter-logic-conformance.test.ts —— 同一张表打真 mongod(createTestMongod),回答前一半答不了的那个问题:MongoDB 同不同意。二进制拉不到时干净地跳过(不是静默通过);本环境 403 拉不到,所以本地是 skip,CI 会真跑。

driver-sqlite-wasmsqlite-wasm-filter-logic-conformance.test.ts 让同一张表走它自己的引擎。编译器是继承来的,这里不重新实现任何东西;钉住的是另一半:嵌套的 (… AND …) OR (… AND …) 必须活着穿过那个自定义 sql.js dialect 的编译、绑参和回程 —— 跟它的 temporal / pagination 套件为各自子句覆盖的是同一个接缝。之所以当初记 DEBT 而不是 EXEMPT:「继承了所以没问题」正是那两个套件要否证的假设,而否证它的是套件,不是 ledger 条目。

没有发现翻译分歧

translateFilter 今天对全部 17 条共享用例的回答都是对的,$not 在分支内、$and 嵌在 $or 里都包括在内,所以本 PR 不改任何翻译逻辑。变的是:下一次改它的人没法悄悄放宽一个过滤条件。

两个套件都验证过是有判别力而非装饰:把 #3774 的误编译重新引入(把 or 传进分支自身的内容),mongodb 翻译套件 26 条里挂 15 条,wasm 套件 18 条里挂 13 条。另外把 $nor 换成文档级 $not(也就是「MongoDB 有 $not 吧」这种想当然的改法)时,那条专门的不变量断言会点名报错。

验证

$ node scripts/check-driver-conformance.mjs
driver FILTER_LOGIC TEMPORAL TEMPORAL_TIME PAGINATION PAGINATION_UNORDERED
driver-memory ok ok ok ok ok
driver-mongodb ok ok ok ok ok
driver-sql ok ok ok ok ok
driver-sqlite-wasm ok ok ok ok ok
check-driver-conformance: OK — 20 covered cell(s), 0 in the DEBT ledger, 0 exempt.
$ pnpm --filter @objectstack/driver-mongodb test
Test Files 7 passed | 5 skipped (12)
Tests 132 passed | 121 skipped (253) # 5 skipped = 拉不到 mongod 的套件
$ pnpm --filter @objectstack/driver-sqlite-wasm test
Test Files 16 passed (16)
Tests 232 passed (232)
$ pnpm --filter @objectstack/driver-mongodb typecheck # tsc --noEmit,无输出
$ pnpm --filter @objectstack/driver-sqlite-wasm typecheck # 同上
$ pnpm --filter @objectstack/spec check:generated # ✓ All 8 generated artifacts are up to date
$ pnpm --filter @objectstack/spec test
Test Files 287 passed (287)
Tests 7270 passed (7270)

ledger gate 的两个反向对照(都如注释所述地挂了):把 wasm 套件挪走 → CONSUMED: driver-sqlite-wasm does not run FILTER_LOGIC_CASES;套件在但把条目加回去 → RECONCILED: driver-mongodb now runs FILTER_LOGIC_CASES …, but the ledger still carries a DEBT entry for it. Delete the entry.--self-test 也是绿的。

CI 上要看的一点: 本地 mongod 拉不到,mongodb-filter-logic-conformance.test.ts 是 skip 的 —— 请在本 PR 的 CI 上确认它真的跑了(18 条,而不是 18 skipped)。

顺带

packages/specfilter-logic-conformance.ts 的头注释和 data/index.ts 的导出注释原来写「four backends」,现在写五个并点名第五个 —— 纯注释,没有 schema、导出或生成物变化(check:generated 全绿佐证)。

🤖 Generated with Claude Code


Generated by Claude Code

…lter-logic standard (#4405)
`FILTER_LOGIC_CASES` (#3774) called itself the standard "the four independent
FilterCondition backends" are checked against. There are five: `driver-mongodb`'s
`translateFilter` is an independent implementation whose $and/$or/$not translation
shares no code with the SQL compiler or the in-memory matcher, and it was missed
rather than excluded. `driver-sqlite-wasm` inherits SqlDriver's compiler but had
never run the table through its own sql.js engine.
- `mongodb-filter-logic-translation.test.ts` — server-free: drives every shared
case through `translateFilter` and evaluates the emitted MongoDB document over
the shared fixture with a deliberately strict in-process reader (unmodelled
shapes throw; a document-level `$not` throws by name, because the server
rejects it). Wire-shape pins cover #4405's named risk areas ($not → $nor,
nested $and inside $or), and negative controls keep the reader discriminating.
- `mongodb-filter-logic-conformance.test.ts` — the same table against a real
mongod via `createTestMongod`, skipping cleanly when the binary is unreachable.
- `sqlite-wasm-filter-logic-conformance.test.ts` — the same table through the
wasm driver's own engine.
No translation change: `translateFilter` answers all seventeen cases correctly
today. Both DEBT entries are deleted from `scripts/check-driver-conformance.mjs`
in the same commit, so the matrix is ok/ok for both cells and the ledger is empty.
The spec's "four backends" prose now says five and names the fifth.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012C2cd7tL8QDoZ2QKN3djJ5
@vercel

vercelBot commented Aug 2, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 2, 2026 9:36am

Request Review

@github-actionsgithub-actionsBot added size/l documentation Improvements or additions to documentation protocol:data tests tooling and removed size/l labels Aug 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

107 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 packages/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @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/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/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/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/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/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/kernel/runtime-capabilities.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/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/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.

@os-zhuangClaude

Copy link
Copy Markdown
ContributorAuthor

CI 全绿(21 个 check,2 个被 path filter 跳过),其中最关键的一条 —— mongod 那半区在 CI 上真跑了,不是 skip

driver-mongodb 的测试并不在 Test Core 里,而是挂在 Temporal Conformance (live PG + MySQL) 这个 job 的 non-SQL 腿上(TZ: America/New_York 偏移时区),日志如下:

packages/plugins/driver-mongodb test: ✓ src/mongodb-filter-logic-translation.test.ts (26 tests) 30ms
packages/plugins/driver-mongodb test: Downloading MongoDB "8.2.6": 0% (0mb / 122.6mb)
packages/plugins/driver-mongodb test: Downloading MongoDB "8.2.6": 100% (122.6mb / 122.6mb)
packages/plugins/driver-mongodb test: ✓ src/mongodb-filter-logic-conformance.test.ts (18 tests) 254ms
packages/plugins/driver-mongodb test: Test Files 12 passed (12)
packages/plugins/driver-mongodb test: Tests 253 passed (253)

12 个文件全 passed、253 条全 passed、0 skipped —— 二进制下下来了,17 条共享用例是打在真 mongod 上过的,顺带也证明了这半区在非 UTC 进程时区下同样成立。真实引擎与无服务器求值器对这张表的回答一致,即「翻译层没有分歧」这个结论有两个独立证据。

Test Core (1/2) 里 wasm 那条:

 ✓ src/sqlite-wasm-filter-logic-conformance.test.ts (18 tests) 281ms
Test Files 16 passed (16)
Tests 232 passed (232)

🤖 Generated with Claude Code


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 2, 2026 09:51
@os-zhuang
os-zhuang added this pull request to the merge queueAug 2, 2026
Merged via the queue into main with commit 9b43ee2Aug 2, 2026
22 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-4405-filter-conformance-mongo branch August 2, 2026 10:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:datateststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

filter-logic conformance 少了两个 backend:MongoDB 的 translateFilter 从来没被 #3774 的标准收编

2 participants

@os-zhuang@claude