Repository navigation
Closed
Labels
domain:devxDomain lane — seat card indexed by label:pm:seatDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loopReady for the PM dispatch looptoolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surfaceFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
Description
#4721 正文最后一段的顺带项:「一条更便宜的内部护栏是 lint 禁止对引擎查询选项 as any —— 是否值得单开一单,取决于树里这种擦除还有多少」。#4721 的执行 agent 按 06:25Z 裁决要求做了这次测量,结论是值得,故按 Prime Directive #10 单独立项,未认领。
实测(origin/main = 89d2a4e)
| 形状 | 非测试代码 | 测试代码 |
|---|---|---|
A. .find(…) / .findOne(…) / .count(…) / .aggregate(…) 调用里把参数 as any 掉 |
25 | 126 |
C. 局部变量声明成 const opts/options/query/queryOptions/findOptions: any |
11 | — |
A 的样本(全部非测试):
packages/metadata/src/loaders/database-loader.ts:231 return this.engine.find(table, query as any);
packages/objectql/src/engine.ts:4170 await driver.find(object, …, hookContext.input.options as any)
packages/objectql/src/engine.ts:3788 ...(nestedAST.orderBy ? { orderBy: nestedAST.orderBy as any } : {}),
C 的样本:
packages/metadata-protocol/src/protocol.ts:4363 const options: any = { ...request.query };
packages/metadata-protocol/src/protocol.ts:4822 const queryOptions: any = { … };
packages/cli/src/commands/data/query.ts:75 const queryOptions: any = { … };
packages/objectql/src/hook-wrappers.ts:461 const options: any = input.options;
packages/runtime/src/domains/mcp.ts:349 const query: any = {};
packages/plugins/plugin-sharing/src/sharing-plugin.ts:735 const options: any = ctx.options;
36 处非测试擦除不是「个位数、顺手清掉」的量级,也不是可以一次性全删的量级——其中一部分(hookContext.input.options、buildDriverOptions 的返回)是真的跨了类型边界,需要的是把边界类型补上而不是删 as any。
为什么这条护栏针对的是 #4674 那一类
#4674 的两个站点都不是「缺运行时闸」漏掉的,是类型被擦掉漏掉的:} as any) 和 const opts: any。EngineQueryOptions.orderBy 声明的就是 SortNodeSchema[],tsc 本来完全有能力在写的那一刻拒绝 direction——它没拒绝,只因为那一行把类型抹平了。#4720 恢复了那两处,#4721 关掉了外部调用方那一侧;这一单是防止同一类擦除再长出来。
注意这三单的分工,不要混:
| 层 | 谁来管 | 状态 |
|---|---|---|
| 内部调用方(包内代码、协议、插件) | tsc,前提是没人擦类型 |
#4720 修了两处;本单防复发 |
外部调用方(REST / RPC 的 orderBy) |
schema strict + ingress normalizer | #4721 已关 |
建议形状(需要决定)
- 范围:只管「引擎/驱动查询选项」这一个语义位,还是所有
as any?后者必然要一张巨大的 baseline,而这条规则的价值恰恰在窄——它要说的是「查询选项的类型是有意义的,别抹」。倾向窄。 - 落点:
packages/lint里的自定义规则,还是scripts/check-*.mjs里的一个 AST 走查(仓里已有check-durability-log-level/check-startup-registry-verdict两个同形状的、带 shrink-only baseline 的走查)?后者与既有惯例一致,且天然支持「已存在的 36 处进 baseline、只禁新增」。倾向后者。 - 测试代码是否算:126 处在测试里。测试里
as any常常是构造非法输入的正当手段(一个被静默丢弃的排序键对外部调用方仍然是静默的:direction该 400 还是继续被丢掉(#4674 第 4 项) #4721 自己的拒绝测试就要这么写)。倾向排除测试,或只在测试里禁「传给真引擎的合法查询」这一子集——但这个子集不好机械识别,所以更可能就是排除。
三条都不是实现问题,是规则边界问题,建议由维护者拍板后再动手。
Metadata
Metadata
Assignees
Labels
domain:devxDomain lane — seat card indexed by label:pm:seatDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loopReady for the PM dispatch looptoolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surfaceFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
Activity
xuyushun441-sys commentedon Aug 3, 2026
分诊(PM):入队,
domain:devx(落packages/lint/scripts门禁族)。正文列的三个规则边界问题属验证策略,PM 直接定、维护者留否决窗口:① 首刀只覆盖非测试代码(25+11 处),测试里的 126 处不阻塞、以 ratchet 计数只减不增管住;② lint-rule vscheck-*.mjs走查:按packages/lint既有惯例由实施 dev 定,判据是「哪种在本仓已有同类先例且能双向证红」;③ 作用域=引擎查询选项(EngineQueryOptions/orderBy一族)的as any/: any擦除,不外扩。若实施中发现某条边界实际改公共契约,再 needs_decision。Generated by Claude Code
os-zhuang commentedon Aug 5, 2026
选批备注(devx 车道 PM,
session_01GX3sL71LFq8m2usg6VqTSE,2026-08-05):packages/lint文件面已随 PR #5490 合并释放,本单回到可派位,但本轮刻意压后:与在飞 #5024(better-auth 探针)都可能新增根package.json的check:*脚本条目(共享注册文件,同批禁止),#5024 落地后下一轮即派。派发时要点(记在此防丢):① 08-03 的三条边界裁定沿用(非测试 25+11 首刀、测试 126 走 ratchet 只减不增、作用域=引擎查询选项族不外扩、形态由 dev 按仓内先例定);② 正文测量基于 89d2a4e(08-03),两天 ~36 合并后站点数必须重测(#4251 的 slot-lookup 清扫在相邻地带持续推进,可能已消掉部分样本);③
packages/lint今日两次大改(#5455、#5490 —— 后者新增规则 + 抽出共享 walker),注册面有位移,基于合并后 main;④ 交付物是门禁 + 存量入 baseline 只减不增,⛔ 不在本 PR 清扫那 36 处(其中一部分需要补边界类型而非删as any,属后续批次)。Generated by Claude Code
os-zhuang commentedon Aug 5, 2026
认领:PM 循环第 5 轮(devx 车道)
会话:
session_01GX3sL71LFq8m2usg6VqTSE分支:
claude/issue-4918-query-options-erasureWorktree:
objectstack-issue-4918域:
domain:devx文件面:新门禁(
scripts/check-*.mjs或packages/lint新规则文件,dev 按 08-03 分诊定)+ baseline + 根package.json一条脚本项。⛔ 互斥声明:同批 #5020 在飞占用packages/lint/src/validate-react-page-props.ts及其测试 —— 本单无论选哪种形态都不得触碰该文件;若评估后确需触碰,停下返回 blocked 说明,不硬做。派发要点沿 08-05 选批备注:重测站点数(测量基于 89d2a4e,已隔两天)+ 存量入 baseline 只减不增 + ⛔ 不清扫存量 36 处。
Generated by Claude Code
os-zhuang commentedon Aug 5, 2026
验收(devx 车道 PM,
session_01GX3sL71LFq8m2usg6VqTSE,2026-08-05):ACCEPT → PR #5600,转 ready 并挂 auto-merge。as unknown as 契约名具名逃生口)的读法;B 的失败模式正是 AGENTS.md 点名的「豁免清单驯化」。若未来要升级到 B,先做 51 文件的正当/随手分诊,由该轮 PM 立项 —— 不在本单。engine.findcalls sort bydirection, a key no driver reads — audit history and global search silently return ASCENDING #4674 成因三态原地复现(state A tsc 精确红 / state B 擦除吃掉那一个错误且门禁红)—— 这条规则守的是被实证的机制,不是自造形状。check:engine-double-contract挂在 #5584 刚落地的action-execution-calldata-not-found.test.ts(2 个 double 未接assertEngineDeleteDispatch,基线无条目)——所有新 PR 的 ESLint job 都过不去 #5604 base 自带(其自身门禁步骤在 CI 已跑过且绿,红在后续步骤),归因已在 PR 留档,非必需检查不阻塞。发现 main 全仓红:check:engine-double-contract挂在 #5584 刚落地的action-execution-calldata-not-found.test.ts(2 个 double 未接assertEngineDeleteDispatch,基线无条目)——所有新 PR 的 ESLint job 都过不去 #5604 时查重未立孪生,处置正确。Generated by Claude Code
fix(driver-turso): satisfy the #4918 query-options-erasure ratchet on…
test(objectql): drop two `as any` erasures on ordinary engine reads (#…
test(objectql): 正控的 find 选项不再擦成 `any`,过 #4918 query-options 棘轮
feat(lint): ban erasing engine query options to `any`, with a counted…
feat(drivers): driver-turso 迁回本仓公开发布,五个 IDataDriver 统一收进 packages/dri…
10 remaining items
chore(scripts): 把 query-options-erasure 的测试面天花板从 263 降到 256 (#6754)
test(drivers): 剥掉 34 处已死的 `bypassTenantAudit` 选项转型,换回编译期检查 (#6754)
chore(scripts): 把 query-options-erasure 的测试面天花板从 263 降到 256 (#6754)
test(objectql): type the #7095 query-options sites instead of erasing…
test(driver-memory): type the aggregation conformance query instead o…
test(objectql): type the #7738 pin's engine inputs instead of erasing…
fix(objectql)!: `engine.find`/`findOne` refuse an unmaterializable fo…
fix(driver-memory): make the `$contains` family case-exact and answer…
fix(objectql): withhold the org-scope predicate from federated objects (
fix(approvals): type the membership read and re-point the double ledg…
fix(approvals): screen the `manager` approver to the request's organi…
fix(scripts): keep the engine.ts query-options erasure sites on the c…
feat(scripts): codemod-split-engine writes ruling 6624345766's facade…
feat(scripts): the engine codemod's fourth pass moves named methods o…
refactor(objectql): move the six formerly erasure-pinned ObjectQL bod…