Filed by the domain:skills seat (session session_019RfFHiRCSs3JXLK4cwcfox, os-steve) from the maintainer's 2026-09-05 design discussion on issue ownership. Observation class for the devx lane: finding, ungraded — the grade and the route are triage's. Scope is the CI gate, not the protocol text (the text lands with #15379 member 5).
The gap
Every agent here shares one GitHub identity, so the assignee field is a presence bit and the Claim: comment (session ID + branch, first line beginning Claim:) is the identity record. Two guards already run at PR time — "No other open PR may claim the same issue" and the single-writer path check — but neither asks the one question that decides ownership: does the card this PR closes carry a Claim: naming this PR's head branch? Today that question is asked only by scripts/pm/check-half-states.mjs row H46, a report-only patrol input that runs after the fact. The cloud-repo incident (an epic seat and a lane PM implementing one card 29 minutes apart, the second without a claim comment) and the objectstack card implemented twice in one morning were both visible to H46's predicate and stopped by nothing.
What is proposed
A required PR check: for every closing-keyword target #n in the PR body (the same parser check-closing-keyword-parity pins), read #n's comments and require at least one comment whose first line begins Claim: and whose body names the PR's head branch (the predicate is CLAIM_COMMENT_MARKER and the branch reading check-clause2-carriers.mjs already uses — import, never restate). A Part of target is not a closing target and is not checked. Failure text names the card, the branch, and the remedy (post the claim in the fixed spelling, or drop the closing keyword). Merge-queue builds see the same PR body, so the check holds in the queue too.
What it decides
- The second implementer of a card cannot land, whoever forgot the protocol: the first
Claim: wins at merge time, not only at patrol time.
- The check reads comments (one REST page per closing target), so its cost is bounded by the closing-keyword count of the PR.
- Out of scope: any change to what a claim IS (the 2026-08-11 ruling fixes the first line), any assignee-field logic, and H46 itself (it stays as the patrol's after-the-fact view).
Dedup
REST enumeration 2026-09-05T10:3xZ, state=all sorted by update (1,200 items, 797 issues, back to 2026-09-03T15:53Z; positive controls #15667 and #15287 hit): no card proposes a PR-time claim check; #15667 (closed) added H46 as report-only and named the gate half as out of its scope.
Generated by Claude Code
Filed by the
domain:skillsseat (sessionsession_019RfFHiRCSs3JXLK4cwcfox, os-steve) from the maintainer's 2026-09-05 design discussion on issue ownership. Observation class for the devx lane:finding, ungraded — the grade and the route are triage's. Scope is the CI gate, not the protocol text (the text lands with #15379 member 5).The gap
Every agent here shares one GitHub identity, so the assignee field is a presence bit and the
Claim:comment (session ID + branch, first line beginningClaim:) is the identity record. Two guards already run at PR time — "No other open PR may claim the same issue" and the single-writer path check — but neither asks the one question that decides ownership: does the card this PR closes carry aClaim:naming this PR's head branch? Today that question is asked only byscripts/pm/check-half-states.mjsrow H46, a report-only patrol input that runs after the fact. The cloud-repo incident (an epic seat and a lane PM implementing one card 29 minutes apart, the second without a claim comment) and the objectstack card implemented twice in one morning were both visible to H46's predicate and stopped by nothing.What is proposed
A required PR check: for every closing-keyword target
#nin the PR body (the same parsercheck-closing-keyword-paritypins), read #n's comments and require at least one comment whose first line beginsClaim:and whose body names the PR's head branch (the predicate isCLAIM_COMMENT_MARKERand the branch readingcheck-clause2-carriers.mjsalready uses — import, never restate). APart oftarget is not a closing target and is not checked. Failure text names the card, the branch, and the remedy (post the claim in the fixed spelling, or drop the closing keyword). Merge-queue builds see the same PR body, so the check holds in the queue too.What it decides
Claim:wins at merge time, not only at patrol time.Dedup
REST enumeration 2026-09-05T10:3xZ,
state=allsorted by update (1,200 items, 797 issues, back to 2026-09-03T15:53Z; positive controls #15667 and #15287 hit): no card proposes a PR-time claim check; #15667 (closed) added H46 as report-only and named the gate half as out of its scope.Generated by Claude Code