Skip to content

feat(signals): wire issue quality reports through snapshot + REST + MCP + opportunities - #56

Merged
JSONbored merged 13 commits into
JSONbored:mainfrom
mkdev5:feat/issue-quality-wiring
May 29, 2026
Merged

feat(signals): wire issue quality reports through snapshot + REST + MCP + opportunities#56
JSONbored merged 13 commits into
JSONbored:mainfrom
mkdev5:feat/issue-quality-wiring

Conversation

@mkdev5

@mkdev5 mkdev5 commented May 29, 2026

Copy link
Copy Markdown
Contributor

Closes #20.

Summary

  • generateSignalSnapshots now builds and persists an issue-quality snapshot alongside the other six signal types (queue/processors.ts).
  • New GET /v1/repos/:owner/:repo/issue-quality returns the cached snapshot when present and computes one on demand when the repo is known but uncached; 404 only when the repo itself is unknown (api/routes.ts). Path registered in OpenAPI.
  • New MCP tool gittensory_get_issue_quality exposes the same data privately (mcp/server.ts); falls back to a not_found payload when the repo is unknown so clients render cleanly.
  • buildContributorOpportunities now accepts an optional Map<repoFullName, IssueQualityReport> and applies issue-quality status to opportunity ranking: do_not_use drops the issue, needs_proof downgrades it to caution (even when lane fit is strong), hold adds a warning and reduces score, ready boosts. Lookup is case-insensitive; falls through to existing behavior when the map is empty (signals/engine.ts).

Acceptance criteria → coverage

  • AC1 "MCP can explain why an issue is or is not worth pursuing" — new tool returns the report with reasons[] and warnings[] per issue. Integration test seeds a snapshot and exercises the tool.
  • AC2 "Direct-PR-only repos do not encourage noisy issue filing" — builder emits a direct-PR first warning that surfaces as needs_proof status; fixture asserts the warning content.
  • AC3 "Issue-discovery repos can surface good candidate issues" — fixture confirms ready status without lane warnings; opportunity-integration test asserts the Issue quality report rates this issue as ready. reason surfaces.
  • AC4 "Duplicate/WIP risk affects opportunity ranking"do_not_use (linked-PR) fixture confirms the issue is dropped from opportunities. Duplicate-prone fixture asserts the collision warning.
  • AC5 "Large repos stay within Worker budget" — fixture asserts the report caps at 100 issues per repo. Snapshot generator only reads existing cached metadata (no new fetches).

Validation

  • npm run typecheck — pass
  • npm run test:coverage — 359 tests pass; branches at 95.11% over the 95% gate
  • npm run test:workers — workers suite green

Safety

  • Backend-only change
  • No secrets, wallet details, user PATs, raw trust scores, or private rankings exposed
  • Public text avoids compensation-seeking or optimization-tactic language
  • OpenAPI/MCP behavior updated where needed (additive new path + tool)
  • Public docs/changelogs updated where needed

Open questions for review

  • Storage shape: I'm persisting issue-quality reports as signal_snapshots rows (matching the pattern every other signal uses) rather than going through the dedicated issue_quality_reports table. The dedicated table + upsertIssueQualityReport are now effectively unused — happy to remove them in this PR or leave for a separate cleanup. Lean toward leaving for cleanup so this PR stays focused.
  • Taxonomy: kept the existing 4-status enum (ready | needs_proof | hold | do_not_use). The issue body sketched a 7-class taxonomy (actionable | too broad | stale | duplicate-prone | already solved | needs maintainer context | good candidate) — those distinctions exist today in the warnings[] strings. Open to promoting them to first-class statuses in a follow-up if you'd rather them be enum members.
  • Preflight + agent-orchestrator integration: deliberately deferred. Opportunities is the primary consumer the issue called out; preflight/local-branch wiring is a clean follow-up scope.

Relationship to other in-flight work

mkdev11 added 3 commits May 29, 2026 10:07
generateSignalSnapshots now builds and persists an issue-quality
snapshot alongside the other six signal types. New
GET /v1/repos/:owner/:repo/issue-quality returns the cached snapshot
or computes one on demand when the repo is known; 404 when the repo
is unknown.

The path is registered in the OpenAPI spec.
Returns the cached or freshly-computed issue-quality report for a
repo. Falls back to a not_found payload when the repo is unknown
locally so MCP clients can render the state without erroring.
buildContributorOpportunities now accepts an optional
Map<repoFullName, IssueQualityReport> and uses each issue's quality
status to drop do_not_use issues, downgrade needs_proof to caution
even at high lane fit, and boost ready issues. Lookup is
case-insensitive.

Adds fixtures for direct-PR / issue-discovery / vague / stale /
already-solved / duplicate-prone / high-volume issue paths plus
opportunity-integration tests for the do_not_use drop, needs_proof
downgrade, and hold-status warnings. Integration test flips the
formerly-legacy /v1/repos/:owner/:repo/issue-quality 404 path to
assert both snapshot and computed responses and seeds an issue-quality
snapshot for the MCP tool happy path.
@mkdev5
mkdev5 requested a review from JSONbored as a code owner May 29, 2026 08:08
@dosubot dosubot Bot added the size:L label May 29, 2026
mkdev5 and others added 6 commits May 29, 2026 01:25
PR #56 should not regenerate CHANGELOG.md per CONTRIBUTING rules
(changelog edits are release-prep only).
buildContributorOpportunities accepted an issueQualityByRepo map but
buildContributorFit was still calling it without one, so production
opportunity ranking never saw quality status. Threads the map through
buildContributorFit and loads cached snapshots once per
build-contributor-evidence run so do_not_use issues drop from
contributor opportunities and needs_proof/hold downgrade correctly.

Also moves the do_not_use filter before slice(0, 5) so dropped issues
don't silently shrink the top-N output, and reuses the already-built
CollisionReport when persisting issue-quality snapshots in
generateSignalSnapshots to honor the Worker-budget acceptance.
Extracts the cache-or-compute load path into
services/issue-quality.ts so REST and MCP return the same envelope
shape with the same generatedAt fallback. Adds an enveloped
IssueQualityResponseSchema in OpenAPI so the documented contract
matches what the handler actually returns.
- Stale fixture now asserts status: needs_proof and exact warning.
- Issue-discovery fixture asserts score >= 70 and the reasons array.
- Duplicate-prone fixture asserts both issue numbers and the exact
  warning string.
- New end-to-end unit test routes a do_not_use issue through
  buildContributorFit and asserts it is dropped from opportunities.
- queue.test.ts now positively asserts an issue-quality snapshot
  is persisted after generate-signal-snapshots and that the payload
  has the expected shape.
@mkdev5

mkdev5 commented May 29, 2026

Copy link
Copy Markdown
Contributor Author

@JSONbored thanks for your merge. could you please review this PR?

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

#56 feat(signals): wire issue quality reports through snapshot + REST + MCP + opportunities
action: merge
required:

  • None obvious. It is snapshot-first, bounded on fallback, and has good unit/integration coverage.

@dosubot dosubot Bot added the lgtm label May 29, 2026
@JSONbored
JSONbored merged commit be39bef into JSONbored:main May 29, 2026
3 checks passed
jony376 pushed a commit to jony376/gittensory that referenced this pull request May 31, 2026
…CP + opportunities (JSONbored#56)

* feat(signals): persist issue-quality snapshots and serve them via REST

generateSignalSnapshots now builds and persists an issue-quality
snapshot alongside the other six signal types. New
GET /v1/repos/:owner/:repo/issue-quality returns the cached snapshot
or computes one on demand when the repo is known; 404 when the repo
is unknown.

The path is registered in the OpenAPI spec.

* feat(mcp): add gittensory_get_issue_quality tool

Returns the cached or freshly-computed issue-quality report for a
repo. Falls back to a not_found payload when the repo is unknown
locally so MCP clients can render the state without erroring.

* feat(signals): weight contributor opportunities by cached issue quality

buildContributorOpportunities now accepts an optional
Map<repoFullName, IssueQualityReport> and uses each issue's quality
status to drop do_not_use issues, downgrade needs_proof to caution
even at high lane fit, and boost ready issues. Lookup is
case-insensitive.

Adds fixtures for direct-PR / issue-discovery / vague / stale /
already-solved / duplicate-prone / high-volume issue paths plus
opportunity-integration tests for the do_not_use drop, needs_proof
downgrade, and hold-status warnings. Integration test flips the
formerly-legacy /v1/repos/:owner/:repo/issue-quality 404 path to
assert both snapshot and computed responses and seeds an issue-quality
snapshot for the MCP tool happy path.

* revert(changelog): restore main CHANGELOG.md

PR JSONbored#56 should not regenerate CHANGELOG.md per CONTRIBUTING rules
(changelog edits are release-prep only).

* fix(signals): thread issue-quality map through buildContributorFit

buildContributorOpportunities accepted an issueQualityByRepo map but
buildContributorFit was still calling it without one, so production
opportunity ranking never saw quality status. Threads the map through
buildContributorFit and loads cached snapshots once per
build-contributor-evidence run so do_not_use issues drop from
contributor opportunities and needs_proof/hold downgrade correctly.

Also moves the do_not_use filter before slice(0, 5) so dropped issues
don't silently shrink the top-N output, and reuses the already-built
CollisionReport when persisting issue-quality snapshots in
generateSignalSnapshots to honor the Worker-budget acceptance.

* refactor(signals): share REST + MCP issue-quality loader

Extracts the cache-or-compute load path into
services/issue-quality.ts so REST and MCP return the same envelope
shape with the same generatedAt fallback. Adds an enveloped
IssueQualityResponseSchema in OpenAPI so the documented contract
matches what the handler actually returns.

* test(signals): tighten issue-quality fixtures and assert wiring

- Stale fixture now asserts status: needs_proof and exact warning.
- Issue-discovery fixture asserts score >= 70 and the reasons array.
- Duplicate-prone fixture asserts both issue numbers and the exact
  warning string.
- New end-to-end unit test routes a do_not_use issue through
  buildContributorFit and asserts it is dropped from opportunities.
- queue.test.ts now positively asserts an issue-quality snapshot
  is persisted after generate-signal-snapshots and that the payload
  has the expected shape.

* fix: complete issue-quality wiring

---------

Co-authored-by: mkdev11 <MkDev11@users.noreply.github.com>
@JSONbored JSONbored added gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. and removed feature gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. labels Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(signals): implement issue quality reports for opportunity ranking

2 participants