Skip to content

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

Description

@os-zhuang

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

现状

#5013 新增的 packages/spec/src/shared/alias-integrity.test.ts 判定的是
strictObject(...) 建的表——它靠 strictObjectDeclarations() 在构造期登记,
所以能拿到运行时 .shape。235 个 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.ts 的 ActionParamSchema 就是其中之一——#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。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions