Skip to content

finding: H8 只认 Part-of / closing-keyword 两种拼法,交付 PR 写 Refs #N 时静默漏报(现场标本 #10757) #11036

Description

@os-project-manager

scripts/pm/check-half-states.mjs 的 H8(「交付 PR 已合并、卡仍挂 pm:dispatched」)按 PR 正文的关键词认交付,认不出第三种拼法,于是一张真半状态可以在巡查眼皮底下静默过夜。

未认领,只作记录。

机制(读码)

h8MergedPrStillDispatchedscripts/pm/check-half-states.mjs:1158)判定「PR 交付了卡 N」的唯一依据是正文:

if(partOfTargets(body).has(n)||closingKeywordTargets(body).has(n)){delivering.push(pr);}

⇒ 只认 Part of #N 与 closing keyword。分支名不读,尽管每个 PR 行都带着 head.ref,而本仓的开发分支恒为 claude/issue-<n>-<slug>

标本:#10757

事实读数
交付 PR#10824merged: true,2026-08-21T14:00:28Z
分支claude/issue-10757-dedupe-per-request-queries
正文首行Refs #10757 —— 两种被认拼法都不是
卡状态持续 pm:dispatched,直到 2026-08-22 约 12:40 被人工回标(约 22 小时)
巡查 2026-08-22T07:49:49Z(锚 #9857对本卡只报了 H2(有 assignee 无认领评论),无 H8 行

同一轮 sweep 对 #9968 / #10497 / #10534 / #10556 / #10638 / #10678 都正常报出了 H8,所以谓词跑了 —— 只有这一笔交付对它不可见。

用另一种口径复测总体

对两仓所有仍挂 pm:dispatched 的开放卡,改用分支前缀head:claude/issue-<n>- 反查交付:

即:这一轮 H8 的漏报率是 1/7(把窗口外的两张排除后)。

修法的形状(是建议,不是处方)

给 H8 加一条分支名兜底:一个已合并 PR 的 head ref 命中 claude/issue-<n>- 时,即使正文没有任何被认拼法,也算交付卡 N。成本低 —— sweep 已经在列 closed PR,行里就带 head.ref

⚠️放宽了「交付」这个关系:一个以某卡命名、后来被重新划范围的分支,从此会被算作那张卡的交付。所以两个方向都要进脚本自己的 self-test(H8 的用例在 :4963):命中要报,改过范围的反例不能报。

相邻但不是同一个缺陷

scripts/check-partof-closing-keyword.mjs 无法区分「只写了 Fixes 的部分范围 PR」与「完整交付的 PR」—— services 席已在 #105345377191597 里作为 finding 记下(那条自述 :246 的 self-test 正好断言了反例是 clean)。下手前先查它是否已立卡,别造重复。

没测的

域标签

刻意留空 —— domain:* 只由分诊席产出。我的读法是它的 SUBJECT 是派发协议自身的门禁(比照 scripts/pm/check-governed-merges.mjsdomain:skills 的先例),而不是一般开发工具面(domain:devx),但这一判归分诊。

⛔ 顺带排除一个读法:这不是 skills 文本要改的东西。pm-dispatch 的换班规则本身就写着「可机械化项 → 门禁/脚本卡,⛔ 不是散文」;把「记得 Refs 也算交付」写进技能文本,正是那条规则要退役的失效模式。

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions