Skip to content

44 个 strictUnknownKeyError 直接调用点的别名表在 #5013 闸门覆盖之外(实测干净,但无人看守) #5483

Description

@os-zhuang

发现于 #5013 的全仓别名一致性闸门(范围外,未指派)。观察类:实测当前无缺陷,
记录的是覆盖边界本身。

现状

#5013 新增的 packages/spec/src/shared/alias-integrity.test.ts 判定的是
strictObject(...) 建的表——它靠 strictObjectDeclarations() 在构造期登记,
所以能拿到运行时 .shape235 个 surface 被判定。

strictObject 不是唯一的入口。helper 之前的老接线直接调
strictUnknownKeyError({ surface, knownKeys, aliases, guidance, history }),
自带一份手抄的 knownKeys 数组,这些表根本不进登记表:

44 个调用点,分布在 14 个文件
data/object.zod.ts、automation/flow.zod.ts、security/permission.zod.ts、
ui/app.zod.ts(9 处)、data/datasource.zod.ts(6 处)、automation/approval.zod.ts(4 处)、
data/driver/{sqlite,mongo,memory,postgres,mysql}.zod.ts、data/hook*.zod.ts、
security/{rls,sharing}.zod.ts、identity/position.zod.ts、
ui/{action,bulk-action}.zod.ts

ui/action.zod.tsActionParamSchema 就是其中之一——#5013 修的是同一个文件里
ActionSchema 的表,而同文件的 param 表当时不在任何闸门下。

实测结论:干净

临时给 strictUnknownKeyError 加了登记后跑同样两条判据(别名 key 不得是已知键、
别名 target 必须是已知键)+ guidance key 判据,51 张表全部通过,唯一的报告集中在
ui/app.zod.ts 的 navigation item 系列,那是刻意的散文式 target
(type: 'url' (with url)),不是键名,属于另一种写法而非缺陷。

所以这条是「暂时没事,但没人看着」,不是待修 bug。

已做的缓解

#5013 在闸门里放了一条只减不增的棘轮,把这个数钉在 44:

expect(uncovered.length).toBeLessThanOrEqual(44);

迁一个到 strictObject 是免费的;新增一个直接调用点会红,逼作者显式选择。

建议(两条路,选一)

  1. 收编判定:让 strictUnknownKeyError 也登记 {surface, knownKeys, aliases, guidance},
    闸门对这批按 knownKeys 判定。便宜,但判的是手抄数组而不是 shape——
    数组本身与 shape 漂移仍无人看守(那正是 strictObject 存在的理由,
    见其 docblock「the array is a second copy of the truth」)。
  2. 迁移到 strictObject:一次性消掉手抄数组,这批自动进入现有闸门,
    棘轮随之降到 0。工作量大得多,但把两个问题一起消掉。

倾向 2,分批做;1 可以作为过渡期的看守。

复现日期 2026-08-05,基线 origin/main ed0d2aa

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions