Skip to content

[finding][spec-tooling] ADR-0087 门的 no-migration-prescription 矛盾检查匹配的是占位符 FROM/TO,不是真实处方 —— 写得越好的处方越照不到 #6419

Description

@os-zhuang

check-adr-0087-registration.mjs#6148 / PR #6342,今天合入)在 PR #6404 上拦下第一例,实测发现它的闭合词表对这一类变更没有任何一个诚实可用的格。四个标记逐个实测(都是在真的 commit 上跑 node scripts/check-adr-0087-registration.mjs,不是读代码推断)。

变更形状

PR #6404#6212 批 B):@objectstack/driver-sql / @objectstack/driver-turso 两个已发布包,major,删掉 query.aggregateagg.func 两个宽容分支。这两个键从未是已声明表面

  • git log -S"aggregate: z." --all -- packages/spec/src/data/query.zod.ts零 commitfunc: z. 同样零。即 QueryASTSchema / AggregationNodeSchema 历史上从未声明过它们。
  • 没有 retiredKey() 墓碑,QuerySchema 上也没有 alias table 收录它们(该文件唯一的 alias table 是 SortNodedirection: 'order')。
  • docs/protocol-upgrade-guide.mdcontent/docs/releases/ 零命中
  • 非测试书写者实测为零(唯一书写者是这两个驱动包自己的 fixture)。

(注:content/docs/** 里确实有 aggregate: / func:,但那是另一个表面 —— UI dataset measure(dataset.zod.ts),那里 aggregate 是规范键、func 是该 schema alias table 里已声明的响亮别名。与本次删的 query AST 键无关,本 PR 不碰。)

四个标记的实测结果

标记 实测 为什么落空
not-required (unpublished) 硬红 该格判的是「npm 包 private: true」,不是「这个键从未发布」。实测报 @objectstack/driver-sql, @objectstack/driver-turso are PUBLISHED。这两件事同名不同义,是最容易照着直觉写错的一格。
not-required (already-registered <id>) 台账里没有覆盖它的既有条目。台账里的 query 键退役(query-joins-retired / query-cursor-retired / query-distinct-retired / query-window-functions-retired全都是已声明并带墓碑的键,与本例正相反。
registered <id> ❌ 实质错 需要在 packages/spec/src/migrations/registry.ts 新增条目。但台账是 objectstack migrate meta 的数据源,改写的是静态存储的 metadataquery.aggregate 是运行期调用实参,从不入库、也从未被告知过任何人。写条目等于告诉升级者「一个你从没拿到过的表面没了」,污染升级指南。
not-required (no-migration-prescription) ⚠️ 机械上会绿,但只是探测器盲区 hasMigrationPrescription大小写敏感、只认本仓 FROM → TO 的英文大写写法。本 changeset 的迁移段写作 **迁移**:\aggregate:` → `aggregations:``(中文),因此不匹配。但正文确实给了消费方改写处方 —— 用这一格就是踩探测器的盲区过关,正是该格文档里点名禁止的自相矛盾。

于是这条 PR 只剩两个选择:写一个机械上绿、实质上撒谎的标记,或把 CI 红着。它选了后者并上报。

缺的那一格是什么

「该键从未是已声明表面(never-declared)」 —— 与 unpublished 正交:包发布了,键从未发布。而这恰恰是最该免于台账的一类:台账的全部内容是「一个你曾被告知的表面没了」,从未告知过的键没有任何升级通道需要交代。

顺带:no-migration-prescription 的探测器只读英文大写 FROM → TO,而本仓 AGENTS.md 要求解释性文字用中文,中文写的迁移处方一律照不到。这不只影响本例 —— 它意味着该格在本仓的实际约束力远低于设计意图(设计时实测 32 个里 11 个带处方,那是按英文大写量的)。

可选处置(不预断,交维护者/门禁车道裁)

  • A. 加第四个 not-required 类别 (never-declared) <why>,机械校验方式现成:在 packages/spec 全历史里 grep 该键的声明(git log -S)+ 确认无 retiredKey 墓碑无 alias-table 条目 —— 与其它三格一样「按事实复核而非凭信任」。⚠️ 代价:多一格就多一条可被滥用的出口,需要把校验做成真检查而不是自述。
  • B. 把 hasMigrationPrescription 扩到中文写法迁移:X → Y),然后裁定本例必须 registered⚠️ 代价:等于承认台账要收录从未声明的键,与台账语义冲突。
  • C. 维持词表,裁定这一类走 registered⚠️ 代价同上,且会让升级指南出现「你从未拿到过的键退役了」的条目。

我倾向 A:它把「包私有」与「键从未声明」两件本就不同的事分开,而不是逼作者在两个都不真的格里挑一个。但这属门禁词表设计,不是实施者该拍的板。

阻塞:PR #6404(其余全绿,仅此一红)。关联:#6148、PR #6342#6212

Activity

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

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions