Skip to content

[decision] with zero measured readers, should spec-changes.json stop emitting aggregate.added / aggregate.removed — or keep them as PR #19115 makes them (honest, scoped, gated)? #19121

Description

@os-elon-musk

Derived from in-flight card #18978 (PR #19115) by the domain:spec execution seat (session_019srGWGCBBCBHqcDoRZpQRh, seat post #18883). domain:spec is inherited from the parent card under the derived-card exception, ⛔ not produced by this seat; ⛔ no priority:* — grading is the triage seat's. needs-user-decision is applied because the question deletes a published machine-readable capability, which the charter routes to the maintainer.

维护者速读

spec-changes.jsonaggregate.added / aggregate.removed 现在诚实了 —— PR #19115 给它加了 surfaceScope,说清那两个数组真正跨的是哪一对发布版本,并让发布门禁两向拒绝缺失/错标/不实的声明。但同一轮的普查量出一件事:这两个数组在可达半径内一个读者都没有,而且它们装的内容与同文件 release.added / release.removed 集合完全相同

⇒ 也就是说:现在它不再说谎,但它是冗余的。要不要干脆不再发它?这一问必须您拍,因为删的是一个已发布的机器可读能力(需 ADR-0087 处置),而且它的登记项落在 packages/spec/src/migrations/registry.ts —— 那个文件今天被四张 open PR 持着。

⇒ 请选 A / B / C(推荐 A 先留着,B 作为您愿意时开的后续)。

三个选项

做什么 得到 代价
A 保持 PR #19115 落地后的形态 已发布能力保留;面不再说谎(surfaceScope 点名版本对);发布门禁两向拒假声明 永久冗余:aggregate.added/removedrelease.added/removed 集合相同。加法式改动 ⇒ 之后再取 B 完全兼容
B 删掉 aggregate.added / aggregate.removed(连 SpecSurfaceAddSchema / SpecSurfaceRemoveSchema),只留 release 段作为唯一导出差通道 零读者前提下最省的诚实终局;消掉 A 留下的冗余 已发布能力 ⇒ 需 ADR-0087 处置;登记项动 registry.ts(#19095 · #19090 · #19084 · #18319 四持有者)
C 键留着但永不填(任何输入下恒空) —— 有 B 的损失而无 B 的清晰,且「一个搬动了数百个导出的 minor 上 added: 0」正是 #18889 落地要终结的那种误读 ⇒ ⛔ 任何排序下都不推荐

四棱(四轴)

  • 实际业务需求 —— 读者侧实测为:可达半径内每一个读 aggregate 字段的消费者都只读 converted/migrated。半径含本仓全树(tracked + untracked)、objectui 全仓、已发布 tarball(17.3.0 / 17.4.0 解包)、以及已发布到客户项目的 skills/objectstack-upgrade/SKILL.md。⛔ 半径外照实申报:objectstack-ai/cloud 未挂载;任何第三方消费者从这里不可知。
  • 项目长远合理性(权重 ≥50%) —— 一个字段与同文件另一个字段集合相同,是「一个键一种被承认的拼写」在数据面上的同形违例;长远看 B 更干净。但 A 已经把说谎这一半修掉了,而 B 只消冗余 ⇒ 长远轴支持 B 而不急。
  • 防 AI 写错元数据 —— 两个同义数组并存,会让读它的 AI 必须猜哪个是权威;surfaceScope 让 A 至少可判别。B 直接消除这个选择。
  • 创业阶段不扩散 —— 本轴支持 B:零读者的已发布面按 implementation-first 处置,已发布零消费的能力不因沉没成本获得豁免⚠️ 但同一条纪律也说「删已发布能力进决策箱」—— 所以它到这里,而不是被执行席自取。

证据(全部取自 #18978 那轮的实测,逐条可复核)

  • 零读者:git grep 全树(含未跟踪)+ objectui 全仓 + 两份已发布 tarball 解包 + 文档/skills 面。亮控:同一支仪器命中 packages/cli/src/utils/spec-release-changes.ts:80,它确实读这份 manifest 的 doc.release 字段并随 @objectstack/cli 发布 ⇒ 零是读数而非哑火;objectui 侧 @objectstack/spec 命中 1628 文件而 spec-changes 命中 0。
  • 集合相同:同一轮量到 aggregate.added/removedrelease.added/removed 集合完全相同(不只是相似)。
  • 已发布载体的现状:GitHub Release 资产 17.4.0 读到 aggregate.added 225 / removed 51,而独立重算(手写 flattener,⛔ 非本仓代码)同样得 225 / 51,集合两向零差。
  • 尚未进 tarball:17.3.0 与 17.4.0 两个 npm 包里 aggregate.added/removed 都是 0/0,因为把它们写进 tarball 的那条 lane 是 feat(spec): ship a per-release section in spec-changes.json, verified against both tarballs #18889 才落的 ⇒ 下一次发布才是第一份带着它的 tarball。这条让 B 的窗口比看起来宽。
  • spec_changes MCP 工具在本仓只有散文没有实现(ADR、文档、changelog、代码注释里都提到它,零实现)⇒ 它不是读者。

⛔ 本卡不做的事

Related: #18978(父卡,PR #19115 已交付 A)· #18889(把 release 段与 tarball lane 落地的那张)· docs/adr/0087(ADR-0087 处置在 B 下必需)· PR #19095 / #19090 / #19084 / #18319(registry.ts 的四个持有者)。


os-decision-facets

  • ① 项目长远合理性:A 让已发布面停止说谎(surfaceScope 点名版本对)且不动 ADR 定下的形状;B 消掉冗余但要改一份已通过的 ADR —— 那是修宪,不是处置。
  • ② 实际业务拉动:读者侧(可达半径:本仓全树含未跟踪 · objectui 全仓 · 17.3.0/17.4.0 tarball 解包 · 已发布到客户项目的 skills/objectstack-upgrade/SKILL.md;亮控:同仪器命中 spec-release-changes.ts:80 确实读该 manifest 的 doc.release)。⇒ 零读者既是 B 的理由,也是 A 无成本的理由。
  • ③ 防 AI 犯错:两个同义数组并存会让读它的 AI 必须猜哪个权威;A 用 surfaceScope 让它可判别,B 直接消除选择 —— 但 B 要动 ADR。
  • ④ 创业阶段不扩散:本轴偏 B(零消费的已发布面按 implementation-first 处置);⛔ 但它不能越过 ③「不推翻既有维护者裁决」。

Prior rulings read: aggregate export diff,published capability removal,enforce-or-remove,spec-changes → 4 hits; ADR-0087 D4, ADR-0105 D5, ADR-0119 D3, ADR-0120 D7

⛔ 本卡按「已裁即执行」退出决策箱 —— 这是本席的更正

check-prior-rulings.mjs 对本卡的词集命中 ADR-0087 D4,而本席读了它(⛔ 不只转述命中):ADR-0087 状态 Accepted (2026-07-04, #2582),D4 在 docs/adr/0087-metadata-protocol-upgrade-contract.md:212 逐字把 spec-changes.json 的形状定成

{ from, to, added[], converted[], migrated[], removed[] }, each entry carrying the replacement, the conversion/migration id, and a rationale anchor.

并接着写 「Per-major manifests compose … cross-major consumers get one aggregate answer, not four documents to reconcile」,且把 spec_changes(from, to) 定为 MCP 面。

added[] / removed[] 是 ADR 已定形状的一部分,而本卡的选项 B(不再发它们)会与一份已通过的 ADR 相抵。按 SKILL.md 〈升级与决策〉③ ⛔ 不推翻既有维护者裁决,以及该工具自己的处方 —— 「a card whose question that decision already answers is EXECUTION, not a decision」 —— 本卡的问题已被回答:A 就是 ADR 现行规定的形态,而 A 已由 PR #19115 落地(诚实标注 + 发布门禁两向拒假声明,达档复核 PASS,已入队)。

⇒ 关单 completed,⛔ 不留在收件箱占维护者的时间。

若你仍想消掉那份冗余

不是本卡:它是一次 ADR-0087 修订请求(D4 的形状少两个键),需要 ADR 层的动作,外加 ADR-0087 处置与 registry.ts(今天四张 open PR 持有)。⇒ 说一声我就另立一张点名 D4 的修订卡;重开本卡也免费

本席的错,记在自己名下

⚠️ 本席 21:06Z 立本卡时没有跑 check-prior-rulings.mjs,于是把一个已被 ADR 回答的问题当成开放二选一送进了收件箱,并在轮报里向维护者列为「决策箱 2 张」之一。发现它的不是本席的复读,而是半状态巡查的 H62 行(它指出本卡缺机器可寻的四棱标记)—— 我为补那个标记才去跑工具,才读到 D4。⇒ 硬规则记在座位贴:决策卡落卡前先跑 check-prior-rulings.mjs,四棱块与 Prior rulings read: 行同笔带上,⛔ 不留待巡查点名。


Generated by Claude Code

Activity

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