Skip to content

build-schemas.ts 检查 (c) 的「墓碑已满 2 个 major」证明仍用叶名匹配 —— 无关簇的登记可以替一次退休提前起算 #5898

Description

@baozhoutao

#4659(检查 (b) 收口到确切 key)的范围外残留。#4659 只搬走了检查 (b);检查 (c) 的同一套叶名匹配原封不动地留了下来,build-schemas.ts 里的注释现在明确写着这一点。

事实

packages/spec/scripts/build-schemas.ts 的检查 (c)(#4650,「删掉一条 authorable-surface.json 基线行必须自带证明」)承认三种证明,其中第一种是「墓碑已老化」:base 里这条是 [RETIRED],它的 surface 在 ADR-0087 登记表里的 major 比当前 major 至少早 TOMBSTONE_AGE_MAJORS(= 2)。

判定「它的 surface 登记在哪个 major」用的是:

const matches = [...clauseMajors.entries()].filter(([clause]) => clause.endsWith('.' + prop));
...
const registeredAt = Math.min(...matches.map(([, major]) => major));

prop 是 key 的叶名,clauseMajorsCONVERSIONS_BY_MAJOR / MIGRATIONS_BY_MAJOR全部 major 的全部 / 子句。和 #4659 修掉的那条完全同构:不看 key 属于哪个 def,任何以同名叶子结尾的无关子句都算数,而且取的是 Math.min —— 最早的那个 major。

为什么要紧

两个后果,都朝「放行」的方向:

  1. 有没有登记判错:matches.length === 0 才报「no conversion/migration clause matching」。一条无关登记就能让一个从没被登记过的墓碑通过这一关。
  2. 老化时钟起算点判错,而且是取最早值,所以一律偏向提前放行。实测:data/Index:type 的叶名 type 命中 protocol 11 的 flow-node-http-callout-rename(flow.node.type,flow 节点的类型,和索引类型毫无关系),Math.min 于是把它的时钟起算在 major 11 —— 它自己那条诚实的登记 object.indexes[].type 是 major 17。当前 major 17 下,前者已满 2 个 major、后者一天都没满。也就是说这条基线行今天就可以被删掉,而它的退休对消费者可见才不过一个 major。

删掉基线行的后果正是 #4650 立这道门禁的理由:检查 (a)/(b) 读的就是这个文件,行没了,证据也就没了。

为什么 #4659 没有一起修

检查 (b) 只在新的 live → retired 跃迁上触发,所以它可以要求作者当场写下确切 key,新表 RETIRED_KEYS_BY_MAJOR 从空表开始、不需要回填(#4659 已实测空表在 main 上全绿)。

检查 (c) 相反:它裁决的是历史墓碑 —— 当前 97 条 [RETIRED] 全部早于 RETIRED_KEYS_BY_MAJOR,一条都不在表里。要让它改读确切 key,必须先把这 97 条(以及它们各自真正的退休 major)回填出来,而唯一能机械推导 major 的来源要么是这条坏掉的叶名匹配(用坏数据喂新表),要么是 authorable-surface.json 的 git 历史(可做,但是一次独立的考据 + 判断,不该塞进 #4659 的 diff)。所以 #4659 把它留下并在代码注释里点名,而不是顺手改成一个没人验证过的映射。

处置方向(未定,供 triage)

  1. 补齐历史映射:从 authorable-surface.json 的 git 历史逐条推出每个 [RETIRED] key 首次出现的 commit → 当时的 packages/spec/package.json major,回填进 RETIRED_KEYS_BY_MAJOR,检查 (c) 改读该表。最彻底,一次性成本在考据。
  2. 只收紧「有没有登记」这一半:要求匹配子句的 def 段与 key 的 def 可判定对应,老化时钟维持现状。半步,叶名耦合仍在。
  3. 把老化证明换成另一个事实:例如以基线行自身首次带上 [RETIRED] 的 commit 为时钟起点(与方向 1 同源,但不需要把结果落成表)。

倾向 1 —— 它让检查 (b) 和 (c) 读同一张表,叶名匹配从 build-schemas.ts 里彻底消失;但回填的准确性必须逐条可复核,不能推导一半就当事实写下。

关联:#4659(检查 (b) 已收口)、#4658(发现现场)、#4650(检查 (c) 的来历)、ADR-0087、ADR-0104

Activity

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions