Skip to content

Commit 6426d26

Browse files
authored
Fix reviewer suggestion confidence for sole experts (#4905)
## Why The `suggest-reviewers` GitHub Action had two issues: 1. When a single person was the sole contributor to all changed files, confidence was reported as "low" instead of "high". This happened because `compute_confidence` treated `len(ss) < 2` as insufficient data, when it actually means there's one clear expert. 2. Output files (`out.*`, `output.txt`) were scored `0.0` and completely excluded from analysis. Reviewers should still verify output changes make sense, so these files deserve a small (but non-zero) contribution to scoring. ## Changes **Before:** Sole-author PRs always got "low" confidence. Output files were invisible to the scoring algorithm. PRs with exactly 2 contributors also always got "low" confidence (the `>= 3` guards prevented any comparison). **Now:** - `len(ss) == 1` (sole contributor) returns "high" confidence - `len(ss) == 2` compares top vs second using the same 2x/1.5x thresholds - Output files get weight `0.01 / total_files` instead of `0.0`, contributing signal without dominating scores - Removed dead `if weight == 0.0` guard that could never trigger after the weight change ## Test plan - Verified against PR #4857 (4 files, 2 output, pietern sole author): would now produce "high" instead of "low" - Logic review of all `compute_confidence` branches for correctness This pull request was AI-assisted by Isaac.
1 parent 6a0ddd8 commit 6426d26

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

tools/suggest_reviewers.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
_login_cache: dict[str, str | None] = {}
1717

1818

19-
def classify_file(path: str) -> float:
19+
def classify_file(path: str, total_files: int) -> float:
2020
p = Path(path)
2121
if p.name.startswith("out.") or p.name == "output.txt":
22-
return 0.0
22+
return 0.01 / max(total_files, 1)
2323
if path.startswith(("acceptance/", "integration/")):
2424
return 0.2
2525
if path.endswith("_test.go"):
@@ -113,10 +113,9 @@ def score_contributors(
113113
scored_count = 0
114114
author_login = pr_author.lower()
115115

116+
total_files = len(files)
116117
for filepath in files:
117-
weight = classify_file(filepath)
118-
if weight == 0.0:
119-
continue
118+
weight = classify_file(filepath, total_files)
120119
history = git_log(filepath)
121120
if not history:
122121
parent = str(Path(filepath).parent)
@@ -165,11 +164,21 @@ def select_reviewers(ss: list[tuple[str, float]]) -> list[tuple[str, float]]:
165164

166165

167166
def compute_confidence(ss: list[tuple[str, float]], scored_count: int) -> str:
168-
if scored_count < 3 or len(ss) < 2:
167+
if not ss:
168+
return "low"
169+
if len(ss) == 1:
170+
return "high"
171+
if len(ss) == 2:
172+
if ss[0][1] > 2 * ss[1][1]:
173+
return "high"
174+
if ss[0][1] > 1.5 * ss[1][1]:
175+
return "medium"
176+
return "low"
177+
if scored_count < 3:
169178
return "low"
170-
if len(ss) >= 3 and ss[0][1] > 2 * ss[2][1]:
179+
if ss[0][1] > 2 * ss[2][1]:
171180
return "high"
172-
if len(ss) >= 3 and ss[0][1] > 1.5 * ss[2][1]:
181+
if ss[0][1] > 1.5 * ss[2][1]:
173182
return "medium"
174183
return "low"
175184

0 commit comments

Comments
 (0)