Repository navigation
把 44 个 strictUnknownKeyError 直调点批量迁到 strictObject,棘轮降到 0(路线 1 消不掉手抄数组与 shape 的漂移) #5593
Description
Activity
补:路线 1 的过渡看守已落地为 PR #5609(draft),本 issue 描述的基线以那个 PR 为准。
实测数字定稿:44 个源码调用点 → 运行时 52 张表,
strictObject那边 235 张。三条判据的首测结果:probe 撞车 0 条、别名 key 不得是已知键 0 条、别名 target 必须是已知键 32 条(全部是 #5555 那一个根因)。对迁移有直接影响的一条:PR #5609 在闸门里加了两处带陈旧检查的显式豁免(
PROSE_ALIAS_TARGETS六条散文式 target、VARIANT_LEGAL_GUIDANCE两条),以及 #5555 的结构化容差。迁移ui/app.zod.ts导航项一族时,这三处会同时失去依据而转红 —— 那是预期行为,不是回归:它们的存在前提就是那批表还在直调登记表里。届时应当删除,而不是改写成新形式。
Generated by Claude Code
发现分诊(#4949 纪律):晋级
pm:queue+pm:blocked(域已在domain:spec,摘finding)。- 一行理由:路线 1 明确消不掉「手抄数组与 shape 漂移」这一半(闸门会照着数组给绿灯),44 个调用点的迁移路线、规模实测、三个坑与基线全部备齐,属已测量的收敛工作项。
- Blocked-by: 44 个
strictUnknownKeyError直接调用点的别名表在 #5013 闸门覆盖之外(实测干净,但无人看守) #5483(在飞,其路线 1 看守 PR test(spec): 别名一致性闸门收编 44 个 strictUnknownKeyError 直调点 —— probe 撞车维度首测 (#5483) #5609 尚为 draft,本单基线以它为准;先落它)。 - 接续注意(评论区已记):迁
ui/app.zod.ts导航族前先修ui/app.zod.ts导航项:4 条expanded别名在另外 8 个变体上把作者指向该变体同样拒绝的键(二次拒绝) #5555;避开 [spec] 退役 HookContext session.roles —— #4839 双删后零消费方零生产方(ADR-0049) #5050 在飞的data/hook*.zod.ts;PR test(spec): 别名一致性闸门收编 44 个 strictUnknownKeyError 直调点 —— probe 撞车维度首测 (#5483) #5609 的三处显式豁免届时应删除而非改写。分批节奏由 spec 座位排。
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- added a commit that references this issue
on Aug 6, 2026 打包建议(致 spec 座位):本单与 #5583 同为 strictObject 机械迁移族,建议同一接力棒内派发(一名 dev 一次落地、一 PR 多
Fixes或紧邻两棒),摊薄四步重建 + CI 圈的每单固定成本。背景:维护者 2026-08-06 拍板 spec 车道缩盘方案,见 #5837。
Generated by Claude Code
Release-board audit (maintainer-directed re-audit of non-board
domain:specitems, 2026-08-07): addingtarget:v17— metadata-protocol change, size M, low-risk: mechanical migration of 44strictUnknownKeyErrorcall sites tostrictObject; pure strictness tightening backed by the alias-integrity gate/ratchet; batch with #5583. (pm:blockedon #5483/PR #5609 retained — board membership is independent of dispatchability.) Maintainer directive: protocol changes land in v17 unless large/risky. Triage seat may veto.
Generated by Claude Code
- added a commit that references this issue
on Aug 17, 2026 - added a commit that references this issue
on Oct 7, 2026
由 #5483 的过渡看守(路线 1)落地后拆出的后续(未指派,记录测量与边界,不认领)。
现状
#5483 按路线 1 落地:
strictUnknownKeyError自己把{ surface, knownKeys, aliases, guidance }登记进一张内部登记表,packages/spec/src/shared/alias-integrity.test.ts因此把这 44 个直调点也判了 —— 零调用点改动。实测规模:44 个源码调用点,运行时 52 张表(
ui/app.zod.ts的导航项工厂一个调用点跑九次,每个type变体一张)。关键在于这批表被判到的强度不均,闸门自己也是这么写的:
strictObject那 235 张.shape判.shape判(含墓碑检查)aliasProbe不得撞车第三条不依赖 shape,所以路线 1 就把它开满了(首测 52 张表 0 撞车)。前两条继承手抄数组与 shape 之间的漂移 —— 数组说
x是已知键,而 schema 里早就没有了,闸门会照着数组给出绿灯。那正是strictObject存在的理由(见其 docblock:"the array is a second copy of the truth"),也正是路线 1 消不掉的那一半。该做什么
把 44 个调用点分批迁到
strictObject(options, shape):*_KEYS数组连同它的漂移探针测试一起删除;alias-integrity.test.ts里toBeLessThanOrEqual(44)的只减不增棘轮随之降到 0;packages/spec/src/shared/alias-table-registry.ts)与闸门里"直调点"那一整段随最后一个调用点一起删除。分布(实测,基线见下):
迁移时已知的三个坑
data/object.zod.ts的表是延迟构建的(objectUnknownKeyErrorImpl ??= …),为的是绕开一个 temporal dead zone ——UNKNOWN_KEY_GUIDANCE和 shape 都声明在它下面。改成strictObject需要先解决这个顺序问题,不是纯机械替换。ui/app.zod.ts的导航项是一个按变体拼装的工厂,九张表共用一段拼装逻辑,knownKeys是[...BASE, ...NAV_VARIANT_KEYS[variant]]。迁移意味着九个变体 schema 各自成为strictObject,extraKeys可能用得上。同一族还有ui/app.zod.ts导航项:4 条expanded别名在另外 8 个变体上把作者指向该变体同样拒绝的键(二次拒绝) #5555 那条待修缺陷,顺序上建议先修ui/app.zod.ts导航项:4 条expanded别名在另外 8 个变体上把作者指向该变体同样拒绝的键(二次拒绝) #5555 再迁,否则修法要写两遍。data/hook.zod.ts/data/hook-body.zod.ts当时在 [spec] 退役 HookContext session.roles —— #4839 双删后零消费方零生产方(ADR-0049) #5050 手里,分批时避开在飞的文件。基线
分支
claude/issue-5483-strict-unknown-registry,origin/main5acb93a。测量复现:pnpm --filter @objectstack/spec exec vitest run src/shared/alias-integrity.test.ts。