feat(miner): add a claim reclaim CLI to expire orphaned soft-claims - #9717
Conversation
ClaimLedger.reclaimExpiredClaims existed to expire claims stranded active by a
crashed/killed attempt, but had no production caller -- unlike its named model
reclaimStuckItems, which both runs automatically inside claimNextBatch AND has an
operator escape hatch (`queue release`). A claim left active by a SIGKILLed attempt
therefore counts against the repo's maxConcurrentClaims cap for up to the 14-day
default window, with no command to clear it.
Add `loopover-miner claim reclaim [--max-age-ms <n>] [--dry-run] [--json]`,
mirroring runQueueRelease's parse -> dry-run-short-circuit -> withStore ->
reportCliFailure shape:
- Calls ClaimLedger.reclaimExpiredClaims(maxAgeMs), passing --max-age-ms when
supplied and omitting it so the ledger's own DEFAULT_MAX_CLAIM_AGE_MS applies.
- --max-age-ms accepts only a finite integer >= 0; anything else returns usage.
- --dry-run prints what would be reclaimed and returns 0 without opening the ledger.
- --json prints { "reclaimed": [...] }; plain text prints one line per reclaimed
claim plus a count, or `none`. Exit 0 either way -- reclaiming nothing is not a
failure.
- Registered in runClaimCli's dispatch and printHelp alongside claim/release/list.
Tests cover every new branch: max-age supplied/omitted, valid/invalid, dry-run
on/off (asserting the ledger is never opened via an injected opener), json on/off,
reclaimed-empty/nonempty, and dispatcher reachability.
Closes JSONbored#9686
|
🚨 Contributor flagged. Click here for more info: Superagent Dashboard |
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-29 04:41:50 UTC
Review summary Nits — 4 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed 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. Decision record
🟩 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.
|
|
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 #9717 +/- ##
===========================================
- Coverage 90.24% 76.60% -13.64%
===========================================
Files 900 284 -616
Lines 112914 59609 -53305
Branches 26776 8534 -18242
===========================================
- Hits 101896 45665 -56231
- Misses 9687 13661 +3974
+ Partials 1331 283 -1048
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Held for manual review: the gate and required CI are green, but GitHub reports this pull request's mergeable state as |
What & why
Closes #9686.
ClaimLedger.reclaimExpiredClaims(maxAgeMs?)exists to expire claims orphaned by a crashed/killedattempt, but had no production caller — unlike its named model
reclaimStuckItems, which bothruns automatically inside
claimNextBatchand has an operator escape hatch (loopover-miner queue release). A claim strandedactiveby aSIGKILLed attempt therefore counts against that repo'smaxConcurrentClaimscap for up to the 14-dayDEFAULT_MAX_CLAIM_AGE_MSwindow, with no command anoperator can run to clear it.
Change
Add
loopover-miner claim reclaim [--max-age-ms <n>] [--dry-run] [--json], mirroringrunQueueRelease(
portfolio-queue-cli.ts) exactly — sameparse → dry-run short-circuit → withClaimLedger → reportCliFailure(describeCliError(error))structure:ClaimLedger.reclaimExpiredClaims(maxAgeMs), passing--max-age-mswhen supplied and omittingit so the ledger's own
DEFAULT_MAX_CLAIM_AGE_MSdefault applies.--max-age-msaccepts only a finite integer>= 0; anything else returns the subcommand usagestring via
reportCliFailure.--dry-runprints what would be reclaimed and returns0without opening the claim ledger.--jsonprints{ "reclaimed": [...] }; plain text prints one line per reclaimed claim plus acount, or
none. Exit0either way — reclaiming nothing is not a failure.runClaimCli's dispatch and inprintHelpalongsideclaim/release/list.Validation
--max-age-mssupplied/omitted, valid/invalid(fractional/negative/non-numeric/missing),
--dry-runon/off (asserting the ledger is neveropened via an injected opener spy),
--jsonon/off, reclaimed-empty/nonempty, an explicit smallerwindow reclaiming a claim inside the default window, the ledger-error path, and dispatcher
reachability of
runClaimCli("reclaim", …).claim-ledger-cli.tsandcli.ts.