feat(mcp): wire gittensory_feasibility_gate's claimStatus to the local claim ledger (#5157)#5361
Conversation
…l claim ledger (JSONbored#5157) gittensory_feasibility_gate took claimStatus as a purely caller-supplied string, never actually connected to real local claim state, even though packages/gittensory-miner/lib/claim-ledger.js already tracks it. Adds optional repoFullName/issueNumber inputs. When both are supplied and a local gittensory-miner install's claim ledger DB file exists, claimStatus is now read from that ledger (an active claim on the exact issue -> "claimed", otherwise "unclaimed") instead of trusting the caller-supplied value. The DB file's existence is checked BEFORE opening anything, so this advisory-only tool never creates the ledger as a side effect -- it stays strictly read-only, never calls recordClaim/releaseClaim/expireClaim, and never gains any ability to block, cancel, or override a claim or attempt; real claim-conflict authority remains entirely with the maintainer-only path. Falls back to today's caller-supplied-string behavior unchanged when repo/issue are omitted, the ledger file doesn't exist, or gittensory-miner isn't resolvable at all. The feasibility calculator's own decision logic is untouched -- this only changes where claimStatus is sourced from.
|
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 #5361 +/- ##
==========================================
- Coverage 94.40% 94.36% -0.04%
==========================================
Files 550 550
Lines 44119 44119
Branches 14632 14632
==========================================
- Hits 41652 41635 -17
- Misses 1792 1809 +17
Partials 675 675
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-12 15:09:23 UTC
✅ Suggested Action - Approve/Merge
Review summary Blockers
Nits — 5 non-blocking
Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory 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://gittensory.aethereal.dev/docs/gittensory-commands 🟩 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.
|
|
An AI reviewer flagged a likely defect, but its confidence was below this repository's configured close-confidence floor, so this is held for a maintainer to confirm instead of closing automatically. Resolve the flagged defect (see the review notes), or ask a maintainer to override. |
JSONbored
left a comment
There was a problem hiding this comment.
Fix + resubmit:
packages/gittensory-mcp/bin/gittensory-mcp.js:217 catches every error from resolving/opening/querying the ledger and returns null, so a real local ledger that is corrupt, locked, or otherwise unreadable falls back to a caller-supplied "unclaimed" value and can emit a "go" verdict despite the ledger-backed source being unavailable; narrow the catch to the module-not-found/no-local-miner case or return a conservative claimed/raise result for existing-ledger read failures.
Summary
gittensory_feasibility_gateinpackages/gittensory-mcp/bin/gittensory-mcp.jstookclaimStatusas a purely caller-supplied string -- the pure feasibility calculator was never actually connected to real local claim state, even thoughpackages/gittensory-miner/lib/claim-ledger.jsalready tracks it.repoFullName/issueNumberinputs tofeasibilityGateShape. When both are supplied AND a localgittensory-minerinstall's claim ledger DB file exists,claimStatusis now read from that ledger (an active claim on the exact issue ->"claimed", otherwise"unclaimed") instead of trusting the caller-supplied value.existsSyncbefore opening anything, so this advisory-only tool never creates the ledger as a side effect. It never callsrecordClaim/releaseClaim/expireClaim, and never gains any ability to block, cancel, or override a claim or attempt -- real claim-conflict resolution authority stays entirely with the maintainer-only path (Wire claim-conflict resolution end-to-end #4848), unaffected.repoFullName/issueNumberomitted, the ledger DB file doesn't exist (no local install detected), or@jsonbored/gittensory-minerisn't resolvable at all (a standalonegittensory-mcpinstall with no miner alongside it).buildFeasibilityVerdict) is completely untouched -- this diff only changes whereclaimStatusis sourced from.Test plan
npx vitest run test/unit/mcp-feasibility-gate.test.ts-- 12/12 passing (6 pre-existing + 6 new), spawning the real MCP server subprocess via stdio (matching this file's existing E2E convention) and pointingGITTENSORY_MINER_CLAIM_LEDGER_DBat fixture SQLite files built withopenClaimLedger/claimIssuefrom the miner package directly. New coverage: (1) a regression test -- a caller-suppliedclaimStatus: "unclaimed"that contradicts a real active ledger claim is overridden to the ledger-backed"raise"/claim_status_claimedverdict, (2) ledger-sourced"unclaimed"overriding a contradicting caller-supplied"solved"when the ledger has no active claim on that issue, (3) fallback to the caller-supplied value unchanged when the ledger DB file doesn't exist, (4) fallback unchanged whenrepoFullName/issueNumberare omitted, (5) an invariant asserting the tool never writes to the ledger and its output shape stays exactly{verdict, avoidReasons, raiseReasons, summary}(no new blocking capability), and (6) the updated tool description.npm run typecheck-- clean.npm run build:mcp-- clean (node --checkpasses).npm run docs:drift-check-- clean.gh[pousr]_/github_pat_/sk-/gts_/AKIA/private-key/TOKEN=/SECRET=patterns -- zero matches (this repo's issue is entirely unrelated to credentials, but I double-checked given a recent false-positive elsewhere).packages/gittensory-mcp/**currently sits outside vitest'scoverage.includeglob, socodecov/patchcannot measure this change yet -- treating the tests above as the enforced house standard regardless. The outercatchbranch for "gittensory-miner genuinely unresolvable" is marked/* v8 ignore */since it isn't reproducible in this monorepo's workspace-hoisted test environment (the sibling package always resolves here).npm run test:coveragelocally (shared/resource-contended machine); relying on the targeted test run above plusnpm run typecheck/build:mcp.Fixes #5157.