Skip to content

fix(miner): refuse a duplicate attempt when this miner already has an open PR for the exact issue#8815

Merged
JSONbored merged 1 commit into
mainfrom
fix/ams-own-open-pr-idempotency
Jul 26, 2026
Merged

fix(miner): refuse a duplicate attempt when this miner already has an open PR for the exact issue#8815
JSONbored merged 1 commit into
mainfrom
fix/ams-own-open-pr-idempotency

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

AMS audit fix (#8808): a crash between PR-open and the attempt's finally left an orphaned open PR that nothing downstream would ever treat as a conflict — claim-conflict resolution deliberately exempts the miner's own PRs, freshness excludes same-author PRs, and the issue-tagged own-submissions ledger was never consulted — so a retry double-opened.

Changes

  • rejection-signal.tsresolveOwnOpenPrForIssue(repo, issue): issue-matched own submissions → bounded live PR-state checks (same maxRejectionHistoryChecks fan-out cap) → first still-OPEN PR number, else null. Fully fail-open (store read failure, fetch rejection, degenerate inputs → null): an idempotency guard must never block a legitimate attempt on a hiccup. A closed/merged prior PR never blocks. Shared option plumbing extracted into resolveHistoryOptions (reused by the Check a miner's own prior-rejection history on a repo (rejectionSignaled's second documented trigger) #5655 sibling — no duplicated arms).
  • attempt-cli.ts — refuses before a worktree slot is consumed, mirroring the rejection-signal block: attempt_aborted/attempt_blocked events + blocked_own_open_pr result naming the existing PR, exit 5, injection seam mirroring resolveRejectionSignaled. Refuse—not adopt: the still-open PR is already doing this issue's job.

Test plan

  • npm run typecheck clean; @loopover/miner builds
  • 6 resolver tests (open-PR hit, issue-mismatch no-fetch, closed-doesn't-block, both fail-open arms, fan-out bound + degenerate inputs + non-array guard) and 3 attempt-cli wiring tests (refusal before allocator.acquire, JSON + stderr shapes, null-proceeds)
  • 135 tests green across both suites
  • Every changed line (script-verified against the diff): 0 uncovered statements/branches

Closes #8808

… open PR for the exact issue (#8808)

The crash-retry double-open guard the audit found missing: claim-conflict
resolution deliberately never treats the miner's own sibling PR as a
competing claim, submission-freshness excludes same-author PRs, and nothing
queried the issue-tagged own-submissions ledger before starting a new
attempt — so a process killed after PR-open but before the finally block
completed could double-open on retry, with no cleanup.

- resolveOwnOpenPrForIssue (rejection-signal.ts, sharing the sibling
  resolver's option plumbing via a new extracted resolveHistoryOptions):
  reads the miner's own issue-matched submissions, live-checks the bounded
  most-recent candidates, returns the first still-OPEN PR number. FULLY
  fail-open — any read/fetch failure returns null so a hiccup never blocks
  a legitimate attempt (freshness + the claim ledger stay the backstops);
  a closed/merged prior PR never blocks a fresh one.
- attempt-cli refuses BEFORE a worktree slot is consumed (mirroring the
  rejection-signal block): attempt_aborted/attempt_blocked events carry the
  existing PR number, outcome blocked_own_open_pr, exit 5. Refusing (not
  adopting) is the safe disposition — the open PR is already doing the job.
@JSONbored JSONbored self-assigned this Jul 26, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.27%. Comparing base (11fb8ee) to head (eae5e2d).
⚠️ Report is 7 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8815      +/-   ##
==========================================
- Coverage   93.81%   92.27%   -1.55%     
==========================================
  Files         797      797              
  Lines       79608    79635      +27     
  Branches    24127    24136       +9     
==========================================
- Hits        74686    73484    -1202     
- Misses       3556     5090    +1534     
+ Partials     1366     1061     -305     
Flag Coverage Δ
backend 92.95% <100.00%> (-2.15%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/loopover-miner/lib/attempt-cli.ts 100.00% <100.00%> (ø)
packages/loopover-miner/lib/rejection-signal.ts 98.95% <100.00%> (+0.20%) ⬆️

... and 2 files with indirect coverage changes

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 26, 2026
@loopover-orb

loopover-orb Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Important

🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪

🔍 LoopOver is reviewing…

AI analysis is in progress. This comment will update when the review is complete.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed · 🟪 Reviewing

@JSONbored
JSONbored merged commit d5ec15a into main Jul 26, 2026
7 checks passed
@JSONbored
JSONbored deleted the fix/ams-own-open-pr-idempotency branch July 26, 2026 07:51
@github-actions github-actions Bot mentioned this pull request Jul 26, 2026
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(miner): pre-attempt idempotency check against the miner's own open PR for the same issue — stop crash-retry double-opens

1 participant