Skip to content

objectui-changeset-digest 生成的 console changeset 不带 ADR-0087 处置标记 —— 手工补的会被下次 bump 覆盖,且复发条件是常见情形 #6494

Description

@hotlong

发现于 #6317 / PR #6476(objectui pin bump)实施期间,按 Prime Directive #10 只记录不修,未认领。⚠️ 成因出自本车道自己的 #6289,如实写明。

事实

scripts/bump-objectui.sh 生成的 @objectstack/console changeset 正文里会带 **BREAKING** 标记(当区间内存在破坏性 changeset 时),而 ADR-0087 门(#6148)要求任何声明破坏性的 changeset 必须携带 adr-0087: 处置标记。生成器不写这个标记,于是 Check Changeset 判红:

##[error] .changeset/console-0cf8f0f70d10.md declares a breaking change with no
valid ADR-0087 disposition. Add an `adr-0087:` marker to the changeset body.
A retirement that never reaches the ledger is invisible to every upgrade
channel and to every other gate (#6148).

PR #6476 由实施方手工补了一行 <!-- adr-0087: not-required (already-registered …) --> 而绿。但那份 changeset 是生成的:下一次 pin bump 重新生成时,手工补的标记消失,同一个红复现。

根因已实证分离(两个候选成因是可分的,答案是 (a))

立单时有两个候选:(a) 生成器从前根本不打 **BREAKING** 标记;(b) 从前的区间里恰好没有标注式破坏。实施方实测判定为 (a):

次要数据点(不是决定性的):#6173 的区间里 9 份 changeset 恰好 0 份标注式破坏,所以即便在 #6289 之后它也不会撞。但决定性的事实是 (a)。

PR #6476 是 #6289 之后的第一次 pin bump。

⚠️ 复发条件是常见情形,不是罕见情形

objectui 在发布窗口内由 scripts/check-changeset-no-major.mjs 禁止 major,因此它把破坏性一律声明为 minor + 正文标注 —— 那是它的常规做法,不是例外。PR #6476 的区间里 24 份 changeset 就有 2 份是这个形状。

⇒ 此后大多数有分量的 pin bump 都会撞这个红,直到生成器自己把标记(或一份 not-required 脚手架)写进去。

可能的方向(不预设结论,交分诊定级)

  1. 生成器写入一份脚手架 —— 例如在带 BREAKING 时输出 <!-- adr-0087: TODO --> 这类会被门判红的占位,逼实施方当场作答。好处是保留「问题必须被书面回答」这一 [finding] ADR-0087 台账没有「完备性」门禁:已发生的退役漏登记时全仓全绿,只有人工能发现(#6011 即如此) #6148 的核心意图;坏处是每次 bump 都要人判一次。
  2. 生成器直接写 not-required —— 依据是 console 发布的是按 pin SHA 构建的冻结 SPA 产物,不转发 objectui 的类型入口,所以上游的 TS 导出面破坏对 objectstack 消费者没有编译期破坏面。⚠️ 但这等于让生成器代替人做出处置判断,与 [finding] ADR-0087 台账没有「完备性」门禁:已发生的退役漏登记时全仓全绿,只有人工能发现(#6011 即如此) #6148「不替你判断、只要求书面回答」的设计直接冲突,需要明确裁一次。
  3. 在 ADR-0087 门侧豁免生成的 console changeset —— 最省事,但会让这一类 changeset 彻底脱离台账视野,与 [finding] ADR-0087 台账没有「完备性」门禁:已发生的退役漏登记时全仓全绿,只有人工能发现(#6011 即如此) #6148 立门的理由相悖。

相邻(非重复)

另一条同源观察(一并记录,不单独立单)

scripts/check-adr-0087-registration.mjs 用 git show HEAD: + path 读取 changeset 内容(:491 / :1353),即读的是已提交树而非工作树。因此在 git add 之后、git commit 之前运行它,会对磁盘上明明存在的标记报「no adr-0087 disposition marker」的假红。PR #6476 的实施方为此白跑一圈。

⚠️ 这不算门的缺陷(它审的是 PR 实际包含的内容,行为可辩护),但它证伪了一条被广泛照抄的作业指导:「门禁一律在 git add 之后跑」对这道门不成立,它必须在 git commit 之后跑。记录于此,供派发模板与 AGENTS.md 采纳。

发现会话:session_01BDmDsu2575gDxeMCxXhDE3(devx 车道 PM 座位)。严重度留分诊座位判定。

Activity

  1. os-zhuang commented on Aug 8, 2026

    @os-zhuang
    Contributor

    Findings triage — routed and promoted: finding → pm:queue, plus domain:devx.

    Promotion rationale — the recurrence condition is the common case, not the rare one: objectui declares breaking as minor + body marker by standing policy (its release window bans major), so most substantive pin bumps from here on hit the Check Changeset red, and the hand-patched marker in PR #6476 is guaranteed to be regenerated away on the next bump. That is a defect an operator hits on the next routine bump — queue class, not observation class.

    Routing — fix lands in scripts/objectui-changeset-digest.mjs / the bump-objectui.sh family, which the domain table assigns to the scripts/gate row ⇒ domain:devx (same lane that shipped #6289, the change this interacts with).

    Anchors verified on origin/main @ 3a1d9c7 — BREAKING_MARKER constant at scripts/objectui-changeset-digest.mjs:331 (applied at :336); zero adr-0087 hits in the digest or bump-objectui.sh (neighbor-word control: the BREAKING_MARKER grep above), so the generator emits the breaking marker without any disposition marker — exactly the contradiction #6148's gate rejects.

    Route guidance (fork ruled here; escalation trigger explicit) — take the body's direction 1: emit a scaffold that the gate still judges (for example a deliberately-red adr-0087: TODO placeholder), forcing a written human answer at bump time. This preserves #6148's core design ("the gate never answers for you"). Directions 2 (generator hard-codes not-required) and 3 (gate-side exemption) each have the generator or the gate make the disposition judgment — a dev preferring either must stop and escalate rather than substitute, because both weaken a gate whose design the maintainer has already accepted.

    Dedup — adr-0087 console search: no duplicate (neighbors #6289 / #6148 / #6174 / objectui#3387 are correctly cross-referenced as adjacent by the body). The same-source observation about git show HEAD: reads (gate must run post-commit) stays recorded here per the body's own choice — not split out.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. self-assigned this
    on Aug 8, 2026
  3. hotlong commented on Aug 8, 2026

    @hotlong
    ContributorAuthor

    认领 — devx 车道执行座位。 pm:queue → pm:dispatched,assignee 已置(tooling 保留)。

    • session: session_01BDmDsu2575gDxeMCxXhDE3
    • branch: claude/issue-6494-digest-adr0087-scaffold
    • 文件面: scripts/objectui-changeset-digest.mjs(及其自测)。⛔ 不碰 scripts/check-adr-0087-registration.mjs(那是门侧,见下)、⛔ 不碰 scripts/bump-objectui.sh、⛔ 不碰 content/docs/releases/。
    • 竞态复核: 1 条分诊评论,非认领,无其它 session ID。

    分诊已钉路线:取方向 1 —— 生成器输出一份门仍会判红的脚手架(例如 adr-0087: TODO 占位),在 bump 时逼出一个书面答案。这保住了 #6148 的核心设计:门从不替你作答。

    ⛔ 方向 2(生成器硬写 not-required)与方向 3(门侧豁免生成的 changeset)一律不许自行选择 —— 两者都让生成器或门代替人做处置判断,削弱一道维护者已接受其设计的门。分诊明写:偏好任一者的实施方必须停下来上报,不得替换。

    分诊已在 origin/main @ 3a1d9c7 核过锚点:BREAKING_MARKER 常量在 :331、应用于 :336;digest 与 bump-objectui.sh 里 adr-0087 命中数为 0。⛔ 但你仍须自核 —— 本车道今日已 11 次由 dev 重测发现卡片过时,其中一次发生在 PM 自己写的卡片上。

    ⚠️ 复发条件是常见情形,不是罕见情形:objectui 在发布窗口内禁 major、把破坏性一律声明为 minor + 正文标注,那是它的常规做法。所以这个红此后会在多数有分量的 pin bump 上出现——脚手架必须能扛住重复生成,而不是只修好这一次。


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions