Skip to content

authorable-surface.json 只能发现、不能阻止 spec 键被移除——gen:schema 会无声重写基线(#4525 钉子暴露的系统性弱点) #4563

Description

@os-zhuang

发现自 #4525 / PR #4561 的变异测试。未认领,先记录待讨论,不要直接开做。

事实

DecisionOutputDefSchema 是 .strict() 的:把 required 从 Zod 源里摘掉,作者写的 required: true 立即变成 unknown-key 拒绝——行为破坏。而在 #4561 补钉子之前,唯一能反映这次移除的防线是 authorable-surface.json,它是 gen:schema 重新生成的基线:跑一次生成,基线被无声改写,没有任何东西变红。变异实验证实:摘掉该键后,既有 40 条用例全绿。

这不是 DecisionOutputDef.required 一个键的问题:所有仅由该基线守护的 authorable 键都具有同样性质——移除是「可见的」(diff 里有),但不是「困难的」(没有闸门喊)。

与既有机制的关系

可能的方向(待维护者定,均未验证)

  • A. 基线比对闸门:check:authorable-surface 区分「新增」与「移除」——移除项要求 PR 显式携带确认标记(类似 ADR-0087 转换注册或 ADR-0112 ledger 的形态),让删除变成一个响亮的、有记录的动作;
  • B. 生成钉子:从 authorable-surface 自动生成每键的 parse 钉子测试,人不用记;
  • C. 维持现状:接受「可见即足够」,依赖 PR review 看 diff——代价是 test(spec): pin DecisionOutputDef.required at the schema level (#4525) #4561 所暴露的:40 条用例全绿的情况下移除一个在用的键。

Refs #4525、PR #4561、#4001(strict unknown-key 体系)、ADR-0049。

Activity

  1. os-zhuang commented on Aug 3, 2026

    @os-zhuang
    ContributorAuthor

    验收关闭:本单要的方案 A(基线比对闸门)已由 #4650 / PR #4726 落地 —— packages/spec/scripts/build-schemas.ts 现在对从 authorable-surface.json 基线消失的键直接 fatal,要求 retiredKey() 墓碑 + ADR-0087 D2 转换 + major changeset;live→retired 必须有注册迁移,rename 必须携带全部键。本地已核实闸门存在,覆盖本单诉求(从「只能发现」升级为「能够阻止」)。gen:schema 无声重写基线的窗口已封死。


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions