fix(maintainer): use affiliation=all so org-owned repos get maintainers#198
Merged
Merged
Conversation
Org-owned repos whose members are private (the GitHub default) resolved
to an empty maintainer set and were skipped by MaintainerPopulateService,
because affiliation=direct only returns users explicitly added to the
repo — it excludes insiders who get access via a team or org base
permission, and /orgs/{org}/members only exposes public members to the
app token.
Switch the collaborators fetch to affiliation=all so any insider with
repo access is captured. The live maintainers table is meant to reproduce
GitHub's author_association (OWNER/MEMBER/COLLABORATOR), which marks org
insiders as maintainers regardless of how access was granted, so this is
the faithful set — not a permission-level reinterpretation.
Fixes gittensor-ai-lab/sparkinfer showing zero maintainers.
entrius
approved these changes
Jun 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
gittensor-ai-lab/sparkinfer(and other org-owned repos) showed zero maintainers in themaintainerstable. The nightlyMaintainerPopulateServicelogged:Root cause
fetchRepoCollaboratorsqueriedGET /repos/{owner}/{repo}/collaborators?affiliation=**direct**, which only returns users explicitly added to the repo. It excludes insiders who get access via a team or org base permission. The other input,/orgs/{org}/members, only exposes public members to the app installation token.gittensor-ai-labhas no public members (private membership is GitHub's default) and grants repo access without direct collaborator entries — so both inputs returned empty, the maintainer set was empty, and the populate step skipped the repo (it fails closed rather than wipe).This is not a per-install permission difference (every install has identical app permissions) and not a setup error on the org — it's the
affiliation=directfilter being too narrow for org-owned repos.Fix
Switch the collaborators fetch to
affiliation=all. Any insider with repo access — direct collaborator, team-based, or org base permission, plus org owners — is now captured, regardless of org-membership visibility.This is deliberate and matches the data's contract: the live
maintainerstable is overlaid on top of GitHub's storedauthor_association(miners.service.ts:COALESCE(m_author.association, p.author_association)), so it must reproduce the OWNER / MEMBER / COLLABORATOR association semantics. GitHub marks any org insider with repo access as a maintainer regardless of how access was granted — soaffiliation=allis the faithful set, not a permission-level reinterpretation.Why not the alternatives
Members: readto the app — forces every org owner to re-approve the install and only helps where the app is installed org-wide.author_association(which counts read-only members/collaborators as MEMBER/COLLABORATOR), breaking the COALESCE overlay.Impact
Downstream, maintainer status gates PR-reward exclusion and the
maintainer_cutcarve-out. With sparkinfer previously showing zero maintainers, its configuredmaintainer_cutwas being silently skipped (carve-out is bypassed when the maintainer set is empty). After this change the carve-out routes correctly and insider PRs are excluded as intended.Testing
npm run build(nest build) passes