You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
gittensor/utils/github_api_tools.py:1051 sorts candidate solving PRs with key=lambda p: (p.get('merged_at') or '', p.get('number') or 0) where merged_at is the raw ISO 8601 string returned by the GraphQL API. ISO 8601 is usually lexicographically sortable, but only if every value uses the
same precision and timezone-suffix format. GitHub's GraphQL API has, historically, returned both 2026-01-01T00:00:00Z and 2026-01-01T00:00:00.000Z depending on the field path and node type.
Lexicographically, '2026-01-01T00:00:00.000Z' < '2026-01-01T00:00:00Z' because '.' (0x2E) < 'Z' (0x5A) — so a PR merged at sub-second precision sorts earlier than one merged at second precision at the same instant.
This decides which PR is credited as the issue's solver.
Steps to Reproduce
Construct two merged-PR fixtures both closing issue repo#5:
Call find_solver_from_cross_references('owner/repo', 5, token) with both returned by the GraphQL helper.
Observe which pr_number is returned.
Expected Behavior
The earliest real-time merge wins. Both PRs were merged at the same moment — the deterministic tiebreaker (pr.number) should pick PR_A.
Actual Behavior
PR_B (number 20) is selected because '2026-01-01T00:00:00.000Z' sorts before '2026-01-01T00:00:00Z' lexicographically. The wrong solver gets
credited; the wrong miner gets the issue bonus.
Environment
OS: Linux
Python version: 3.10+
Commit/Version: d8ba803
Additional Context
Even when GitHub returns consistent precision, this is fragile against future API changes.
Description
gittensor/utils/github_api_tools.py:1051sorts candidate solving PRs withkey=lambda p: (p.get('merged_at') or '', p.get('number') or 0)wheremerged_atis the raw ISO 8601 string returned by the GraphQL API. ISO 8601 is usually lexicographically sortable, but only if every value uses thesame precision and timezone-suffix format. GitHub's GraphQL API has, historically, returned both
2026-01-01T00:00:00Zand2026-01-01T00:00:00.000Zdepending on the field path and node type.Lexicographically,
'2026-01-01T00:00:00.000Z' < '2026-01-01T00:00:00Z'because'.'(0x2E) <'Z'(0x5A) — so a PR merged at sub-second precision sorts earlier than one merged at second precision at the same instant.This decides which PR is credited as the issue's solver.
Steps to Reproduce
repo#5:PR_A:number=10,merged_at='2026-01-01T00:00:00Z'PR_B:number=20,merged_at='2026-01-01T00:00:00.000Z'find_solver_from_cross_references('owner/repo', 5, token)with both returned by the GraphQL helper.pr_numberis returned.Expected Behavior
The earliest real-time merge wins. Both PRs were merged at the same moment — the deterministic tiebreaker (
pr.number) should pickPR_A.Actual Behavior
PR_B(number 20) is selected because'2026-01-01T00:00:00.000Z'sorts before'2026-01-01T00:00:00Z'lexicographically. The wrong solver getscredited; the wrong miner gets the issue bonus.
Environment
d8ba803Additional Context
— that PR fixed the selection of earliest-merged but didn't address the string-vs-datetime sort key.
parse_github_iso_to_utcto convert before sort:merged.sort(key=lambda p: (parse_github_iso_to_utc(p['merged_at']), p['number'])).