fix(agent-actions): never approve a repeat unlinked-issue offender's PR it is closing - #6695
Conversation
…PR it is closing
planAgentMaintenanceActions guarantees a coherent disposition set ("never
both merge and close"). The approve guard excluded the linked-issue and
conflict close paths (!linkedIssueCloseInFlight, !isConflict) but omitted the
third close path that can coexist with a review-good PR: a confirmed repeat
unlinked-issue offender (unlinkedIssueMatchViolated).
So a green, clean, not-yet-approved PR from a confirmed repeat offender, with
both approve and close autonomy acting, was planned as an incoherent
["approve", "close"] pair — the bot approves the very PR it closes as a
repeat violation, and leaves a stale approval behind. heldForManualReview
does not catch this: its unlinked term is gated on !acting("close"), which is
false precisely when close is acting.
Add !unlinkedIssueMatchViolated to the approve guard, matching the sibling
close paths (lines 1092, 1128-1134) that already carry it. Now the plan is a
single close. Every other approve/close/merge disposition is unchanged.
Adds a regression test asserting the plan contains close and not approve for
this input.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
1 similar comment
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6695 +/- ##
==========================================
- Coverage 93.65% 93.65% -0.01%
==========================================
Files 682 682
Lines 68118 68112 -6
Branches 18711 18708 -3
==========================================
- Hits 63795 63788 -7
Misses 3347 3347
- Partials 976 977 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Caution 🛑 LoopOver review result - reject/close recommendedReview updated: 2026-07-16 19:50:48 UTC
Review summary Nits — 4 non-blocking
Why this is blocked
📋 Copy for AI agents — paste into your coding agentDecision drivers
Context & advisory signals — never blocks the verdict
Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
|
LoopOver is closing this pull request on the maintainer's behalf (No linked issue detected; Maintainer requires a linked issue). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed. |
Bug (self-found, no issue)
planAgentMaintenanceActions(src/settings/agent-actions.ts) documents that it returns a coherent disposition set — its contract comment: "never both merge and close", and the approve guard's own comment: approving "a PR we're about to close is incoherent (and a stale approval strands the PR if it later goes green)."The approve guard excludes two of the three close paths that can coexist with a review-good PR —
!linkedIssueCloseInFlightand!isConflict— but omits the third: a confirmed repeat unlinked-issue offender,unlinkedIssueMatchViolated(which fires its own one-shotclose).Triggering input
A green, gate-passing, not-yet-approved PR from a confirmed repeat unlinked-issue offender, with both
approveandcloseautonomy acting:conclusion: "success"→reviewGood === trueautonomy: { approve: "auto", close: "auto" }unlinkedIssueMatchCloseset,mergeableState: "clean",reviewDecisionunsetResult: the plan is
["approve", "close"]— the bot approves the very PR it is closing as a repeat violation, and leaves a stale approval behind.heldForManualReviewdoes not catch this: its unlinked term isinput.unlinkedIssueMatchClose !== undefined && !acting("close"), which is deliberately false exactly whencloseis acting — the scenario here.Fix
Add
!unlinkedIssueMatchViolatedto the approve guard — the same term the sibling close paths already carry (lines 1092 and 1128–1134). The one place that checked!linkedIssueCloseInFlightbut forgot!unlinkedIssueMatchViolatedis now consistent, so a repeat offender's PR gets a singlecloseand no approval.Every other approve / merge / close / hold disposition is unchanged.
Test
Adds a regression test to the "unlinked-issue-match CLOSE" suite asserting the plan contains
closeand notapprovefor the triggering input. Verified it fails on the current code (plan is["approve","close"]) and passes with the fix.agent-actionssuite: 287/287 pass.src/settings/agent-actions.ts: statements/lines 100%, and the changed guard line's new branch is covered on both outcomes (repeat-offender → approve suppressed; normal → approve proceeds), so the patch is fully covered.