Skip to content

[BUG] Mirror issue discovery: MERGED solving PR with null merged_at inflates eligibility counters #919

Description

@statxc

Description

In _classify_issue (gittensor/validator/issue_discovery/mirror_scan.py), a solving PR reported with state == 'MERGED' but merged_at is None is not gated. The record reaches _mirror_issue_for_scoring, which correctly drops it as unscoreable — but only after total_solved_issues and total_valid_solved_issues have already been incremented.

A single corrupted record can therefore push a miner from valid_solved_count == MIN_VALID_SOLVED_ISSUES - 1 (ineligible) to MIN_VALID_SOLVED_ISSUES (eligible), flipping is_issue_eligible and producing a non-zero issue_discovery_score from the other valid records that would otherwise be discarded.

The OSS mirror scoring path already rejects this exact shape with a "MERGED but missing merged_at" guard; the issue-discovery path was missing the equivalent gate.

Steps to Reproduce

  1. Set up a miner with exactly MIN_VALID_SOLVED_ISSUES - 1 clean solved mirror issues (one short of the eligibility floor).
  2. Add one mirror issue whose solving_pr.state == 'MERGED' and solving_pr.merged_at is None.
  3. Run run_mirror_issue_discovery against this miner.

Expected Behavior

The corrupted record is bucketed as not-solved-closed. total_valid_solved_issues stays at MIN_VALID_SOLVED_ISSUES - 1, is_issue_eligible is False, and issue_discovery_score is 0.

Actual Behavior

_classify_issue returns 'solved'. total_solved_issues and total_valid_solved_issues are incremented to MIN_VALID_SOLVED_ISSUES. _mirror_issue_for_scoring then drops the corrupted record, but the eligibility flag has already flipped to True, and the miner receives a non-zero issue_discovery_score derived from the other valid records.

Environment

  • OS: Linux (Ubuntu 24.04)
  • Python version: 3.11
  • Commit/Version: test branch HEAD (pre-fix)

Additional Context

  • Affected file: gittensor/validator/issue_discovery/mirror_scan.py_classify_issue.
  • Reference for the equivalent OSS-side gate: gittensor/validator/oss_contributions/mirror/scoring.py ("MERGED but missing merged_at" rejection).
  • Fix: add a sp.merged_at is None → 'not-solved-closed' branch in _classify_issue after the state != 'MERGED' check, so the gate fires before the counters increment. See PR fix: gate MERGED solving PRs missing merged_at in mirror issue discovery #920.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions