Skip to content

fix(repo-finder): grade de facto maintainers whose association under-reports - #34

Open
imkp1 wants to merge 2 commits into
gaurav0107:mainfrom
imkp1:fix/defacto-maintainer-grading
Open

fix(repo-finder): grade de facto maintainers whose association under-reports#34
imkp1 wants to merge 2 commits into
gaurav0107:mainfrom
imkp1:fix/defacto-maintainer-grading

Conversation

@imkp1

@imkp1 imkp1 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Fixes #32.

author_association reports public org membership only. A private org member, or a lead who was never added to the org, comments as CONTRIBUTOR. Signal grading reads $mca, which is association only, so those confirmations are discarded and the issue grades none. The failure is silent: nothing in the output separates "no maintainer commented" from "the maintainer commented and we did not count them".

I originally filed #32 saying $mca should just use the $maint fallback. That was wrong and I have corrected the issue. The $mca / $mc split is deliberate, stated in the code, in the rubric prose, and asserted by a fixture that says PR #25's distinction must survive. The union is top-25 by commit count, and commit rank is not authority.

What this does

Adds a third set, strictly narrower than the union: authors of >= 5 of the last 20 merged PRs, bots excluded. Grading runs on association ∪ de facto.

  • $mca and maintainer_comment_assoc stay association only
  • the union stays ungraded, so a prolific committer still earns nothing
  • fixture #904, the union-only lead, still asserts none

Threshold

Measured, not picked. Per-author share of the last 20 merged PRs across 18 Go and AI repos:

n=15  1 author
n=11  1   bot, excluded
n= 9  1
n= 8  1
n= 6  1
n= 5  2
n= 4  2   both bots, excluded
n= 3  13 authors   <- ordinary contributors
n= 2  14
n= 1  112

Clean gap between 3 and 5 once bots are out. All six non-bot authors at >= 5 are insiders whose association under-reports, none of them public org members. A cutoff of 3 admits 23 authors and re-creates the commit-rank error #25 fixed.

Notes

  • --defacto is optional. An absent list reads as empty, which restores the previous behaviour exactly. I diffed the output against main on a union-only fixture to confirm.
  • Reuses $MERGED_PRS from 3a. No extra API calls.
  • The caller's $BOT_NAMES misses handles like ...-cherrypick-robot, where bot is not a whole word. Safe: the filter's own bot regex is a superset and runs before grading. Noted in a comment rather than duplicating the guard.

Tests

New fixture #927: a de facto lead commenting as CONTRIBUTOR must grade confirms while maintainer_comment_assoc stays false. Fails before the change with unknown argument: --defacto, passes after.

61/64 scripts pass. The three failures (test_audit_impact, test_parse_workflows, test_smoke_gate) fail identically on main in my environment for missing yq and GNU timeout. shellcheck is not installed locally, so CI covers it.

Summary by CodeRabbit

  • New Features
    • Improved issue triage by recognizing active maintainers based on recent merged pull request activity.
    • Maintainer signals can now be identified even when the contributor is not formally associated with the project.
  • Bug Fixes
    • Preserved existing association-based triage behavior while adding support for de facto maintainer signals.
  • Tests
    • Added coverage confirming correct triage results for issues involving active maintainers.

…reports

author_association reports public org membership only, so a private member
or a lead never added to the org comments as CONTRIBUTOR and their
confirmation is discarded. Add a third set, strictly narrower than the 3c
union: authors of >=5 of the last 20 merged PRs, bots excluded. Grade on
association union de facto.

$mca and maintainer_comment_assoc stay association-only, and the union
stays ungraded, so the distinction PR gaurav0107#25 drew is unchanged.

Threshold measured across 18 repos, not picked: with bots removed the
per-author distribution has a clean gap between 3 and 5 of 20. All six
non-bot authors at >=5 are insiders whose association under-reports. A
cutoff of 3 admits 23 authors and re-creates the commit-rank error gaurav0107#25
fixed.

--defacto is optional; an absent list restores the previous behaviour
byte for byte. Reuses the merged-PR list from 3a, so no extra API calls.
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@imkp1, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dc0e0c5b-29a5-4288-9ae8-974039720340

📥 Commits

Reviewing files that changed from the base of the PR and between e148590 and e31ca64.

📒 Files selected for processing (3)
  • agents/repo-finder.md
  • scripts/orchestrator/triage_filter.sh
  • tests/scripts/test_triage_filter.sh
📝 Walkthrough

Walkthrough

The repo-finder workflow now derives de facto maintainers from recent merged PR authors, passes them to the triage filter, and includes them in maintainer signal grading while retaining association-only comment metadata. Tests cover de facto confirmations and union-only exclusions.

Changes

De facto maintainer signal

Layer / File(s) Summary
Derive and document de facto maintainers
agents/repo-finder.md
Stage A identifies non-bot authors appearing in at least five of the last 20 merged PRs, passes the list to triage filtering, and updates the scoring rubric.
Integrate de facto comments into grading
scripts/orchestrator/triage_filter.sh
The filter accepts an optional --defacto file and includes its logins in signal grading while preserving association-only fields.
Validate de facto signal behavior
tests/scripts/test_triage_filter.sh
Fixtures and assertions verify de facto confirmations, union-only exclusions, and unchanged comment association behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RepoFinder
  participant triage_filter.sh
  participant jq
  RepoFinder->>RepoFinder: Derive DEFACTO from merged PR authors
  RepoFinder->>triage_filter.sh: Pass --defacto DEFACTO
  triage_filter.sh->>jq: Load maintainer and de facto sets
  jq->>triage_filter.sh: Grade association or de facto comments
Loading

Possibly related PRs

Suggested reviewers: gaurav0107

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is specific and accurately summarizes the de facto maintainer grading change.
Linked Issues check ✅ Passed The changes add a non-bot last-20-merged-PR de facto set and grade on association ∪ de facto while preserving association-only fields.
Out of Scope Changes check ✅ Passed All changes support the de facto maintainer grading workflow or its tests, with no unrelated edits evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/scripts/test_triage_filter.sh (1)

204-205: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the legacy invocation without --defacto.

This test now always supplies the new file, so it does not verify the explicitly supported backward-compatible path. Add a run without --defacto and assert that association-only grading remains unchanged.

Based on the PR objective, preserving behavior when --defacto is absent is part of the contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/scripts/test_triage_filter.sh` around lines 204 - 205, Extend the test
around the FILTER invocation to also run without the --defacto option, using the
same issues, maintainers, and timestamp inputs. Assert that association-only
grading matches the existing expected output, preserving the legacy invocation
behavior while retaining the current --defacto coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@agents/repo-finder.md`:
- Line 775: Update the “Maintainer signal” documentation to state that
gradeability requires association or de facto maintainer membership, while
keeping the broader contributor union ungraded. Preserve the existing scoring
values and de facto threshold, and express the rule as association ∪ de facto
rather than association alone.
- Around line 622-623: Update the DEFACTO generation pipeline using MERGED_PRS
so jq excludes missing or null author logins before grouping, preventing null
candidates. Preserve valid zero-result output, but propagate actual jq, sort, or
bot-filter failures instead of converting them to an empty DEFACTO file; avoid
grep pipeline status behavior that treats expected no matches as an upstream
failure.

---

Nitpick comments:
In `@tests/scripts/test_triage_filter.sh`:
- Around line 204-205: Extend the test around the FILTER invocation to also run
without the --defacto option, using the same issues, maintainers, and timestamp
inputs. Assert that association-only grading matches the existing expected
output, preserving the legacy invocation behavior while retaining the current
--defacto coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ecc6462f-d812-4003-81a1-d9e40b18e26a

📥 Commits

Reviewing files that changed from the base of the PR and between 5305304 and e148590.

📒 Files selected for processing (3)
  • agents/repo-finder.md
  • scripts/orchestrator/triage_filter.sh
  • tests/scripts/test_triage_filter.sh

Comment thread agents/repo-finder.md Outdated
Comment thread agents/repo-finder.md Outdated
…g them

Three defects in the de facto tier as first written.

$defacto was documented as a strict subset of $maint and only unioned into
the grading set. It is not a subset by construction: $maint ranks contributors
by all-time commits, so a lead who joined recently clears 5 of the last 20
merged PRs and still sits outside the top 25, and $maint's association legs
cannot catch them either — under-reported association is why they are in the
de facto list at all. Such a lead was graded but absent from $mc, which drives
the triage gate, maintainer_commented and last_maintainer_comment. The issue
then failed the gate and never reached the ranker, which is the silent discard
this tier exists to fix; when a good-first-issue label rescued it, the row read
maintainer_commented: false beside maintainer_signal: confirms. Union $defacto
into $mc instead of assuming containment.

The derivation masked its own failures. grep exits 1 on no match, and no match
is the ordinary case here, so `|| : > "$DEFACTO"` could not tell an empty and
correct result from a jq that died. Both filters now run inside jq and a real
failure is fatal. It also counted ghost authors: a deleted account serializes
as author: null, and five of them grouped into a literal `null` maintainer.
Guard with `// empty`, as 3c already does. An unset $BOT_NAMES would make
test("") match every login and empty the set in silence; assert it instead.

Rubric prose said association is the prerequisite, which the de facto tier
contradicts. Gradeable is association ∪ de facto; the 3c union stays ungraded.

Tests: fixture #928 is a de facto lead outside the union, labelled `bug` only
so no label can rescue it at the gate — it fails without the $mc change. A
legacy run without --defacto asserts #927 falls back to `none`, #928 fails the
gate, and every other verdict is byte-identical.

61/64 scripts pass; test_audit_impact, test_parse_workflows and test_smoke_gate
fail identically on main here for missing yq and GNU timeout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

repo-finder: signal grading ignores the $maint fallback list, dropping de facto maintainers

1 participant