feat(miner-plan): add soft-claim adjudication using the duplicate-winner election (#4291) - #4426
Merged
Conversation
…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).
Contributor
|
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 #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:
|
JSONbored
approved these changes
Jul 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #4291.
Decides which of several miners claiming the same issue proceeds — by reusing the maintainer-side election (
isDuplicateClusterWinnerByClaimfrom@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— pureadjudicateSoftClaim(self, competing).competingis 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 byisDuplicateClusterWinnerByClaimwinnerNumber— display-only (resolveDuplicateClusterWinnerNumber), for surfacing "you lost this claim to PR #N"toClaimMemberbridge mapping the observedclaimedAt→ the engine'slinkedIssueClaimedAt(the field names deliberately differ — not interchangeable by accident)..d.ts+ thebuildnode --checkentry.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 --checkpasses; full suite (npm run test):