fix: prefer the last close/fix/resolve #N match, not the first, when the shadow reviewer resolves a PR's linked issue #500
No reviewers
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
1 participant
Notifications
Total time spent: 48 seconds
Due date
igor
48 seconds
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor!500
Loading…
Reference in a new issue
No description provided.
Delete branch "agent/498-the-review-pass-links-the-wrong-issue-when-a-pr"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What this PR does
#Nmatch, not the first, when the shadow reviewer resolves a PR's linked issueImplements option 1 from the issue (the one-word change):
pr_body_ensure_closes(lib/checkpoint.sh) always appends itsCloses #Nline at the very bottom of a PR body when Claude hasn't already written a real closing keyword for that exact issue, so the bottom-most match is a guarantee from the harness itself, not a heuristic. A body that merely discusses an issue reference earlier on (e.g. quoting an example closing phrase while tracing a root cause) used to win under first-match and hand the reviewer the wrong issue's requirements -- exactly what happened on PR #497, which picked up #490 instead of its real #496.lib/review.sh:review_closed_issue_number--head -1->tail -1bin/test-review.sh: updated the "first match wins" test to reflect the new "last match wins" behavior, and added a regression test modeling PR #497's actual shape (quoted example phrase above the harness-appendedCloses #Nline)Test plan
make testpasses (bin/test-review.shand the full suite)make lintpasses (shellcheck + mdl, no findings on touched files)Closes #498
#Nmatch, not the first, when the shadow reviewer resolves a PR's linked issue🤖 Review —
COMMENT(automated)CI for
b0d17fe0: successOne-word semantic flip (
head -1→tail -1) inreview_closed_issue_number, plus an updated and one new unit test. Correct, in scope, CI green — nothing I'd block on, but two things worth a human's eye before merge.Findings
lib/review.sh:64— the fix trades one failure mode for its mirror image. The stated guarantee ("pr_body_ensure_closesalways appends at the very bottom") only holds when the harness appends; the PR text itself says it doesn't append when Claude already wrote a real closing keyword for that issue. In that case the position of the realCloses #Nis whatever Claude chose, so any prose containing a closing keyword below it now wins — e.g. a body withCloses #496near the top and a later test-plan line quoting "fixes #490". Convention putsCloseslast, so this is probably net-better, but it is a heuristic, not the invariant the comment claims. Worth a sentence in the comment acknowledging the residual case, or option 2 from the ticket.agent:questionticket that explicitly asks the human to pick between option 1 (this) and option 2 (<!-- agent-issue=N -->marker, described in the ticket as "unambiguous"). The PR asserts "Implements option 1" but I can't see any answer from the human in what I was given. If the direction wasn't actually chosen, that's the call to confirm — the ticket author called option 2 the correct-by-construction one.lib/review.sh:43-51— the new comment is nine lines of why for a one-word change, and most of it (PR #497 picked up #490, the quoted example phrase) duplicates the PR description verbatim. It's legal under the comment contract (it's rationale, not narration) and the file already carries a similar igor#444 note, so I'm not calling it a violation — but two lines would carry the same constraint.Tests
last match winscase and the new igor#498 regression case both trace correctly against the regex by hand (Part of #496isn't a keyword match;fixes #490andCloses #496are, last wins → 496). Good shape — it models the real #497 body rather than a synthetic string.lib/checkpoint.shdepends on first-match ordering.pr_body_ensure_closespresumably greps for the specific#N(order-independent), but I can't see that file here.No security, privilege, or CI-config surface touched; diff is minimal and honestly described.
Independent review by the harness on
claude-opus-5(effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.