Description
PR #769 introduced the stale_closed_pull_requests bucket to refresh pr_state for out-of-window PRs but left two issues unaddressed.
Gap 1 — Stale UPSERT silently zeroes previously-scored rows
store_pull_requests_bulk in gittensor/validator/utils/storage.py:74-76 uses BULK_UPSERT_PULL_REQUESTS, an ON CONFLICT DO UPDATE SET that overwrites all columns via EXCLUDED.*. PullRequest.from_graphql_response() leaves every scoring field at its dataclass default (base_score = 0.0, earned_score = 0.0, credibility_multiplier = 1.0, etc.), so any row that was previously scored has those computed values silently replaced with zeros on every subsequent scan.
Gap 2 — Fragile positional assertion in test_stale_closed_prs_are_stored_separately
tests/validator/utils/test_storage_mirror.py:176 asserts stale storage via a hardcoded call index call_args_list[3]. Any reordering of bulk calls in store_evaluation silently breaks the assertion's target without failing the test.
Steps to Reproduce
- A miner has a PR that was previously scored (e.g. was OPEN with collateral) and later closed outside the 35-day lookback window.
- On the next validator scan,
try_add_open_or_closed_pr routes it to stale_closed_pull_requests.
store_pull_requests_bulk fires the full BULK_UPSERT_PULL_REQUESTS with dataclass-default scoring fields.
- The previously-computed
earned_score, base_score, credibility_multiplier, etc. are overwritten with 0.0 / 1.0 in the database.
Expected Behavior
- Only
pr_state and updated_at should be modified for stale PRs. All scoring columns on existing rows must be left untouched.
- The stale storage test should assert against the dedicated stale method by name, not by positional call index.
Actual Behavior
- Previously-scored rows have their scoring columns zeroed out by the stale UPSERT on every subsequent scan.
test_stale_closed_prs_are_stored_separately asserts via call_args_list[3] and would pass incorrectly if call order in store_evaluation changed.
Environment
Additional Context
Follow-up to #769, #768. No schema changes are required to fix either gap. Gap 1 can be resolved with a dedicated method backed by a targeted UPDATE touching only pr_state and updated_at instead of routing through the full-column UPSERT path.
Description
PR #769 introduced the
stale_closed_pull_requestsbucket to refreshpr_statefor out-of-window PRs but left two issues unaddressed.Gap 1 — Stale UPSERT silently zeroes previously-scored rows
store_pull_requests_bulkingittensor/validator/utils/storage.py:74-76usesBULK_UPSERT_PULL_REQUESTS, anON CONFLICT DO UPDATE SETthat overwrites all columns viaEXCLUDED.*.PullRequest.from_graphql_response()leaves every scoring field at its dataclass default (base_score = 0.0,earned_score = 0.0,credibility_multiplier = 1.0, etc.), so any row that was previously scored has those computed values silently replaced with zeros on every subsequent scan.Gap 2 — Fragile positional assertion in
test_stale_closed_prs_are_stored_separatelytests/validator/utils/test_storage_mirror.py:176asserts stale storage via a hardcoded call indexcall_args_list[3]. Any reordering of bulk calls instore_evaluationsilently breaks the assertion's target without failing the test.Steps to Reproduce
try_add_open_or_closed_prroutes it tostale_closed_pull_requests.store_pull_requests_bulkfires the fullBULK_UPSERT_PULL_REQUESTSwith dataclass-default scoring fields.earned_score,base_score,credibility_multiplier, etc. are overwritten with0.0/1.0in the database.Expected Behavior
pr_stateandupdated_atshould be modified for stale PRs. All scoring columns on existing rows must be left untouched.Actual Behavior
test_stale_closed_prs_are_stored_separatelyasserts viacall_args_list[3]and would pass incorrectly if call order instore_evaluationchanged.Environment
86390ad(post-fix: sync pr_state for stale-closed PRs excluded from scoring #769 merge)Additional Context
Follow-up to #769, #768. No schema changes are required to fix either gap. Gap 1 can be resolved with a dedicated method backed by a targeted
UPDATEtouching onlypr_stateandupdated_atinstead of routing through the full-column UPSERT path.