The no-op merge guard only stops robots: make it block a human merge, via the aggregate required check - #219
Merged
Merged
Conversation
…-merge pass The guard from toon-meta#405 catches a PR whose merge result is empty, but it ran as a stand-alone shim - and a red NON-required check is a warning on the merge button, not a block. connector#1008, the empty merge it exists for, was merged by a human. Move it inside the workflow that computes this repo's one aggregate required check and make that aggregate assert on its result, so a red guard turns the required context red. Delete the now-redundant shim; running both would put two identical 'No-op merge guard' check runs on every PR. Deliberately NOT a second required context: a required context that can never appear wedges a repo permanently (swap#147 is in that state right now - a changesets Release PR whose runs sit at action_required, so its rollup is empty and the required context never reports). One required context per repo, before and after; no protection or ruleset setting touched. Part of toon-protocol/toon-meta#408 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ALLiDoizCode
enabled auto-merge (squash)
August 16, 2026 22:57
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.
The fleet no-op merge guard (
toon-meta#405) catches a PR whose merge result is empty —connector#1008merged green, closed its ticket, andgit showreturned zero files. But asshipped it only stopped robots: it ran in a workflow of its own, and a red non-required check
is a warning on the merge button, not a block. block#1008 was merged by a human.
This wires the guard into this repo's aggregate required check, so a red guard turns that
context red and branch protection refuses the merge. Ported from
toon-meta#408/toon-meta#409.What changed
ci.ymlgains ano-op-mergejob that callstoon-protocol/toon-meta/.github/workflows/empty-pr-guard.yml@main— the same reusableworkflow the shim called, now inside the workflow that computes the aggregate.
needs.no-op-merge.result..github/workflows/empty-pr-guard-shim.ymlis deleted. Running both would put two identicalNo-op merge guardcheck runs on every PR.Net effect on branch protection: none. This repo still has exactly one required context,
unchanged in name. No protection or ruleset setting was modified through the API.
Why through the aggregate rather than a second required context
Mainly because it is the smaller change — the required-context set is untouched, so the guard
cannot introduce a new way for this repo to become unmergeable. That mattered acutely earlier
today: a changesets Version Packages PR could sit at
action_requiredwith zero check runs,so its required context never reported and the PR was BLOCKED forever (
swap#147). That cause isnow fixed (
toon#208/relay#135/swap#149:actions/checkoutwas persistingGITHUB_TOKENinto
.git/config, so the changesets push triggered nothing;token:now falls back to the Apptoken, the org convention from
toon-client#467) andswap#147has recovered green — verified.So this is no longer load-bearing, but it costs nothing and keeps the blast radius of a guard
change at one context per repo.
Why a bare
needs:would not have been enoughWhen a
needs:dependency fails, GitHub reports the dependent job with conclusionskipped, andbranch protection treats a skipped required check as a pass. So the aggregate keeps
if: always()and asserts on the result explicitly.Why it is safe to require
The guard warns and passes wherever it cannot tell — a required check that fails on "I could not
tell" is how guards get disabled. Verified on a deliberately conflicted throwaway PR
(
toon-meta#407): GitHub does not dispatchpull_requestworkflows at all for a conflictedPR, so neither the guard nor CI even runs; the PR is blocked by its own conflict exactly as
before, and the guard cannot wedge it further. On
pushthe guard passes with a plain "no mergeresult to evaluate" — deliberately not a job-level
if:, because a skipped gating job must neverread as a pass (
toon-meta#279).Part of toon-protocol/toon-meta#408
🤖 Generated with Claude Code