Skip to content

[Bug] Issue Discovery Credits Issues Solved by PRs Merged Into Non-Scoring Branches #130

@Helios531

Description

@Helios531

Summary

The mirror issue API returns an inline solving_pr for any merged PR that closed an issue, but it neither filters nor exposes the solving PR’s base_ref / default_branch.

This breaks parity with the OSS PR scoring path, where merged PRs are rejected if they target a non-acceptable branch. In gittensor, issue discovery only checks that solving_pr.state == "MERGED" and then scores it, so an issue can receive discovery credit even when the solving PR would be rejected from PR scoring because it merged into a non-scoring branch.

Reproduction Steps

  1. Run the DAS locally with local Postgres/Redis and a dummy GitHub App key:
  2. Seed a repo, a closed issue, and a solving PR merged into a non-scoring branch:
  3. Query the mirror issue endpoint:
curl -sS \
  'http://127.0.0.1:6970/api/v1/miners/111/issues?since=2026-05-01T00:00:00Z'
  1. Validate the same shape in gittensor:
  2. Compare with normal PR scoring branch eligibility:

Actual Result

The mirror returns a solving_pr for the non-scoring-branch PR:

{
  "issue_number": 9,
  "state": "CLOSED",
  "state_reason": "COMPLETED",
  "solved_by_pr": 7,
  "solving_pr": {
    "pr_number": 7,
    "author_github_id": "222",
    "state": "MERGED",
    "merged_at": "2026-05-20T01:00:00+00:00",
    "edited_after_merge": false,
    "head_sha": "1111111111111111111111111111111111111111",
    "base_sha": "2222222222222222222222222222222222222222",
    "merge_base_sha": "3333333333333333333333333333333333333333"
  }
}

gittensor classifies and adapts it as scoreable:

classification: solved
adapted: True
discovery_base_score: 42.0

But the same PR is rejected by normal OSS PR scoring:

oss_pr_skip: True
reason: PR #7 merged to 'scratch-do-not-score' not in acceptable branches=['main']

Expected Result

Issue discovery should not award solved-issue credit for a PR that would fail the same merged-PR branch eligibility gate used by OSS contribution scoring.

Evidence

Local project execution:

Nest application successfully started
Bootstrap listening on port 6970
/api/v1/health returned 200 with db.ok=true and redis.ok=true

Root Cause

packages/das/src/api/miners/miners.service.ts builds inline solving_pr with only minimal fields. It does not include base_ref, head_ref, head_repo_full_name, or default_branch, and it does not filter by branch eligibility in SQL.

Relevant local files:
[miners.service.ts] (https://github.com/entrius/das-github-mirror/packages/das/src/api/miners/miners.service.ts):115

[gittensor issue discovery] (https://github.com/entrius/gittensor/gittensor/validator/issue_discovery/scan.py):692

[gittensor PR branch gate] (https://github.com/entrius/gittensor/gittensor/validator/oss_contributions/mirror/scoring.py):236

Security/Business Impact

This is a reward-integrity bug. A miner can receive issue-discovery credit for issues closed by PRs merged into branches that are explicitly not accepted for normal contribution scoring. That creates an inconsistent scoring policy and a practical bypass of repository branch restrictions.

Suggested Fix

Add solving PR branch eligibility to the issue-discovery path.

Recommended DAS-side fix:

  • Include base_ref, head_ref, head_repo_full_name, and default_branch in inline solving_pr.
  • Or filter solving_pr server-side so only PRs merged into acceptable branches are returned.
  • Keep the validation rule aligned with _should_skip_merged_mirror_pr.

Recommended gittensor-side defense-in-depth:

  • Extend MirrorSolvingPR with branch fields.
  • Apply the same base/head branch gate before _classify_issue returns solved or before _mirror_issue_for_scoring adapts the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions