Context
PR #11183 empirically proved that stale magic-close keywords inside branch commit bodies can still close a GitHub issue even when the PR body has been corrected to Refs #N.
Observed sequence:
- PR #11183 originally had first commit
deb022d0c with Resolves #11182 and stale AC wording.
- Later PR body and second commit changed the live framing to
Refs #11182; gh pr view 11183 --json closingIssuesReferences returned [] before merge.
- PR #11183 was squash-merged as dev commit
5c7c5a2f4.
- GitHub auto-closed #11182 anyway.
- #11182 had to be manually reopened. Claude's reopen comment ties the auto-close to the stale
Resolves #11182 in the squash commit body.
This validates the PR #11183 Cycle 2 branch-history RA as load-bearing, not cosmetic.
The Problem
The current review discipline treats PR body close-target state and GitHub's pre-merge closingIssuesReferences surface as sufficient evidence that a PR will not auto-close an issue. That is false under the repository's squash-merge path.
GitHub's squash commit body can concatenate branch commit bodies. If any branch commit body contains Closes #N, Fixes #N, or Resolves #N, the resulting dev-tip commit can still trigger auto-close, even if:
- the PR body says
Refs #N,
- the latest commit body says
Refs #N,
closingIssuesReferences is empty before merge,
- reviewers have already downgraded the issue to non-blocking branch hygiene.
This creates a repeatable false-negative in the close-target audit.
The Architectural Reality
Relevant workflow surfaces:
.agents/skills/pr-review/references/pr-review-guide.md §5.2: reviewer-side close-target audit already says to parse PR body and commit messages, but it does not explicitly capture squash-merge commit-body preservation as a post-merge auto-close mechanism.
.agents/skills/pull-request/references/pull-request-workflow.md: author-side PR workflow controls commit and PR body hygiene before handoff.
- PR #11183 / merge commit
5c7c5a2f4: empirical anchor showing stale commit-body Resolves #11182 survived squash merge and auto-closed #11182.
- #11182 reopen comment: confirms actual issue state damage and manual repair.
The Fix
Update the workflow documentation / skill substrate so both authors and reviewers treat branch commit bodies as merge-time close-target surfaces.
Recommended implementation shape:
- In
pr-review-guide.md §5.2, add an explicit squash-merge note: commit-body magic close keywords are load-bearing even when the PR body is corrected and closingIssuesReferences is empty.
- In the reviewer close-target audit, require scanning
git log origin/dev..HEAD --format='%h%x09%s%n%b' or equivalent for magic close keywords whenever a PR is partial / multi-phase / leaves the referenced issue open.
- Define the resolution ladder:
- clean branch / Drop+Supersede when no operator auth exists for rewrite,
- operator-explicit auth for amend/rebase/force-push when preserving the same PR is preferred,
- do not approve with stale magic-close commit bodies on partial-resolution PRs.
- In
pull-request-workflow.md, add the author-side pre-handoff check: if the PR body uses Refs #N because the ticket stays open, no commit body in origin/dev..HEAD may contain Closes/Fixes/Resolves #N.
- Keep wording concise. This is a high-severity tripwire, not a new long-form theory section.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
| Reviewer close-target audit |
PR #11183 / commit 5c7c5a2f4 / #11182 reopen |
Reviewers scan PR body and branch commit bodies; stale magic close in any commit body blocks partial-resolution PR approval |
Drop+Supersede clean branch or operator-authorized rewrite |
pr-review-guide.md §5.2 |
Reproducer: #11182 auto-closed despite PR body Refs |
| Author PR handoff |
pull-request-workflow.md close-target discipline |
Authors ensure Refs #N PRs have no stale Closes/Fixes/Resolves #N in origin/dev..HEAD commit bodies |
Create clean replacement PR when rewrite is unsafe |
pull-request-workflow.md |
git log origin/dev..HEAD --format='%h%x09%s%n%b' |
Acceptance Criteria
Out of Scope
- Changing GitHub repository merge settings.
- Adding automation that rewrites commits.
- Reworking all close-target discipline across AGENTS.md.
- Retrospectively editing already-merged commit history.
Avoided Traps
- Relying on
closingIssuesReferences alone: empirically insufficient before squash merge.
- Treating stale commit bodies as cosmetic: disproven by #11182 auto-close.
- Forcing amend/rebase/force-push without operator authorization: conflicts with workflow safety; clean replacement PR is the compliant path.
- Adding a large new rule block: this should be a surgical close-target audit tripwire.
Related
Origin Session ID
22713fa8-23d2-4b31-918b-6e2f48d69c06
Handoff Retrieval Hints
query_raw_memories(query="squash merge stale Resolves commit body auto close")
query_raw_memories(query="PR 11183 branch-history RA closingIssuesReferences")
gh api repos/neomjs/neo/commits/5c7c5a2f4 --jq '.commit.message'
Context
PR #11183 empirically proved that stale magic-close keywords inside branch commit bodies can still close a GitHub issue even when the PR body has been corrected to
Refs #N.Observed sequence:
deb022d0cwithResolves #11182and stale AC wording.Refs #11182;gh pr view 11183 --json closingIssuesReferencesreturned[]before merge.5c7c5a2f4.Resolves #11182in the squash commit body.This validates the PR #11183 Cycle 2 branch-history RA as load-bearing, not cosmetic.
The Problem
The current review discipline treats PR body close-target state and GitHub's pre-merge
closingIssuesReferencessurface as sufficient evidence that a PR will not auto-close an issue. That is false under the repository's squash-merge path.GitHub's squash commit body can concatenate branch commit bodies. If any branch commit body contains
Closes #N,Fixes #N, orResolves #N, the resulting dev-tip commit can still trigger auto-close, even if:Refs #N,Refs #N,closingIssuesReferencesis empty before merge,This creates a repeatable false-negative in the close-target audit.
The Architectural Reality
Relevant workflow surfaces:
.agents/skills/pr-review/references/pr-review-guide.md§5.2: reviewer-side close-target audit already says to parse PR body and commit messages, but it does not explicitly capture squash-merge commit-body preservation as a post-merge auto-close mechanism..agents/skills/pull-request/references/pull-request-workflow.md: author-side PR workflow controls commit and PR body hygiene before handoff.5c7c5a2f4: empirical anchor showing stale commit-bodyResolves #11182survived squash merge and auto-closed #11182.The Fix
Update the workflow documentation / skill substrate so both authors and reviewers treat branch commit bodies as merge-time close-target surfaces.
Recommended implementation shape:
pr-review-guide.md§5.2, add an explicit squash-merge note: commit-body magic close keywords are load-bearing even when the PR body is corrected andclosingIssuesReferencesis empty.git log origin/dev..HEAD --format='%h%x09%s%n%b'or equivalent for magic close keywords whenever a PR is partial / multi-phase / leaves the referenced issue open.pull-request-workflow.md, add the author-side pre-handoff check: if the PR body usesRefs #Nbecause the ticket stays open, no commit body inorigin/dev..HEADmay containCloses/Fixes/Resolves #N.Contract Ledger Matrix
5c7c5a2f4/ #11182 reopenpr-review-guide.md§5.2Refspull-request-workflow.mdclose-target disciplineRefs #NPRs have no staleCloses/Fixes/Resolves #Ninorigin/dev..HEADcommit bodiespull-request-workflow.mdgit log origin/dev..HEAD --format='%h%x09%s%n%b'Acceptance Criteria
pr-review-guide.md§5.2 explicitly states that squash-merge can preserve branch commit-body magic-close keywords and trigger post-merge issue closure.pull-request-workflow.mdincludes the symmetric author pre-handoff check forRefs #Npartial PRs.5c7c5a2f4/ #11182 reopen as the empirical anchor.Out of Scope
Avoided Traps
closingIssuesReferencesalone: empirically insufficient before squash merge.Related
5c7c5a2f4Origin Session ID
22713fa8-23d2-4b31-918b-6e2f48d69c06Handoff Retrieval Hints
query_raw_memories(query="squash merge stale Resolves commit body auto close")query_raw_memories(query="PR 11183 branch-history RA closingIssuesReferences")gh api repos/neomjs/neo/commits/5c7c5a2f4 --jq '.commit.message'