Skip to content

[finding] the Clause-②: declaration lives in the PR body, so any unrelated body edit destroys it silently — measured: three runs of one check on one head SHA #16949

Description

@claude

维护者速读

每个 PR 都要一句「这次动没动契约」的声明。说动了的那句有两个不会丢的地方可放(一个标签,加 changeset 文件里的一行);说没动的那句只有一个地方——PR 描述框里的一行纯文字。任何人顺手重写描述,它就没了,且没有任何记录说它曾经在。已真实发生过一次:同一个 commit、没有推送,只因 dev 按要求改了描述,门禁从绿变红;补回那行字又变回绿。

说「没动」是多数:本席现读最近 120 个已合并 PR,85 个「没动」、25 个「动了」。而这 85 个里 63 个连 changeset 文件都没有(它们本来就不发布东西)⇒「把那句话写进 changeset」这条最省事的路,对其中四分之三没有文件可写。

四条路:A 维持现状加一道门禁(描述被删就报红);B 搬进 changeset 文件;C 给「没动」发一个对等标签;D 只写文档。本席荐 C,回退 B。

请裁一个字母:A / B / C / D。

① 项目长远合理性:今天「动了」有耐久载体、「没动」没有,这是一条不对称的特例;给「没动」一条对等载体是收缩特例,而只给纯文字再加一道守卫是扩大(多养一个只为自由文本而生的门禁)。
② 实际业务拉动:撞上的是每一个如实声明「没动」的 PR 作者与审查者,占本席实测样本的 85/120;已实测发生过一次真实丢失(PR #16916,同一 SHA,两分钟内复原)⇒ ⛔ 不是零拉动。
③ 防 AI 犯错:自由文本无 schema、无历史、任何 agent 改描述都可能无声抹掉它——这正是一次静默丢失;标签有 label-write 纪律与 timeline,丢了看得见,属响亮那一侧。⚠️ B 路在 63/85 的 skip-changeset PR 上没有载体,会把「丢失」换成「无处可写」。
④ 创业阶段不扩散:C 确实新增一个治理标签(永久义务),⚠️ 这是 C 的真实代价;但它不新增概念——Clause-② 的两个臂已经都在协议里,C 只是让「no」臂用上「yes」臂早就有的那种载体。

Prior rulings read: clause-②,declaration,carrier,pr body,label → 29 hits; ADR-0020 D1, ADR-0020 D4, ADR-0029 D1, ADR-0044 D2, ADR-0057 D7, ADR-0058 D6; thread: none
⛔ 六条的标题本席现读过,唯一可能相关的 ADR-0020 D1(「One declaration shape」)通读后是对象 spec 的状态机声明形状 ⇒ 无一条回答本卡的载体问题,本卡仍是决策而非执行。

Governing text: AGENTS.md:1066-1068(「The declaration is Clause-②: yes|no plus at most one arm…」)· AGENTS.md:1078-1080(breaking changeset 的 ADR-0087 标记住在 changeset 正文,「which also carries the PR's Clause-② line」)· scripts/check-changeset-no-major.mjs:1226-1228(解析器:yes 两条路 = 标签载体或正文行;no 只有正文行一条)。

选项 × 真实代价(本席现读 origin/main 24d622b94)

做什么 作者/审查者可感知的后果
A 正文仍是载体,加一道「曾经有、现在没了就红」的门禁 丢失更早被发现,⛔ 仍会丢;分诊已明说这不是对等载体——yes 从不需要这道守卫
B 声明写进 changeset 正文(yes 的 ADR-0087 标记已住那里) 随 diff 进 review 与 git 历史;⛔ 但 63/85 的「没动」PR 带 skip-changeset、没有 changeset 文件 ⇒ 对多数无解,除非强制非发布 PR 也写 changeset(与 AGENTS.md 第 3 条矛盾)
C 给「没动」发一条与 needs:contract-review 对等的治理标签 覆盖全部 85 个,不依赖有没有 changeset;⚠️ 新增一个永久义务的治理标签,且标签词表那一半按车道表属 domain:skills
D 机制不动,只把风险写进作者读得到的地方 零实现成本;⛔ 不改变任何一次丢失,把治理记录的耐久性留给人的记性

推荐 —— C,回退 B

只看①得出:两年后这个平台该有的样子是「一条治理声明有一个耐久载体,两个臂对称」。C 给出对称;B 在结构上给不出——一个不发布任何东西的 PR 按构造没有 changeset 文件,除非推翻 AGENTS.md 第 3 条。
自检行:只看①选 C;②③④ 是否翻转:否。 ④ 确实反对新增已声明键,但它反对的是新增概念;Clause-② 的两个臂已在协议里,C 只补载体。
置信缺口:⛔ 未测标签能否由 ensure-pm-labels.sh 铸出而不动受管面;⛔ 未测 check-changeset-no-major.mjs:1226-1228 的优先序能否在不推翻既有判定下读一个 no 标签;⚠️ 同一次枚举里另有 10/120 个已合并 PR 连行首 Clause-② 都没有,本席未核实门禁当时是否对它们要求过该行——那可能是另一张卡。

裁后执行(让您只裁方向)

裁 C ⇒ 拆两半:标签词表与铸造归 domain:skills(分诊 5599637112 已预告「选了新增标签这条路就回报同笔改判 skills」),解析器那一半留 domain:devx;无下游被阻塞卡。裁 B/A ⇒ 全落 domain:devx,本席即可派发。裁 D ⇒ 落点 AGENTS.md(Tier H 受管面)⇒ 草稿 PR + ## 维护者速读(草稿),人工合并。


⬇️ 原卡面,⛔ 一字未改。

The Clause-②: declaration lives in the PR body, and any ordinary body edit destroys it — silently, with no warning to whoever edits and no trace except the gate flipping to not-measured-*. Measured live today, not from inspection.

Filed unlabelled by the domain:devx execution PM seat. ⛔ Grade and domain:* are triage's. ⛔ Not claiming.

Measured — three runs of one check on ONE head SHA, PR #16916 at 804192a5dc

time what happened Check Changeset
17:57:25Z the body carried a line-start Clause-②: no, written by the PM seat at 16:29Z success
~18:14Z the dev rewrote the PR body while repairing a merge conflict — a legitimate, in-scope edit that had nothing to do with the declaration —
18:14:19Z the edited trigger re-read the body. Line-start ^Clause-②: matches: 0. The whole string Clause appeared 0 times failure
18:16:15Z the PM seat re-declared the identical line success

⛔ No commit was pushed between any of these. The SHA is the same in all three. The only variable is the body.

⭐ Nobody did anything wrong. The dev was told to correct the PR body (it had a measurement to withdraw), it rewrote the body, and the declaration went with it. There is no step in that sequence anyone would flag in review.

Why this is worth a card rather than a shrug

⭐ This is the carrier the two cards that just landed both depend on.

⇒ Both rest on the body being a durable carrier for a governance declaration. It is not. It is a mutable free-text field with no history anyone reads, no schema, and no protection — and the gate's own remedy text points authors straight at it.

⚠️ The failure direction here is the good one, and that is the only reason this is not p1: losing the line makes the gate refuse, loudly, because #16776 landed. ⛔ Before this morning the same loss would have produced LEVEL AXIS: NOT MEASURED at exit 0 — a silent green. So the observable cost today is a confusing red on an unrelated PR; the structural cost is that a governance record is one careless edit from gone.

⭐ And note the asymmetry that makes it nastier than it looks: the carrier label (needs:contract-review) is protected by label-write discipline and shows up in the timeline. The body line, which exists precisely to outlive the carrier, has neither.

⛔ What this card does NOT claim

Reproduce

Cheapest form, no repo needed: on any open PR whose diff moves packages/*/src/** with a patch changeset and which carries a line-start Clause-②: line, edit the body to remove that line and read Check Changeset on the unchanged head. Firing control: re-add the line and watch the same check go green on the same SHA. Both directions were driven above.

Related


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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions