Summary
In buildContributorOpenPrMonitor, the helper groupByRepo buckets a contributor's open PRs by the raw pr.repoFullName, while every other repo-name operation in the same function is case-insensitive (the registered-repo set, the open-PR filter, and the repo lookup all use .toLowerCase()). GitHub repo names are case-insensitive, so if a contributor's open PRs for one repo carry different casings, they are split into separate groups — under-counting per-repo open PRs (so the spam/threshold view is wrong), running cross-case duplicate detection only within each partial group, and doing redundant per-repo work.
Area
Signal logic
Expected behavior
groupByRepo should bucket case-insensitively (like the rest of the function), so all of a repo's open PRs land in one group, while the case-sensitive per-repo DB queries still receive a real repo casing.
Actual behavior
groupByRepo keys the map on pr.repoFullName verbatim, so entrius/allways-ui and Entrius/Allways-UI become two groups for the same repo — splitting the open-PR set and the duplicate-proneness check, and querying listPullRequests twice (once per casing).
Reproduction
A contributor with two open PRs in the same registered repo whose records differ only in repoFullName casing yields two groups instead of one (e.g. duplicate-proneness is no longer computed across both PRs).
Validation
Unit test added: two open PRs for one repo under different casings are grouped together, and the case-sensitive listPullRequests query runs only against a real casing, never the case-variant.
Public-safety check
Summary
In
buildContributorOpenPrMonitor, the helpergroupByRepobuckets a contributor's open PRs by the rawpr.repoFullName, while every other repo-name operation in the same function is case-insensitive (the registered-repo set, the open-PR filter, and the repo lookup all use.toLowerCase()). GitHub repo names are case-insensitive, so if a contributor's open PRs for one repo carry different casings, they are split into separate groups — under-counting per-repo open PRs (so the spam/threshold view is wrong), running cross-case duplicate detection only within each partial group, and doing redundant per-repo work.Area
Signal logic
Expected behavior
groupByReposhould bucket case-insensitively (like the rest of the function), so all of a repo's open PRs land in one group, while the case-sensitive per-repo DB queries still receive a real repo casing.Actual behavior
groupByRepokeys the map onpr.repoFullNameverbatim, soentrius/allways-uiandEntrius/Allways-UIbecome two groups for the same repo — splitting the open-PR set and the duplicate-proneness check, and queryinglistPullRequeststwice (once per casing).Reproduction
A contributor with two open PRs in the same registered repo whose records differ only in
repoFullNamecasing yields two groups instead of one (e.g. duplicate-proneness is no longer computed across both PRs).Validation
Unit test added: two open PRs for one repo under different casings are grouped together, and the case-sensitive
listPullRequestsquery runs only against a real casing, never the case-variant.Public-safety check