fix(agent-actions): honor ADMIN_GITHUB_LOGINS in close-eligibility - #2390
Conversation
The planner's isContributor/closeEligible/blacklistContributor gates and the draft-dodge path's duplicated authorIsOwner computation only recognized the literal repo-owner login. The reopen-reclose path's hasMaintainerPermission already treats ADMIN_GITHUB_LOGINS members as trusted maintainers, so a fleet-operator admin (not the literal owner) was reopen-immune but still eligible for heuristic/blacklist auto-close on the same PR — two independently drifting definitions of "maintainer" for the same identity. Thread a new authorIsAdmin field (computed via the same parseGitHubLoginList(env.ADMIN_GITHUB_LOGINS) helper) through planAgentMaintenanceActions, treating it identically to authorIsOwner everywhere: never auto-closed by default, eligible only when closeOwnerAuthors is on. Apply the identical fix to the draft-dodge handler's duplicate computation in processors.ts.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2390 +/- ##
=======================================
Coverage 95.71% 95.71%
=======================================
Files 222 222
Lines 24661 24663 +2
Branches 8949 8951 +2
=======================================
+ Hits 23605 23607 +2
Misses 433 433
Partials 623 623
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-01 20:09:50 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
What
The main planner's close-eligibility gate (
isContributor/closeEligible/blacklistContributorinsrc/settings/agent-actions.ts) and the draft-dodge handler's duplicated owner check (src/queue/processors.ts) only recognized the literal repo-owner login as a trusted, never-auto-closed identity. The reopen-reclose path'shasMaintainerPermissionalready treatsADMIN_GITHUB_LOGINSmembers as trusted maintainers (login === repoOwner || admins.has(login)) — explicitly unified there for exactly this purpose. A fleet-operator admin login (not the literal repo owner) was therefore reopen-immune but still eligible for heuristic/blacklist auto-close on the very same PR: two independently drifting definitions of "maintainer" for the same identity.Fix
src/settings/agent-actions.ts: addedauthorIsAdmin: booleanto the planner's input type, computed the same wayauthorIsOwneris (by the caller, kept out of this pure/dependency-injected module). Threaded it intoisContributor,blacklistContributor, andcloseEligible— treated identically toauthorIsOwnerthroughout: never auto-closed by default, eligible only whencloseOwnerAuthorsis explicitly on (folded into the same per-repo toggle rather than inventing a second one, since it's the same "should our trusted-tier PRs be treated like contributor PRs" question).src/queue/processors.ts: computedauthorIsAdminvia the sameparseGitHubLoginList(env.ADMIN_GITHUB_LOGINS)helperhasMaintainerPermissionalready uses, at both the main maintenance planner's call site and the draft-dodge handler's independently-duplicatedauthorIsOwnercomputation — the two spots named in the issue.Tests
agent-actions.test.tsmirroring the existing owner-PR-guard group: an admin-authored noisy/failing PR is not auto-closed, still auto-merges when clean+approved, closes whencloseOwnerAuthorsis on, and is not closed on red CI.queue.test.ts: the draft-dodge handler no-ops for anADMIN_GITHUB_LOGINS-listed, non-owner author, mirroring the existing literal-owner no-op test.npx tsc --noEmitclean — makingauthorIsAdmina required field (matchingauthorIsOwner's own required-ness) surfaced every call site needing the update via the compiler, including 3 raw-literal test calls that bypass the sharedinput()test helper.agent-actions.test.ts— 99 passed (95 + 4 new).agent-action-executor.test.ts,agent-approval-queue.test.ts,outcomes-wire.test.ts,precision-breakers-chain.test.ts(all other importers ofagent-actions.ts) — 89 passed; fullqueue.test.ts— 203 passed.npm run test:coverage: 5605 passed, 4 skipped (pre-existing/unrelated), 0 failed.npm audit --audit-level=moderate: 0 vulnerabilities.Advances #1936. Closes #2133.