Bug
gittensor/validator/issue_discovery/mirror_scan.py:174 computes the spam-multiplier signal:
open_issue_count = sum(1 for i in filtered if i.state == 'OPEN')
This count includes issues whose is_transferred == True. Everywhere else in the same module, transferred issues are treated as having no scorable meaning at all:
- Module docstring lines 12-19 list "not
issue.is_transferred" among the anti-gaming gates.
_classify_issue (line 468-470) returns 'ignore' for transferred issues regardless of state.
The spam-multiplier path is the only place in the module that treats transferred-OPEN issues as if they were real OPEN issues this miner is responsible for.
Source
mirror_scan.py:169-175:
# Count this miner's currently-open issues across mirror-enabled repos
# (within the lookback window). Used as the spam-multiplier signal and
# also written to evaluation.total_open_issues so the DB row reflects
# mirror-scoped state ...
open_issue_count = sum(1 for i in filtered if i.state == 'OPEN') # ← does not filter is_transferred
pending.append((evaluation, filtered, open_issue_count))
mirror_scan.py:458-470 (the canonical "no scorable meaning" check):
def _classify_issue(issue: MirrorIssue) -> str:
"""Return 'solved', 'not-solved-closed', or 'ignore' per anti-gaming gates.
'ignore' = issue is open / transferred / has no scorable meaning at all.
...
"""
if issue.is_transferred:
bt.logging.debug(f' issue #{issue.issue_number} ({issue.repo_full_name}): ignore (transferred)')
return 'ignore'
Impact
-
Inflated spam multiplier — calculate_open_issue_spam_multiplier(open_issue_count, …) reads the inflated count and reduces the per-solved-issue discovery score. A miner with 5 legitimate OPEN issues plus 3 transferred-OPEN issues gets penalized as though they had 8 currently-open issues.
-
Corrupted DB audit row — mirror_scan.py:376 writes evaluation.total_open_issues = open_issue_count. The miner_evaluations row carries the inflated number, so analytics queries (SELECT total_open_issues …) show miners as having more open issues than they actually own.
-
Asymmetric anti-gaming — the docstring promises that transferred issues "have no scorable meaning at all," but they DO have negative scoring meaning via the spam multiplier path. An attacker controlling repo administration could file an issue, transfer it to a target miner's tracking surface, and inflate that miner's spam count even though the issue itself can never score.
Reproduction
Construct a MirrorIssue list containing two entries:
state='OPEN', is_transferred=False
state='OPEN', is_transferred=True
Drive them through _score_miner_mirror_issues. Observe open_issue_count == 2. Observe the resulting spam multiplier as if both issues were real. Then mark is_transferred=False on the second issue and run again — multiplier changes, demonstrating the transferred issue affected the score.
Suggested fix
One-line change at line 174:
open_issue_count = sum(1 for i in filtered if i.state == 'OPEN' and not i.is_transferred)
Optionally, add a regression test that asserts transferred-OPEN issues do not contribute to open_issue_count and total_open_issues.
Related
- #929 / #930 address a different gap on the same line — old still-open issues outside the lookback window being undercounted. Fixing that does not address transferred-issue inclusion; the two filters are independent.
- The merged #796 introduced this scoring path with
is_transferred already being a recognized "ignore" signal in _classify_issue; the omission in the spam-count branch appears to be an oversight rather than a deliberate semantic choice.
Bug
gittensor/validator/issue_discovery/mirror_scan.py:174computes the spam-multiplier signal:This count includes issues whose
is_transferred == True. Everywhere else in the same module, transferred issues are treated as having no scorable meaning at all:issue.is_transferred" among the anti-gaming gates._classify_issue(line 468-470) returns'ignore'for transferred issues regardless of state.The spam-multiplier path is the only place in the module that treats transferred-OPEN issues as if they were real OPEN issues this miner is responsible for.
Source
mirror_scan.py:169-175:mirror_scan.py:458-470(the canonical "no scorable meaning" check):Impact
Inflated spam multiplier —
calculate_open_issue_spam_multiplier(open_issue_count, …)reads the inflated count and reduces the per-solved-issue discovery score. A miner with 5 legitimate OPEN issues plus 3 transferred-OPEN issues gets penalized as though they had 8 currently-open issues.Corrupted DB audit row —
mirror_scan.py:376writesevaluation.total_open_issues = open_issue_count. Theminer_evaluationsrow carries the inflated number, so analytics queries (SELECT total_open_issues …) show miners as having more open issues than they actually own.Asymmetric anti-gaming — the docstring promises that transferred issues "have no scorable meaning at all," but they DO have negative scoring meaning via the spam multiplier path. An attacker controlling repo administration could file an issue, transfer it to a target miner's tracking surface, and inflate that miner's spam count even though the issue itself can never score.
Reproduction
Construct a
MirrorIssuelist containing two entries:state='OPEN', is_transferred=Falsestate='OPEN', is_transferred=TrueDrive them through
_score_miner_mirror_issues. Observeopen_issue_count == 2. Observe the resulting spam multiplier as if both issues were real. Then markis_transferred=Falseon the second issue and run again — multiplier changes, demonstrating the transferred issue affected the score.Suggested fix
One-line change at line 174:
Optionally, add a regression test that asserts transferred-OPEN issues do not contribute to
open_issue_countandtotal_open_issues.Related
is_transferredalready being a recognized "ignore" signal in_classify_issue; the omission in the spam-count branch appears to be an oversight rather than a deliberate semantic choice.