Skip to content

objectui pin bump 生成的 console changeset 对破坏性变更零标注 —— digest 只认 major 声明级别,而 objectui 在 v17 窗口内把破坏性声明为 minor + 正文标注 #6099

Closed

Description

@hotlong

未认领。 发现于 #6089 的 pin 刷新(PR #6097),不在那个 PR 的范围内,单开记录。

现象

scripts/objectui-changeset-digest.mjs 里,"这条是不是破坏性变更"的判据是声明级别等于 major:

const breaking = releasing.filter((r) => r.level === 'major').length;

它只驱动一件事 —— 生成的 @objectstack/console changeset 末尾那句提示:

⚠️ N of these declare a **major** (breaking) bump in objectui …

但 objectui 在 v17 发布窗内不用 major 声明破坏性变更,而是 minor + 正文标注(与本仓 check-changeset-no-major.mjs 的窗口约定同源:窗口外一个 major 会把整个 lockstep 组顶上去)。于是判据与约定错位,breaking 恒为 0,那句提示永远不触发。

实测(PR #6097 的区间 f5bc4c78be76...f995a452d2ca)

区间里有两条确凿的 v17 破坏性变更,digest 判定 breaking = 0:

objectui commit changeset 声明级别 digest 判定
042e09d77 refactor(types,react,components,fields)! field-widget-single-metadata-carrier.md minor 非破坏性
6e794a19e fix(app-shell)! flow-node-geometry-is-spec-position.md minor 非破坏性

区间内 64 条 releasing changeset:14 minor / 50 patch / 0 major。也就是说,连提交标题上带 ! 的那两条,在 digest 眼里都与一条普通 patch 无异。

为什么这值得单开

不是"丢失"——两条都在清单里,级别正确、摘要完整,#4731 修好的那部分是稳的。问题在能不能被认出来,而这一点目前取决于 changeset 作者是否碰巧在正文首段自报家门(digest 取的正是首段):

  • 042e09d77 的首段以 **BREAKING (v17)** 开头 ⇒ 条目里能看见;
  • 6e794a19e 的破坏性陈述("Breaking for anyone reading node.ui")在正文靠后的段落 ⇒ 首段读不到,生成出来的条目就是一句普通行为修复:
- **minor** — The flow designer writes node geometry as the spec's `FlowNode.position`, not its
  own `ui: { x, y }` (objectui#3172). (objectui `6e794a19e`)

于是"作者升级时会踩到的破坏性迁移"能不能进入平台发布记录的视野,靠的是上游作者的排版习惯,而不是机制。这正是 #4731 自己写下的那条理由的另一半 —— "Breaking changes are the single class that must never vanish from a release record";#4731 解决了"进不去",剩下"进去了但认不出来"。#3340 关心的也是同一条链路的完整性。

两种读法(留给分诊定级)

按"立案时判定的严重度两个方向都不可靠"(#4949 的经验)的原则,如实记两读法,不自打级别标签。

可能的落点(不预设结论)

  1. 判据从"级别 = major"扩到"级别 = major 或 正文命中破坏性标注(BREAKING、! 型提交)";
  2. 让 digest 读提交标题里的 conventional-commit !(bump-objectui.sh 的 pin changeset 只收 feat|fix 且静默截断到 40 条 —— 破坏性 refactor! 进不了前端发布记录 #4731 明确反对用类型当过滤器,但把 ! 当作附加信号、不改变收录集,与那条理由不冲突 —— 需要维护者判断这算不算破线);
  3. 约定上游:v17 窗口内破坏性 changeset 的首段必须以标注开头(纯约定,无强制)。

三条各有代价,尤其 2 与 #4731 的"declaration over inference"取向的边界需要维护者裁定,故不在 #6097 里顺手改。

关联

Activity

  1. claude commented on Aug 7, 2026

    @claude
    Contributor

    Triage: pm:queue + domain:devx.

    Classification — dispatchable defect, not an observation, and not a decision card.
    The issue deliberately records two readings and leaves the grade to triage (#4949: grading happens here, not at filing). Graded as a concrete defect:

    Landing-site anchoring (why domain:devx, read from the code — not from the title).
    The fix lands in scripts/objectui-changeset-digest.mjs. Verified verbatim on origin/main:

    • :297 — const breaking = releasing.filter((r) => r.level === 'major').length; — the sole producer of the count;
    • :345–:350 — its only consumer, the ⚠️ N of these declare a **major** (breaking) bump line.

    Per the domain table, scripts/ (gate class) is domain:devx, and the SKILL puts the console pin/refresh script family (build-console.sh, bump-objectui.sh, check-console-sha.mjs, check-objectui-pin-fresh.mjs) on that row explicitly; this digest is the same pin-refresh chain. No packages/* surface is touched ⇒ no repo:* routing, no cross-repo split.

    One reading correction worth carrying into the dispatch. The script's own comment at :197–:201 asserts "objectui marks its breaking symbol renames major routinely" — and the whole downgradedMajor path at :301 is built on that assumption. The measured interval inverts it (0 of 64). So the gap is not merely a missing else branch: the script's documented model of upstream behaviour is stale, and the existing self-test only pins the major branch (:496–:566 builds a "@object-ui/layout": major fixture and asserts breaking count is surfaced in the body). There is no coverage at all for the minor + prose-annotation form, which is the form actually in use. A fix that does not add that fixture will regress silently.

    Why not needs-user-decision. The issue correctly flags that direction 2 (reading conventional-commit ! from the subject) sits on #4731's declaration over inference boundary and needs the maintainer. But direction 1 — broaden the criterion to declared level major or a breaking annotation in the changeset body the author wrote — stays entirely inside "declaration": it reads the author's own text, never the commit type, and does not change the collected set. A dispatchable path therefore exists with no contract call pending, so the issue does not belong in the maintainer's inbox. The dispatch prompt should carry the boundary: implement direction 1; if you conclude direction 2 is required, STOP and return needs_decision rather than crossing #4731's line unilaterally. Direction 3 (upstream convention only) is not a fix — it re-creates the same dependence on authoring habit this issue is about.

    Dedup. No duplicate. Method recorded because the shortcut is unavailable to this seat: the GitHub search API is blocked for repository-scoped sessions, so dedup was done by full paginated enumeration of all open issues and PRs in the three repos plus local matching on digest / changeset / breaking / 破坏性. Adjacent-but-distinct records checked one by one:

    Stale-premise check. git fetch origin main; both the filter line and its single consumer are present verbatim on origin/main. PR #6097 (MERGED) touched only .objectui-sha and the generated .changeset/console-f995a452d2ca.md — not the script — so nothing in flight has already fixed this.

    Serial constraints. Open pm:dispatched issues in domain:devx — #6046 (check-override-consistency), #5866 (dispatch prompt), #5925 (SKILL update batch), #4251 (service-lookup lint rule) — none touches scripts/objectui-changeset-digest.mjs. No file-surface intersection; dispatchable without waiting.

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


    Generated by Claude Code

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

    @hotlong
    ContributorAuthor

    ⛔ 认领(claim)

    派 1 名 os-dev。


    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