Skip to content

feat(mcp): gittensory_validate_linked_issue - #622

Merged
JSONbored merged 3 commits into
JSONbored:mainfrom
oktofeesh1:feat/issue-546-validate-linked-issue
Jun 12, 2026
Merged

feat(mcp): gittensory_validate_linked_issue#622
JSONbored merged 3 commits into
JSONbored:mainfrom
oktofeesh1:feat/issue-546-validate-linked-issue

Conversation

@oktofeesh1

Copy link
Copy Markdown
Contributor

Fixes #546

What

Adds gittensory_validate_linked_issue, an MCP tool that reports — before opening a PR — whether linking a given issue will actually earn the standard linked-issue scoring multiplier. It answers: is the issue open, valid, single-owner (uncontested), and solvable by the planned PR? When the multiplier won't apply, it returns the precise blocking reason. Metadata only; no GitHub writes.

This stops miners from chasing the linked-issue multiplier blind on targets that won't qualify (closed, duplicate/invalid, already solved, or contested by another open PR).

How

  • src/scoring/preview.ts — exports projectLinkedIssueMultiplierForPlannedSolve, which reuses decideLinkedIssueMultiplier (the exact eligibility rule buildScorePreview uses) for the projected "this PR becomes the merged solver" scenario, so the validator stays consistent with the scoring engine.
  • src/signals/engine.ts — new buildLinkedIssueValidation builder composing buildIssueDiscoveryLifecycleReport (lifecycle/solvability truth) with the projected multiplier decision. It flags closed, duplicate/invalid, already-solved, and contested-by-another-contributor's-PR targets, and excludes the contributor's own open PR from the contention check.
  • Public-safe — reasons/blockers routed through sanitizePublicComment (fail-closed). The output surfaces only multiplierWouldApply + the canonical multiplierStatus; the raw numeric multiplier value stays private.
  • src/mcp/server.ts — registers the tool with an inputSchema and outputSchema.
  • src/api/routes.tsPOST /v1/repos/:owner/:repo/validate-linked-issue backing the local CLI tool.
  • packages/gittensory-mcp/bin/gittensory-mcp.js — exposes the tool, proxying to the API route.

Output boundaries

Public-safe; metadata only, no writes. Returns applies / does-not-apply + the canonical status and a blocking reason — never the raw multiplier value or other contributors' private context.

Tests

  • test/unit/linked-issue-validation.test.ts — would-apply, closed, duplicate/invalid, solved (merged), self-solved loop, contested (other open PR), own-PR-ignored, not-found, plus forbidden-term assertions on all output.
  • test/unit/mcp-output-schemas.test.ts — output-schema discovery + structured-content calls for both would-apply and uncached cases.
  • test/integration/api.test.ts — route success, invalid body (400), session-forbidden (403).

npm run validate (typecheck + coverage) is green at the 97%+ branch threshold; build:mcp, test:mcp-pack, test:workers, and ui:openapi:check also pass.

🤖 Generated with Claude Code

…alidator

Adds an MCP tool that reports, before opening a PR, whether linking a given issue
will actually earn the standard linked-issue scoring multiplier — is it open,
valid, single-owner (uncontested), and solvable by the planned PR — with the
precise blocking reason when it will not. Metadata only; no GitHub writes.

- scoring/preview: export projectLinkedIssueMultiplierForPlannedSolve, reusing the
  existing decideLinkedIssueMultiplier eligibility rule (the same logic buildScorePreview
  uses) for the projected "this PR solves the issue" scenario.
- engine: new buildLinkedIssueValidation builder composing buildIssueDiscoveryLifecycleReport
  (lifecycle/solvability) with the projected multiplier decision; detects closed,
  duplicate/invalid, already-solved, and contested-by-another-PR targets. Public-safe via
  sanitizePublicComment; surfaces only applies/does-not-apply + canonical status, never the
  raw multiplier value.
- mcp(worker): register gittensory_validate_linked_issue with input + output schema.
- api: POST /v1/repos/:owner/:repo/validate-linked-issue backing the local bin tool.
- mcp(local bin): proxy the new tool to the API route.
- tests: builder unit coverage (apply, closed, duplicate/invalid, solved, self-solved loop,
  contested, own-PR-ignored, not-found, public-safe), MCP structured-content (apply + uncached),
  and API route success/invalid/forbidden. npm run validate green at 97%+ branch coverage.

Fixes JSONbored#546

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ghost

ghost commented Jun 12, 2026

Copy link
Copy Markdown

Note

Gittensory Gate skipped

PR closed before full evaluation. No late first comment was created.

Signal Result Evidence Action
Gate result ⚠️ Skipped #622 is no longer open. No action.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

@ghost ghost added the gittensory:reviewed label Jun 12, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

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

@ghost

ghost commented Jun 12, 2026

Copy link
Copy Markdown

gittensory · advisory review

Reviewed 8 changed file(s) — two independent AI reviewers.

Suggested action:Safe to merge — both reviewers found no blocking issues.

What changed

  • packages/gittensory-mcp/bin/gittensory-mcp.js: adds input schema and registers the new tool.
  • src/api/routes.ts: adds route /validate-linked-issue with request validation and response building.
  • src/mcp/server.ts: registers the tool with input and output schemas and implements the handler.
  • src/scoring/preview.ts: adds helper projectLinkedIssueMultiplierForPlannedSolve.
  • src/signals/engine.ts: implements buildLinkedIssueValidation using sanitization and scoring logic.
  • Tests: integration test for API route, unit tests for validation logic, and MCP output‑schema test.

Reviewer A · gpt-oss-120b — recommends ✅ merge
This PR introduces a new "gittensory_validate_linked_issue" tool across the API, MCP server, scoring preview, and signals engine, adding validation for linked‑issue multiplier eligibility and accompanying tests. The implementation appears thorough, respects public‑private sanitization, and integrates with existing schemas.

Suggestions

  • Align the input shape in packages/gittensory-mcp/bin/gittensory-mcp.js with the one in src/mcp/server.ts by adding the same max length constraints for title and changedFiles to keep validation consistent.
  • Consider adding a unit test for the CLI registration to ensure the tool can be invoked via the binary with the expected schema.

Worth double-checking

  • Make sure the report field returned by the API does not unintentionally expose private scoring data; current sanitization appears sufficient but double‑check future extensions.
  • Confirm that the new input shape is kept in sync across the binary and server to avoid mismatched validation errors.

Reviewer B · nemotron-3-120b-a12b — recommends ✅ merge
This PR adds a new MCP tool and API endpoint for validating whether linking an issue will earn the standard linked-issue scoring multiplier. The implementation is thorough, reuses existing scoring logic, maintains the public/private boundary via sanitization, includes proper authentication/authorization, and is well-tested with unit and integration tests. The code follows project conventions and is ready for merge.

Suggestions

  • Consider adding a test case for when plannedChange.contributorLogin is provided but doesn't match the session login (to ensure it's treated as external contention)
  • In the MCP tool handler, the report field is typed as Record<string, unknown> but could be more precisely typed as LinkedIssueValidationReport for better type safety
  • The bin/gittensory-mcp.js tool definition could use the same PREFLIGHT_LIMITS as the MCP/server.ts version for consistency, though not strictly necessary since validation occurs server-side

Worth double-checking

  • Ensure the new endpoint doesn't inadvertently expose private scoring metrics - but sanitization appears correct
  • Verify that the PROJECTED_SOLVED_BY_PULL_REQUEST_VALIDATION constant is properly imported/scoped in preview.ts (not shown in diff but assumed correct)
  • Confirm that the stale warning threshold aligns with existing issue staleness logic elsewhere in the codebase

@ghost ghost added the gittensory-review label Jun 12, 2026
@JSONbored JSONbored added gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier. gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. labels Jun 12, 2026
@dosubot dosubot Bot added the lgtm label Jun 12, 2026
@JSONbored
JSONbored merged commit 2b40a48 into JSONbored:main Jun 12, 2026
9 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in gittensory - v1 roadmap Jun 12, 2026
@github-actions github-actions Bot mentioned this pull request Jun 12, 2026
12 tasks
@JSONbored JSONbored removed the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier.

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

feat(mcp): gittensory_validate_linked_issue

2 participants