Skip to content

refactor(drivers)!: memory / mongodb 的 aggregate / distinct 收进 DriverQuery (#6212 批 C) - #6356

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-6212-batch-c-frozen-face-types
Aug 7, 2026
Merged

refactor(drivers)!: memory / mongodb 的 aggregate / distinct 收进 DriverQuery (#6212 批 C)#6356
os-zhuang merged 2 commits into
mainfrom
claude/issue-6212-batch-c-frozen-face-types

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Part of #6212 (批 C,清单锚点单保持 open)

#6210 的 changeset 结尾专门留了一句:aggregate / distinct 不在那次范围内,因为它们不是 IDataDriver 收窄的那六个方法。#6212 记下了这笔账,本 PR 结清 memory 与 mongodb 两个包的部分。⛔ 未碰 A/B/D/E/F。

四处签名收窄

位置 收窄前 收窄后
MongoDBDriver.aggregate query: QueryAST query: DriverQuery(并删已无用的 import)
InMemoryDriver.distinct query?: QueryInput query?: DriverQuery
InMemoryDriver.aggregate Record< string, any >[] | QueryAST Record< string, any >[] | DriverQuery
InMemoryDriver.performAggregation(私有) Omit< QueryInput, 'object' > DriverQuery

QueryAST / QueryInput 都把 object 声明成必填,所以一个手上只有 where 的调用方叫不出这个类型的名字,只能伸手拿 as any —— 连 where / orderBy / limit 的检查一起关掉。这正是 #5181 记过账的代价。

memory.aggregate 的联合已保留

两支都有活体生产者,退役任何一支都会打断一条链路:管线支由 memory-analytics.ts 喂,AST 支由 objectql 引擎与 @objectstack/verify 的日期分桶探针喂。已在源码里把这条写进注释。

证伪了 #6212 正文的一处归因

正文说 performAggregation 当初选 Omit< QueryInput, 'object' > 是被 groupBy 的元素类型差异逼的。实测不成立QueryInputQueryASTgroupBy 上逐字相同,差异只在 search / orderBy / expand;直接换 DriverQuery 零报错。所以那不是被迫的选择 —— 契约优先取 DriverQuery,不再引入第二个查询类型家族。(与测量棒评论的结论一致。)

冻结面口径

纯类型注解、零运行时行为、零 emit 差异(as 断言编译期即抹除),不属 #5499 冻的「缺陷修复与语义补齐的开发投入」;#6210 已按同一口径在同一批驱动上做过一次并合并。硬约束遵守:只改了签名类型 + 无用 import + 测试里与第一实参逐字相等的冗余 object 键(仅一处),没有任何一处需要动逻辑。

刻意改的:aggregate'Aggregate operation (QueryAST)' 这条 debug 日志文案 —— 它是运行期字符串,改它就不再是零行为变化了。

反向验证(方向先判后跑)

反转 预判 实测
distinct 退回 QueryInput ✅ 红:TS2322 元组槽变 never、裸 { where } 字面量 TS2345TS2578 未使用的 @ts-expect-error
memory.aggregate 退回 QueryAST ✅ 红:同上三类
mongodb.aggregate 退回 QueryAST 绿 绿(exit 0,零输出)

第三行是刻意预判为绿并如实记录的:mongodb 的 tsconfig.json 排除 *.test.ts,而该方法的唯一消费者就是它自己的测试 —— per-package typecheck 根本看不见这次收窄。这不是"没写好",是门禁盲区本身,见下。

两个门禁

1. check:query-options-erasure —— 棘轮向下

收窄让 4 处 as any 变成多余(memory 2 + mongodb 2),删除后测试面 267 → 263,门禁按规矩红。已同 PR --update 提交 baseline(diff 恰好一行)。⛔ 全程零新增 as any

2. check:type-check-debt —— 全仓 re-measure 通过,并把 mongodb 从 43 ratchet 到 10

这一条不是纯记账,请重点看:

其余 5 条 ℹ(service-storage / objectql / runtime / rest / mcp 可下调)是既存漂移、非本 PR 所致,未动。

测试

新增 memory-driver-query-narrowing.test.ts(152 行)。所有 pin 都挂在对被收窄方法的真实调用上,不挂 const x: DriverQuery = … 字面量 —— 后者在签名回退后依旧是绿的(DriverQuery 本来就没有 object),正是 #5018 / #4984 付过学费的死 pin 形状。该包 tsconfig 不排除测试层、且无 TEST_DEBT 条目,所以这些 @ts-expect-error 是真检查而非幽灵。

mongodb 侧刻意没有写同形 pin:那里的测试不在任何 tsc program 里,写了就是 AGENTS.md PINS_CHECKED 警告的幽灵检查;它的钉子是上面那条 ratchet。

typecheck: driver-memory Done / driver-mongodb Done
全仓 pnpm typecheck: Tasks 125 successful, 125 total
driver-memory  test: Test Files 18 passed (18) | Tests 532 passed (532)
driver-mongodb test: Test Files 10 passed | 5 skipped (15) | Tests 206 passed | 137 skipped (343)
check:query-options-erasure: ✓ holds — test surface 263 sites, no files added
check:type-check-debt:       ✓ OK — 34 entries re-measured, none above its recorded number
check-nul-bytes:             ✓ OK

mongodb 的 137 条 skipped 需要真实 mongod(#5517 起 opt-in),因此那两处 as any 的删除是类型层证据,不是运行期证据 —— 如实说明。


Generated by Claude Code

…Query (#6212 批 C)

#6210 的 changeset 结尾专门留了一句:aggregate / distinct 不在那次范围内,
因为它们不是 IDataDriver 收窄的那六个方法。#6212 记下了这笔账,本次结清
memory 与 mongodb 两个包的部分。

四处签名收窄(第一实参已经是对象名,query 里不再要求写第二遍):

  mongodb aggregate            QueryAST                -> DriverQuery(并删无用 import)
  memory  distinct             QueryInput              -> DriverQuery
  memory  aggregate            [] | QueryAST           -> [] | DriverQuery(保留联合)
  memory  performAggregation   Omit<QueryInput,'object'> -> DriverQuery

memory.aggregate 的联合刻意保留:两支都有活体生产者 —— mongo 管线支由
memory-analytics.ts 喂,AST 支由 objectql 引擎与 @objectstack/verify 的日期
分桶探针喂。

证伪了 #6212 正文的一处归因:正文说 performAggregation 当初选
Omit<QueryInput,'object'> 是被 groupBy 的元素类型差异逼的。实测 QueryInput
与 QueryAST 在 groupBy 上逐字相同,差异只在 search/orderBy/expand;直接换
DriverQuery 零报错。契约优先取 DriverQuery,不再引入第二个查询类型家族。

零运行时改动:非测试改动 100% 是类型注解,无逻辑、无行为、无 emit 差异
(as 断言编译期即抹除)。这是 #5499 冻结面上被允许的处置口径,与 #6210 在同
一批驱动上走的是同一条。

两个门禁:
- check:query-options-erasure 的测试面 267 -> 263(收窄让 4 处 as any 变多余,
  memory 2 + mongodb 2),已按门禁要求同 PR --update 提交 baseline;
- check:type-check-debt 全仓 re-measure 通过。同时把 driver-mongodb 的
  TEST_DEBT 从 43 ratchet 到实测 10:那 33 条 TS2345 是 PR #6210 消掉的(在
  d367f03^ 实测仍是 43,组成与旧 note 逐字吻合),ledger 一直没跟着降。这不是
  纯记账 —— mongodb 的 tsconfig 排除测试层,本次 aggregate 收窄的唯一消费者就
  在那些被排除的测试里,把签名改回 QueryAST 实测是 12 条,43 的余量会把它整个
  吞掉;降到 10 之后该反向验证才真的变红。

新增 memory-driver-query-narrowing.test.ts:pin 全部挂在对被收窄方法的真实调用
上,不挂 `const x: DriverQuery = …` 字面量 —— 后者在签名回退后依旧是绿的
(DriverQuery 本来就没有 object),正是 #5018/#4984 付过学费的死 pin 形状。

Part of #6212

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

vercel Bot commented Aug 7, 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 7, 2026 3:04pm

Request Review

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

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

  • content/docs/data-modeling/drivers.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb)
  • content/docs/deployment/vercel.mdx (via @objectstack/driver-memory)
  • content/docs/getting-started/glossary.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb)
  • content/docs/permissions/authentication.mdx (via @objectstack/driver-memory)
  • content/docs/plugins/index.mdx (via @objectstack/driver-memory)
  • content/docs/plugins/packages.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb)
  • content/docs/releases/implementation-status.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb)

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-zhuang
os-zhuang marked this pull request as ready for review August 7, 2026 15:06
@os-zhuang
os-zhuang enabled auto-merge August 7, 2026 15:07
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit 262e40d Aug 7, 2026
25 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6212-batch-c-frozen-face-types branch August 7, 2026 15:34
lemonhub-io pushed a commit to OpenFork-org/objectstack that referenced this pull request Aug 8, 2026
…base cannot answer (objectstack-ai#6452) (objectstack-ai#6461)

`resolveSurfaceBase()` fell back to origin/main's TIP whenever
`merge-base HEAD origin/main` failed. Under a tip anchor "main added a key
after this branch forked" and "this branch deleted a key" are the same fact,
so the gate reported the first as the second (objectstack-ai#6359: PR objectstack-ai#6356 touched no
packages/spec file and was told it had deleted ui/BulkActionDef:requiredPermissions).

The anchor moves; the verdict does not. When merge-base cannot answer, the
baseline rev now comes from an upstream anchor rev and its keys are read out
of git at that commit — never out of authorable-surface.base.json itself.
The rev is accepted only when something the PR does not control vouches for
it: demonstrated reachability, or origin/main's own committed copy of the
anchor naming the same commit; otherwise the rev origin/main records is used.
With no upstream anchor at all the tip is kept and the run says so, naming
`fetch-depth: 0`.

Also folds verifyCommittedSurfaceBase's open-coded ancestry read onto the
shared `probeAncestry` (objectstack-ai#5370/objectstack-ai#5847), so git DECLINING to answer is no longer
read as a verdict of "not an ancestor".


Claude-Session: https://claude.ai/code/session_01AZgRyPVwi1jLb1mNNuUQ9o

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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 size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants