---
id: 11185
title: Detect stale magic-close keywords in PR commit bodies
state: CLOSED
labels:
  - bug
  - documentation
  - ai
  - regression
  - model-experience
assignees:
  - neo-gpt
createdAt: '2026-05-11T07:00:36Z'
updatedAt: '2026-05-11T07:23:09Z'
githubUrl: 'https://github.com/neomjs/neo/issues/11185'
author: neo-gpt
commentsCount: 0
parentIssue: null
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy: []
blocking: []
closedAt: '2026-05-11T07:23:09Z'
---
# Detect stale magic-close keywords in PR commit bodies

## 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:

1. 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.
2. 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.
3. 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.
4. 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`.
5. 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

- [ ] `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.
- [ ] Reviewer audit instructions include a branch commit-body scan command or equivalent.
- [ ] Reviewer resolution guidance blocks approval for partial-resolution PRs with stale magic-close commit bodies unless the branch is cleaned or a clean superseding PR is used.
- [ ] `pull-request-workflow.md` includes the symmetric author pre-handoff check for `Refs #N` partial PRs.
- [ ] The docs cite PR #11183 / commit `5c7c5a2f4` / #11182 reopen as the empirical anchor.
- [ ] Added text is compact and placed in existing close-target sections rather than creating a large new top-level rule.

## 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

- PR #11183
- PR #11184
- Issue #11182
- Merge commit `5c7c5a2f4`

## 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'`


## Timeline

- 2026-05-11T07:00:38Z @neo-gpt added the `bug` label
- 2026-05-11T07:00:38Z @neo-gpt added the `documentation` label
- 2026-05-11T07:00:38Z @neo-gpt added the `ai` label
- 2026-05-11T07:00:38Z @neo-gpt added the `regression` label
- 2026-05-11T07:00:39Z @neo-gpt added the `model-experience` label
- 2026-05-11T07:04:08Z @neo-gpt assigned to @neo-gpt
- 2026-05-11T07:07:47Z @neo-gpt cross-referenced by PR #11186
- 2026-05-11T07:23:09Z @tobiu referenced in commit `37a8eb8` - "docs(ai): detect stale close keywords in commit bodies (#11185) (#11186)

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-11T07:23:09Z @tobiu closed this issue

