Skip to content

feat(miner-plan): add soft-claim adjudication using the duplicate-winner election (#4291) - #4426

Merged
JSONbored merged 1 commit into
JSONbored:mainfrom
nickmopen:feat/miner-claim-adjudication
Jul 9, 2026
Merged

feat(miner-plan): add soft-claim adjudication using the duplicate-winner election (#4291)#4426
JSONbored merged 1 commit into
JSONbored:mainfrom
nickmopen:feat/miner-claim-adjudication

Conversation

@nickmopen

Copy link
Copy Markdown
Contributor

Closes #4291.

Decides which of several miners claiming the same issue proceeds — by reusing the maintainer-side election (isDuplicateClusterWinnerByClaim from @jsonbored/gittensory-engine) rather than reimplementing it, so the miner and the gate agree on exactly one winner by construction. The engine module's own header earmarks this as its intended "second consumer," and the claim-ledger's comment defers exactly this adjudication to here.

What's here

  • lib/claim-adjudication.js — pure adjudicateSoftClaim(self, competing). competing is the publicly-observable set of other open PRs linking the issue (the local ledger is client-side and can't see other miners). Returns:
    • isWinner — the go/no-go, driven only by isDuplicateClusterWinnerByClaim
    • winnerNumberdisplay-only (resolveDuplicateClusterWinnerNumber), for surfacing "you lost this claim to PR #N"
    • explicit toClaimMember bridge mapping the observed claimedAt → the engine's linkedIssueClaimedAt (the field names deliberately differ — not interchangeable by accident).
    • Fail-closed: a missing/sparse claim time loses and yields no guessed winner.
    • .d.ts + the build node --check entry.
  • Tests — this miner wins / loses (winner surfaced) / no competing (trivial winner) / fail-closed sparse-timestamp cases / the field mapping.

Scope

The pure adjudication seam. Wiring it into the claim CLI (contested-claim warnings on claim list/claim claim) is the sibling claim-ledger-commands issue, per this issue's own framing.

Validation

Typecheck clean; node --check passes; full suite (npm run test):

Test Files  630 passed | 2 skipped (632)
     Tests  12527 passed | 12 skipped   (0 failed)

…ner election (JSONbored#4291)

Decides which of several miners claiming the same issue proceeds by REUSING the
maintainer-side election (isDuplicateClusterWinnerByClaim from @jsonbored/gittensory-
engine) rather than reimplementing it — so the miner and the gate agree on exactly one
winner by construction (the engine module's own header earmarks this as its second
consumer).

- lib/claim-adjudication.js: pure adjudicateSoftClaim(self, competing) — competing is the
  publicly-observable set of OTHER open PRs linking the issue (the local ledger can't see
  other miners). Returns the go/no-go isWinner (driven only by isDuplicateClusterWinner-
  ByClaim) + a DISPLAY-only winnerNumber (resolveDuplicateClusterWinnerNumber). Explicit
  toClaimMember bridge maps the observed `claimedAt` → the engine's `linkedIssueClaimedAt`
  (the field names deliberately differ). Fail-closed: a sparse claim time loses and yields
  no guessed winner. + a .d.ts and the build node --check entry.
- Tests: this miner wins / loses (winner surfaced) / no competing (trivial winner) /
  fail-closed sparse-timestamp cases / the field mapping.

Scope: the pure adjudication seam. Wiring it into the claim CLI (contested-claim warnings)
is the sibling claim-ledger-commands issue, per this issue's own framing.

Verified: typecheck clean; full suite green (12527 passed, 0 failed).
@nickmopen
nickmopen requested a review from JSONbored as a code owner July 9, 2026 14:49
@superagent-security

Copy link
Copy Markdown
Contributor

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

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.98%. Comparing base (7967e78) to head (614892e).
⚠️ Report is 34 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4426   +/-   ##
=======================================
  Coverage   93.98%   93.98%           
=======================================
  Files         406      406           
  Lines       37028    37028           
  Branches    13538    13538           
=======================================
  Hits        34801    34801           
  Misses       1570     1570           
  Partials      657      657           
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JSONbored JSONbored added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 9, 2026
@JSONbored
JSONbored merged commit 7708d60 into JSONbored:main Jul 9, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Development

Successfully merging this pull request may close these issues.

feat(miner-plan): adjudicate competing soft-claims via the existing duplicate-winner election

2 participants