fix: gate retroactive issue body edits in mirror issue discovery#827
Open
statxc wants to merge 1 commit intoentrius:testfrom
Open
fix: gate retroactive issue body edits in mirror issue discovery#827statxc wants to merge 1 commit intoentrius:testfrom
statxc wants to merge 1 commit intoentrius:testfrom
Conversation
Restores legacy parity. PR entrius#796 ported the PR-side post-merge edit gate (solving_pr.edited_after_merge) but missed the issue-side counterpart (issue.body_or_title_edited_at > pr.merged_at, originally added in entrius#434). MirrorIssue.last_edited_at is fetched and parsed but never consumed. Without this gate a miner can author a deliberately vague issue, wait for a third party's PR to merge a fix, then edit the issue body to retroactively match the fix and collect full discovery_earned_score. The check is added inline in _classify_issue, mirroring the shape of the neighboring solving_pr.edited_after_merge gate. Tests cover the post-merge edit (closed), pre-merge edit (solved), and never-edited (solved) cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Restores legacy parity in
mirror_scan._classify_issue. PR #796 ported the PR-side post-merge edit gate (solving_pr.edited_after_mergeatmirror_scan.py:461) but missed the issue-side counterpart (issue.body_or_title_edited_at > pr.merged_at, originally added in #434).MirrorIssue.last_edited_atis already fetched and parsed atgittensor/utils/mirror/models.py:271— it just was never read by the scoring path.Without this gate, a miner can author a deliberately vague issue, wait for a third party's PR to merge a fix, then edit the issue body to retroactively match what the PR fixed and collect full
discovery_earned_scorethey didn't earn. The check is added inline in_classify_issue, mirroring the shape of the neighboringsolving_pr.edited_after_mergeblock. Returns'not-solved-closed'so the issue still counts toward credibility (matches legacy semantics) but contributes no discovery score.Legacy parity table
oss_contributions/scoring.py:493checkedpr.last_edited_at > pr.merged_atsolving_pr.edited_after_mergeissue_discovery/scoring.py:253checkedissue.body_or_title_edited_at > pr.merged_at(added by #434)issue.last_edited_at > sp.merged_atRelationship to #822
#822 fixes the cross-miner one-issue-per-PR rule in
run_mirror_issue_discovery. This PR fixes a missing anti-gaming gate in_classify_issue. Different functions, different test classes, different attack vectors — the only mechanical overlap is the_issue_dicttest helper signature, which 3-way merges cleanly in either order.Related Issues
Closes #826
Type of Change
Testing
Three new tests in
TestClassifyIssue(mirroring the existingtest_solving_pr_edited_after_merge_counts_as_closedpattern):test_issue_edited_after_solving_pr_merge_counts_as_closedlast_edited_at = merged_at + 1s'not-solved-closed'(gate fires)test_issue_edited_before_solving_pr_merge_is_solvedlast_edited_at = merged_at − 1d'solved'(legitimate pre-merge edits not penalized)test_issue_never_edited_is_solvedlast_edited_at = None'solved'(gate is null-safe)Commands run:
uv run ruff check gittensor/validator/issue_discovery/mirror_scan.py tests/validator/issue_discovery/test_mirror_scan.py— All checks passeduv run ruff format --check <same paths>— 2 files already formatteduv run pyright <same paths>— 0 errors, 0 warnings, 0 informationsuv run python -m pytest tests/validator/issue_discovery/test_mirror_scan.py -v— 34 passed (3 new + 31 existing)uv run python -m pytest(full suite) — 646 passedOut of scope
solving_pr.edited_after_merge) is correctly ported and unchanged here.last_edited_atdirectly — it does not populate the legacybody_or_title_edited_atfield on the adaptedIssue, since that field is unread on the mirror path (mirror_scan.py:504already passesbody_or_title_edited_at=None).Checklist