Skip to content

[Bug] find_solver_from_cross_references sorts merged PRs by ISO string instead of parsed datetime #881

@bitcompass

Description

@bitcompass

Description

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

  1. Construct two merged-PR fixtures both closing issue 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'
  2. Call find_solver_from_cross_references('owner/repo', 5, token) with both returned by the GraphQL helper.
  3. 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.
  • Related: PR fix: credit earliest-merged PR in find_solver_from_cross_references #758 ("credit earliest-merged PR in find_solver_from_cross_references")
    — that PR fixed the selection of earliest-merged but didn't address the string-vs-datetime sort key.
  • Suggested fix: use parse_github_iso_to_utc to convert before sort:
    merged.sort(key=lambda p: (parse_github_iso_to_utc(p['merged_at']), p['number'])).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions