Skip to content

feat(miner-discovery-plane): add the client-side soft-claim coordination request builder - #4443

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
jeffrey701:feat/discovery-soft-claim
Jul 9, 2026
Merged

feat(miner-discovery-plane): add the client-side soft-claim coordination request builder#4443
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
jeffrey701:feat/discovery-soft-claim

Conversation

@jeffrey701

Copy link
Copy Markdown
Contributor

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 a SoftClaimRequest, stamped with DISCOVERY_INDEX_CONTRACT_VERSION. Returns null for 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_STATUSES are handled explicitly — an active claim produces a claim request; released/expired produce an explicit release variant (so the fleet learns an issue is free again) rather than being silently rejected. context.instanceId is an opaque, caller-anonymized handle (not a wallet/hotkey) copied through verbatim; the local ledger id is 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

npx vitest run test/unit/discovery-soft-claim.test.ts
npm run typecheck

9/9 tests pass; typecheck clean. New engine file at 100% line + branch coverage (17/17, 39/39, 4/4).

…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
@jeffrey701
jeffrey701 requested a review from JSONbored as a code owner July 9, 2026 18: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.97%. Comparing base (a51dadb) to head (57763b9).
⚠️ Report is 1 commits behind head on main.

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           
Files with missing lines Coverage Δ
...ages/gittensory-engine/src/discovery-soft-claim.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 9, 2026
@loopover-orb

loopover-orb Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ Gittensory review result - approve/merge recommended

Review updated: 2026-07-09 19:01:26 UTC

3 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This adds a small, pure, well-scoped request builder (`buildSoftClaimRequest`/`softClaimActionForStatus`) that maps a local claim-ledger record onto a public-safe `SoftClaimRequest` payload for the hosted discovery-index contract, plus a barrel re-export and thorough unit tests. The logic is correct: it copies only a fixed set of known fields (never spreads), mirrors the existing `normalizeRepoFullName` validation from `claim-ledger.js`, and both branches of every ternary (`note`, `instanceId`, `action`) are exercised in tests. It closes #4302 as described, is intentionally unwired (no HTTP/network client), and CI is green with no schema or migration surface touched.

Nits — 5 non-blocking
  • discovery-soft-claim.ts: `buildSoftClaimRequest(claim, context: SoftClaimRequestContext = {})` only applies its default for `undefined` — an explicit `buildSoftClaimRequest(claim, null)` call will throw on `context.instanceId` since destructuring/property access on `null` isn't guarded; worth a `context ?? {}` normalization even though no caller passes `null` today.
  • discovery-soft-claim.test.ts: the note-normalization test covers `undefined`, blank string, and a non-string (`5`), but not an explicit `note: null` — logically identical to the non-string branch, so low risk, but worth adding for symmetry with the `instanceId` tests.
  • discovery-soft-claim.ts: `normalizeRepoFullName` duplicates the same owner/repo validation already implemented in `claim-ledger.js` and presumably `discovery-index-contract.ts` — understandable given the package-direction constraint (miner depends on engine, not vice versa), but a one-line comment noting why it can't be shared would help future readers.
  • Guard `context` against an explicit `null` argument in `buildSoftClaimRequest` (packages/gittensory-engine/src/discovery-soft-claim.ts) with `const ctx = context ?? {};` before reading `ctx.instanceId`.
  • Add a `note: null` case to the normalization test block in test/unit/discovery-soft-claim.test.ts for parity with the instanceId null-handling tests.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #4302
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 97 registered-repo PR(s), 40 merged, 4 issue(s).
Contributor context ✅ Confirmed Gittensor contributor jeffrey701; Gittensor profile; 97 PR(s), 4 issue(s).
Gate result ✅ Passing No configured blocker found.
Linked issue satisfaction

Addressed
The PR adds a pure buildSoftClaimRequest/softClaimActionForStatus in gittensory-engine that maps the claim-ledger's repoFullName/issueNumber/claimedAt/status/note fields onto a discovery-index request, explicitly handles all three CLAIM_STATUSES (active→claim, released/expired→release) with no network call, and includes unit tests under test/unit/ covering valid and invalid inputs.

Review context
  • Author: jeffrey701
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 97 PR(s), 4 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 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.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gittensory approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 58e08e9 into JSONbored:main Jul 9, 2026
10 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(miner-discovery-plane): add client-side soft-claim coordination request builder

1 participant