docs(contributing): document the merge gate and the never-arriving-check trap - #941
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Contributor
blove
force-pushed
the
blove/ci-gate-docs
branch
from
September 1, 2026 22:38
9ec6103 to
0f96d2d
Compare
blove
enabled auto-merge (squash)
September 1, 2026 22:38
Contributor
…eck trap On 2026-09-01 Vercel consolidated its commit-status contexts from one per project (`Vercel – threadplane`, `Vercel – threadplane-minting-service`) to a single `Vercel`. Branch protection required the literal old string, so the required check stopped arriving and every PR became permanently unmergeable while showing all checks green — `MERGEABLE` + `BLOCKED`, indistinguishable from a slow queue. That cost a lot of confused debugging, and the diagnostic is one API call once you know to make it. Adds a "The merge gate" section covering: - what the single required check is (`CI — required`, the `required-pr-checks` job, app-pinned to 15368, strict), and that `approve` must never join it; - why the gate is a job we own rather than a vendor status string a third party can rename out from under us; - the diagnostic — diff the contexts posted on the head SHA against the contexts protection requires — including the check-runs/statuses API split that makes `CI — required` absent from `/status`; - the pre-2026-09-01 protection config as a rollback reference, since branch protection is not version-controlled and needs an admin token to read. Deliberately no CI guard asserting protection matches the file: reading branch protection needs `administration: read`, which the workflow `permissions:` key cannot grant, so it would require a long-lived admin PAT in Actions secrets. That credential is a worse risk than the drift it catches. Reasoning is recorded in the section so the next person doesn't re-derive it. Verified against the API while writing: f927124 carries the two old contexts (minting-service failing), a8a603f carries the single `Vercel`, and `CI — required` is a check run from app 15368. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Reviewed 2026-09-01. States the residual gap plainly — a Vercel-environment- specific failure is not caught pre-merge, only post-merge by `Deploy → Vercel` — and why requiring the status back was rejected: the consolidated `Vercel` context now covers every project, so it would let an unrelated project block a pure-website PR, reversing the #931 behaviour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
blove
force-pushed
the
blove/ci-gate-docs
branch
from
September 1, 2026 22:48
0f96d2d to
409a86e
Compare
Contributor
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.
On 2026-09-01 Vercel consolidated its GitHub commit-status contexts — from one per project (
Vercel – threadplane,Vercel – threadplane-minting-service) to a singleVercel. Branch protection required the literal old string, so the required check stopped arriving and every PR became permanently unmergeable while showing all checks green.It presented as
mergeable: MERGEABLE+mergeStateStatus: BLOCKED, which is indistinguishable from a slow queue or a GitHub cache quirk, and never resolves on its own. That cost a lot of confused debugging for what is one API call once you know to make it.What this adds
A "The merge gate" section in
CONTRIBUTING.md:CI — required(therequired-pr-checksjob), app-pinned to 15368,strict: true— and thatapprove(fromauto-approve.yml, which exists only to give Scorecard's Code-Review check a review to read) must never join it.CI — requiredis safe to gate on — it'salways()-gated so it posts on fork PRs, and it isn't vacuous.gh apicalls. Includes the check-runs-vs-statuses API split —CI — requiredis a check run, so it does not appear in/statusoutput, which is its own trap when eyeballing the two lists.On the CI guard
The brief asked me to judge whether a CI assertion that protection matches a committed value is worth it. It isn't feasible without a new credential, and I don't think that trade is worth making:
administration: readscope. The workflowpermissions:key has no such scope —GITHUB_TOKENcannot be granted it — so a guard requires a long-lived admin PAT in Actions secrets.GET /repos/{owner}/{repo}/rules/branches/mainreturns[](verified).An admin PAT's blast radius is worse than the drift it would catch, especially now that the drift is loud once the diagnostic is written down. The reasoning is recorded in the section so the next person doesn't re-derive it.
Verified while writing
f9271249→["Vercel – threadplane" (success), "Vercel – threadplane-minting-service" (failure)]a8a603f9→["Vercel"]CI — requiredona8a603f9→ check run, app id15368required_status_checks→strict: true,checks: [{context: "CI — required", app_id: 15368}]rulesets→0;rules/branches/main→[]Docs only, no behavior change.
🤖 Generated with Claude Code