feat(miner-discovery-plane): add the client-side soft-claim coordination request builder - #4443
Conversation
…ion request builder The local soft-claim ledger (claim-ledger.js) is 100% client-side — it "never uploads, syncs, or phones home" — and duplicate-cluster adjudication (isDuplicateClusterWinnerByClaim, JSONbored#3355) only resolves collisions AFTER the fact, by observing which PR/comment publicly landed first. This closes that gap on the client side: a pure function that turns a local claim record into the request payload a miner would send to the optional hosted discovery-index (the contract in discovery-index-contract.ts, JSONbored#4300) to softly announce/reserve an issue across the fleet BEFORE starting, so collisions are reduced rather than only detected afterward. Scoped as a request builder, not a network client — pure input→output, no HTTP (wiring the hosted plane's client into the miner runtime is downstream of JSONbored#4250 existing). It shares the discovery-index contract's posture: metadata-only and public-safe by construction — the request is built by explicitly copying a fixed set of known fields, never by spreading the input, so no forbidden field can ride along. - packages/gittensory-engine/src/discovery-soft-claim.ts: buildSoftClaimRequest maps a claim-ledger record (repoFullName, issueNumber, claimedAt, status, note) onto a SoftClaimRequest; softClaimActionForStatus maps status→action. All three claim-ledger statuses are handled explicitly: `active` produces a `claim` request; `released`/`expired` produce an explicit `release` variant (so the fleet learns an issue is free again) rather than being rejected. An invalid claim or unknown status returns null. - packages/gittensory-engine/src/index.ts: barrel re-export. - test/unit/discovery-soft-claim.test.ts: full coverage. Closes JSONbored#4302
|
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 #4443 +/- ##
=======================================
Coverage 93.96% 93.97%
=======================================
Files 413 414 +1
Lines 37296 37314 +18
Branches 13625 13636 +11
=======================================
+ Hits 35047 35065 +18
Misses 1594 1594
Partials 655 655
🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-09 19:01:26 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 5 non-blocking
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🟩 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 Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Closes #4302
What
The local soft-claim ledger (
claim-ledger.js) is 100% client-side — it "never uploads, syncs, or phones home" — and the duplicate-cluster adjudication it references (isDuplicateClusterWinnerByClaim, #3355) only resolves collisions after the fact, by observing which PR/comment publicly landed first. This adds the client-side piece that closes that gap: a pure function that turns a local claim record into the request payload a miner would send to the optional hosted discovery-index (the contract from #4300, now merged) to softly announce/reserve an issue across the fleet before starting — reducing collisions rather than only detecting them afterward.Scoped as a request builder, not a network client: pure input→output, no HTTP (wiring the hosted plane's client into the miner runtime is downstream of #4250 actually existing). It shares the discovery-index contract's posture — metadata-only and public-safe by construction: the request is built by explicitly copying a fixed set of known fields, never by spreading the input, so no forbidden field can ride along.
API (
packages/gittensory-engine/src/discovery-soft-claim.ts)buildSoftClaimRequest(claim, context?) => SoftClaimRequest | null— maps a claim-ledger record (repoFullName,issueNumber,claimedAt,status,note) onto aSoftClaimRequest, stamped withDISCOVERY_INDEX_CONTRACT_VERSION. Returnsnullfor a missing/invalid claim or an unknown status.softClaimActionForStatus(status) => "claim" | "release".Design decision (the issue's open question — reject vs. release for non-active claims): all three
CLAIM_STATUSESare handled explicitly — anactiveclaim produces aclaimrequest;released/expiredproduce an explicitreleasevariant (so the fleet learns an issue is free again) rather than being silently rejected.context.instanceIdis an opaque, caller-anonymized handle (not a wallet/hotkey) copied through verbatim; the local ledgeridis deliberately not leaked into the outbound request.Files
packages/gittensory-engine/src/discovery-soft-claim.ts— the builder.packages/gittensory-engine/src/index.ts— barrel re-export.test/unit/discovery-soft-claim.test.ts— tests.Testing
9/9 tests pass; typecheck clean. New engine file at 100% line + branch coverage (17/17, 39/39, 4/4).