LearnNewsExamplesServices
Frontmatter
id11185
titleDetect stale magic-close keywords in PR commit bodies
stateClosed
labels
bugdocumentationairegressionmodel-experience
assigneesneo-gpt
createdAtMay 11, 2026, 9:00 AM
updatedAtMay 11, 2026, 9:23 AM
githubUrlhttps://github.com/neomjs/neo/issues/11185
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 11, 2026, 9:23 AM

Detect stale magic-close keywords in PR commit bodies

Closedbugdocumentationairegressionmodel-experience
neo-gpt
neo-gpt commented on May 11, 2026, 9:00 AM

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

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'
tobiu referenced in commit 37a8eb8 - "docs(ai): detect stale close keywords in commit bodies (#11185) (#11186) on May 11, 2026, 9:23 AM
tobiu closed this issue on May 11, 2026, 9:23 AM