Skip to content

fix(github): stop a third-party action_required check from auto-closing PRs on repos with no branch protection - #4736

Merged
JSONbored merged 1 commit into
mainfrom
fix/ci-third-party-action-required-no-branch-protection-4735
Jul 10, 2026
Merged

fix(github): stop a third-party action_required check from auto-closing PRs on repos with no branch protection#4736
JSONbored merged 1 commit into
mainfrom
fix/ci-third-party-action-required-no-branch-protection-4735

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • Live incident: PR Upgrade duplicationDelta's greedy block assignment to optimal bipartite matching #4812 (JSONbored/metagraphed, contributor jimcody1995) was auto-closed this morning with the reason CI is failing (Contributor trust) — despite every real CI check green (tests, ui, codecov/patch, codecov/project) and despite fix(github): treat completed third-party action_required checks as failing/manual-hold #4414 having previously fixed exactly this class of bug.
  • Root cause: reduceLiveCiAggregate gates a third-party app's own action_required verdict (Superagent's advisory-only "Contributor trust" check) on isRequired(name), which is !enforceRequiredOnly || requiredContexts.has(name)defaults to true for every check name whenever a repo has no branch-protection required-status-checks configured at all. Confirmed live: JSONbored/metagraphed's required_status_checks.contexts is []. fix(github): treat completed third-party action_required checks as failing/manual-hold #4414's fix only actually protects a repo that has some required contexts configured; a repo with none falls through the "assume required when unknown" fail-safe and reopens the exact bug.
  • Fix: a second, stricter helper isConfirmedRequired (enforceRequiredOnly && requiredContexts.has(name)) used only for this one branch — requires POSITIVE confirmation instead of "unknown → assume yes". isRequired() itself is untouched and still governs genuine CI-failure detection (where "unknown → assume required" is the correct fail-safe).

Closes #4735.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves.

Validation

  • git diff --check
  • npm run actionlint — skipped, no .github/workflows/** changes.
  • npm run typecheck
  • npm run test:coverage (targeted, not the full unsharded suite — see Notes) locally; every changed line in src/github/backfill.ts confirmed hit via lcov (both the true and false branch of the new isConfirmedRequired gate).
  • npm run test:workers — skipped, this function has no Worker-runtime-specific behavior beyond what the unit suite covers.
  • npm run build:mcp / npm run test:mcp-pack — skipped, no MCP package changes.
  • npm run ui:openapi:check / ui:lint / ui:typecheck / ui:test / ui:build — skipped, no apps/gittensory-ui/** or API-shape changes.
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests — see Notes.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth/cookie/CORS/GitHub App/Cloudflare/session changes include negative-path tests — N/A, none touched.
  • API/OpenAPI/MCP behavior updated and tested — N/A, no API/OpenAPI/MCP surface changed.
  • UI changes use live API data — N/A, no UI changes.
  • UI Evidence section — N/A, backend-only, no visible UI surface.
  • Public docs/changelogs are updated where needed; no changelog edit (not a release-prep PR).

Notes

Test coverage: extended test/unit/backfill.test.ts with two new regression tests, both reproducing PR #4812's exact real-world scenario:

  1. An empty requiredContexts Set (new Set(), matching metagraphed's live branch-protection response exactly) — the third-party action_required check-run now correctly lands in nonRequiredFailingDetails, ciState stays "passed".
  2. requiredContexts: null (a distinct origin — the required-status-checks fetch outright failed/403'd, rather than confirming an empty list) — same expected outcome, since "unconfirmed" should behave identically regardless of why it's unconfirmed.

Both new tests were verified to actually fail against the pre-fix isRequired() gate (temporarily reverted the one-line change, confirmed both tests fail with ciState: "failed" as PR #4812 actually did, then restored the fix) before being finalized — not just passing vacuously. The full existing backfill.test.ts suite (236 tests, including all 4 pre-existing #4414 tests) plus the broader consumer suites (queue.test.ts, unified-comment.test.ts, 892 tests) pass unchanged, confirming no regression for repos that DO configure required contexts.

Not retroactive: this fix prevents the bug going forward; it does not reopen or re-review PR #4812 itself (closed PRs are never automatically reopened, per the bot's own close message) — the contributor will need to open a fresh PR once this deploys.

…ng PRs on repos with no branch protection (#4735)

reduceLiveCiAggregate gated a third-party app's own action_required
verdict (e.g. Superagent's advisory-only "Contributor trust" check) on
isRequired(name), which defaults to true for every check name whenever
a repo has NO branch-protection required-status-checks configured at
all (enforceRequiredOnly false). That silently reopened #4414 for any
such repo: confirmed live, JSONbored/metagraphed's required_status_checks
.contexts is [], and PR #4812 there was auto-closed this morning with
the literal reason "CI is failing (Contributor trust)" despite every
real CI check green and the review panel's own gate result correctly
reading "Advisory; not blocking".

Adds isConfirmedRequired (enforceRequiredOnly && requiredContexts.has),
the deliberate opposite default from isRequired, and uses it only for
this one branch. isRequired() itself is untouched -- a genuine CI
failure should still fail closed when required-ness is unconfirmed;
a third-party app's advisory opinion should not.
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.22%. Comparing base (12147aa) to head (6b8de5f).
⚠️ Report is 4 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4736   +/-   ##
=======================================
  Coverage   94.22%   94.22%           
=======================================
  Files         439      439           
  Lines       38704    38705    +1     
  Branches    14100    14100           
=======================================
+ Hits        36468    36469    +1     
  Misses       1576     1576           
  Partials      660      660           
Files with missing lines Coverage Δ
src/github/backfill.ts 97.19% <100.00%> (+<0.01%) ⬆️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 10, 2026
@loopover-orb

loopover-orb Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-10 22:03:06 UTC

2 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · unstable

⏸️ Suggested Action - Manual Review

  • Touches a guarded path — held for manual review: This PR changes guardrail-protected path(s): src/github/backfill.ts (matched src/github/backfill.ts).

Review summary
This narrowly-scoped fix adds a stricter `isConfirmedRequired` helper (positive confirmation only) used solely to gate whether a third-party app's `action_required` check-run feeds into `failingDetails`, leaving the existing `isRequired` fail-safe untouched for genuine CI-failure detection elsewhere. The root-cause trace is correct and verifiable in the diff: `enforceRequiredOnly` is false whenever `requiredContexts` is null or empty (no branch protection configured), which made the old `isRequired` return true for every check name and folded an advisory-only third-party verdict into the auto-close path — exactly reproducing #4812 despite #4414. Two new regression tests exercise both origin cases (empty-Set from a confirmed-empty branch-protection response, and null from a failed/skipped fetch) and assert the check lands in `nonRequiredFailingDetails` with `ciState` staying `passed`, which is the real production path (`fetchLiveCiAggregate`), not a fabricated payload. CI is green and the change is tightly scoped to the one branch that caused the incident, closing the linked issue #4735 with no unrelated surface area.

Nits — 6 non-blocking
  • The inline comment blocks in src/github/backfill.ts (both above `isConfirmedRequired` and above the `isThirdPartyActionRequired` branch) are quite long (~10 lines each) restating the same incident narrative — consider trimming to a couple of sentences per site now that the PR description and issue carry the full history.
  • Consider adding a brief unit test (or at least a comment) confirming `isRequired` itself is unchanged/still governs the non-action_required CI-failure branches, to make the intentional divergence between the two helpers harder to accidentally collapse in a future refactor.
  • nit: fold the two long doc comments into a single shared comment above `isConfirmedRequired`'s definition and just reference it briefly at the call site, reducing duplication.
  • Since this fix only covers third-party `action_required` checks, it may be worth a one-line note (or follow-up issue) on whether other 'unknown-required, fail-safe assumes true' spots in this file have the same no-branch-protection blind spot, so it doesn't need rediscovering incident-by-incident.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.
  • Touches a guarded path — held for manual review — A maintainer must review and merge this change.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #4735
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 48 registered-repo PR(s), 40 merged, 285 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 48 PR(s), 285 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Linked issue satisfaction

Addressed
The diff adds the isConfirmedRequired helper exactly as prescribed and switches the third-party action_required branch to use it instead of isRequired, while leaving isRequired's CI-failure fail-safe untouched, and includes regression tests for both the confirmed-empty Set and null origins of #4812's scenario. This directly satisfies all four listed deliverables, with the only unverifiable claim b

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 48 PR(s), 285 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 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.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 10, 2026
@JSONbored
JSONbored merged commit 2d6377c into main Jul 10, 2026
11 checks passed
@JSONbored
JSONbored deleted the fix/ci-third-party-action-required-no-branch-protection-4735 branch July 10, 2026 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(github): third-party action_required check still auto-closed a PR on a repo with no branch-protection required contexts (#4812)

1 participant