Skip to content

fix(issue-discovery): honor per-repo min_token_score in solving-PR cache#1356

Open
galuis116 wants to merge 1 commit into
entrius:testfrom
galuis116:fix/per-repo-min-token-score-cache
Open

fix(issue-discovery): honor per-repo min_token_score in solving-PR cache#1356
galuis116 wants to merge 1 commit into
entrius:testfrom
galuis116:fix/per-repo-min-token-score-cache

Conversation

@galuis116
Copy link
Copy Markdown

Summary

PR #1330 plumbed min_token_score_for_base_score through the OSS scoring path (mirror/scoring.py) and the issue-discovery solving-PR cache-MISS path (scan.py:676-680), but the solving-PR cache-population path at scan.py:409 kept reading the global MIN_TOKEN_SCORE_FOR_BASE_SCORE constant — silent state asymmetry between the cache and the path that fills its misses.

With a repo-level override set, OSS gives a merged PR with token_score = 3 a non-zero base_score (post-#1330), but _build_solving_pr_cache drops the entry because 3 < 5. Every sibling discoverer's lookup for that PR then cache-MISSes and refetches via MirrorClient.get_pr_files; on a MirrorRequestError or scoring_data_stored = False the per-repo accumulator sets fetch_failed = True, and the discoverer loses both valid_solved credit and discovery_earned_score for that issue — even though the data was already in memory on this validator round. No repo in master_repositories.json currently sets the override, so the bug is latent, but the moment an admin uses the field the cache and the cache-MISS path disagree about which PRs are scorable. Same forward-looking-consistency posture as #1330.

The docs are explicit on the contract: every eligibility constant "is a global default that any repository can override in its config entry" (docs.gittensor.io/oss-contributions.html §"Per-repo configs vary"), and the cross-miner cache is specified as a pure pass-through — "Miners' own PRs are pre-scored during OSS evaluation and reused for free" (docs.gittensor.io/issue-discovery.html §"Base Score Calculation"). The current cache filter breaks the "reused for free" promise whenever the override is in effect.

Closes #1355.

Fix

  • _build_solving_pr_cache now takes mirror_repos: Dict[str, RepositoryConfig] and resolves the per-PR threshold via resolve_eligibility(repo_config.eligibility).min_token_score_for_base_score, falling back to the global MIN_TOKEN_SCORE_FOR_BASE_SCORE when the repo isn't in mirror_repos (defensive — in practice every merged_prs entry is from a tracked repo).
  • The single call site in run_issue_discovery (scan.py:165) now passes mirror_repos.
  • Docstring updated to spell out the parity with the cache-MISS path and the OSS scoring path.

Test plan

  • New regression tests in tests/validator/issue_discovery/test_scan.py::TestSolvingPrCache:
    • test_per_repo_override_keeps_pr_above_repo_threshold — a repo with min_token_score_for_base_score = 2 keeps a PR whose token_score = 3 (clears override, fails global default).
    • test_untracked_repo_falls_back_to_global_threshold — defensive: a repo missing from mirror_repos still gates on the global default, doesn't crash.
  • Existing TestSolvingPrCache tests (test_build_cache_from_multiple_miners, test_cache_first_occurrence_wins_on_duplicate, test_below_threshold_prs_excluded_from_cache) updated to pass mirror_repos; behavior preserved when no override is configured.
  • uv run pytest tests/validator/issue_discovery/test_scan.py -q — 66 passed.
  • uv run pytest tests/validator/ -q — 519 passed.
  • uv run ruff check gittensor/validator/issue_discovery/scan.py tests/validator/issue_discovery/test_scan.py — clean.
  • uv run ruff format --check gittensor/validator/issue_discovery/scan.py tests/validator/issue_discovery/test_scan.py — clean.
  • uv run pyright gittensor/validator/issue_discovery/scan.py tests/validator/issue_discovery/test_scan.py — 0 errors, 0 warnings.

Files changed

  • gittensor/validator/issue_discovery/scan.py_build_solving_pr_cache accepts and uses the resolved per-repo threshold; call site in run_issue_discovery updated to pass mirror_repos.
  • tests/validator/issue_discovery/test_scan.py — 2 new regression tests; 3 existing TestSolvingPrCache tests updated to pass mirror_repos; RepoEligibilityConfig added to the existing load_weights import block.

`_build_solving_pr_cache` filtered by the global `MIN_TOKEN_SCORE_FOR_BASE_SCORE`,
dropping merged PRs that cleared their repo's per-repo override. The cache-MISS
path (`_resolve_solving_pr_score`) and OSS scoring path already honor the
per-repo threshold (PR entrius#1330); align the cache-population path so cache-HIT and
cache-MISS yield the same scoring outcome. Falls back to the global default for
repos missing from `mirror_repos` (defensive).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@xiao-xiao-mao xiao-xiao-mao Bot added the bug Something isn't working label May 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]build_solving_pr_cache ignores per-repo min_token_score_for_base_score

1 participant