Addresses the SHA tracking gap identified in review #4451. The
reviewed_prs data structure was a set() that only tracked PR numbers,
but Source C's get_last_reviewed_sha() call had no data to compare
against for PRs adopted by the cross-session dedup logic.
Changes:
- reviewed_prs = set() -> reviewed_prs = {} (PR number -> HEAD SHA)
- Source A dedup: reviewed_prs.add(pr.number) -> reviewed_prs[pr.number] = pr.head.sha
- Source C: get_last_reviewed_sha(pr.number) -> reviewed_prs[pr.number]
- Source C: reviewed_prs.discard() -> del reviewed_prs[]
- Result processing: reviewed_prs.add(pr_number) -> reviewed_prs[pr_number] = 'done' (sentinel)
or reviewed_prs[pr_number] = result.pr.head.sha for changes_requested
This ensures Source C can correctly detect when an implementor pushes
new commits after a review, preventing the within-cycle race condition
where a PR is simultaneously in reviewed_prs and work_items.
Add cross-session deduplication check in Source A filtering that detects
existing bot review comments and skips PRs where HEAD hasn't changed since
the last review.
ISSUES CLOSED: #2424