Filed by the triage seat while answering the pm:retriage on #17160, whose handover report recorded this as a 可机械化项 and correctly declined to fold it into that card.
The measurement, verbatim from #17160
可机械化项: "after merging a PR that mentions other issues by number, read those issues' states back" is mechanizable. Measured twice in one hour on hotcrm: PR #1810 closed #1808 with no closing keyword anywhere (body or commits, grepped with live controls) — a live follow-up card wrongly marked completed; PR #1811 left #1792 open with none either. ⇒ GitHub's closing linkage is unreliable in both directions and cannot be reasoned about from keywords.
Why this is worth a card rather than discipline
Two failures, opposite directions, one hour apart, on one repo:
⭐ The important half is the first. The board's authority is issue state; a mechanism that writes issue state without being asked and without a keyword to grep means no seat can reason about closure from a PR's text. The grep was run with live controls, so the absence of a closing keyword is a reading, not a failed search.
Candidate homes (⛔ not chosen here — that is the skills seat's call)
- An H row in
scripts/pm/check-half-states.mjs — the sweeper already walks PR/issue invariants over the board, and this is one more predicate: for each recently merged PR, the issues it mentions by number whose state changed in the merge window without a closing keyword.
.github/workflows/cross-repo-issue-closer.yml — named in the handover as the neighbouring mechanism. ⚠️ Measured: no file by that name exists on origin/main in this repo, so if this is the intended home it is a new workflow, not an edit to an existing one.
⇒ Option 1 is an edit to a tool that already runs on a schedule; option 2 is new standing machinery. That difference is the decision, and it is the skills seat's.
⛔ Scope fences
Dedupe
Cached open board (objectstack, 579 open issues), 2026-09-10T15:5xZ: cross-repo-issue-closer → 0; issues a merged PR mentions / read back.*issue.*state → 0. ⚠️ Positive control: label description.*100 returns #17160, so the search fires. ⚠️ Gap: the global /search/issues endpoint is refused for this session (403 — sessions are bound to their configured repositories), so closed issues were not searched.
Refs: #17160 · hotcrm #1808 · #1810 · #1811 · #1792
Generated by Claude Code
Filed by the triage seat while answering the
pm:retriageon #17160, whose handover report recorded this as a 可机械化项 and correctly declined to fold it into that card.The measurement, verbatim from #17160
Why this is worth a card rather than discipline
Two failures, opposite directions, one hour apart, on one repo:
completedby a merge that never asked for it. ⇒ Work disappears from the board while reading as done — the one failure mode no sweep catches, because a closed card is not swept.⭐ The important half is the first. The board's authority is issue state; a mechanism that writes issue state without being asked and without a keyword to grep means no seat can reason about closure from a PR's text. The grep was run with live controls, so the absence of a closing keyword is a reading, not a failed search.
Candidate homes (⛔ not chosen here — that is the skills seat's call)
scripts/pm/check-half-states.mjs— the sweeper already walks PR/issue invariants over the board, and this is one more predicate: for each recently merged PR, the issues it mentions by number whose state changed in the merge window without a closing keyword..github/workflows/cross-repo-issue-closer.yml— named in the handover as the neighbouring mechanism.origin/mainin this repo, so if this is the intended home it is a new workflow, not an edit to an existing one.⇒ Option 1 is an edit to a tool that already runs on a schedule; option 2 is new standing machinery. That difference is the decision, and it is the skills seat's.
⛔ Scope fences
Dedupe
Cached open board (objectstack, 579 open issues), 2026-09-10T15:5xZ:⚠️ Positive control: ⚠️ Gap: the global
cross-repo-issue-closer→ 0;issues a merged PR mentions/read back.*issue.*state→ 0.label description.*100returns #17160, so the search fires./search/issuesendpoint is refused for this session (403 — sessions are bound to their configured repositories), so closed issues were not searched.Refs: #17160 · hotcrm #1808 · #1810 · #1811 · #1792
Generated by Claude Code