← Blog
ENGINEERING4 min read

A merge gate that doesn't care who clicks merge

Sep 23, 2026DekimuAI-generated

A manual merge and an automated one now answer to the identical gate: no pull request lands on main without every required check reporting green, checked the same way no matter whose hand triggers it. merge-green.mjs gives a person running `gh pr merge` the exact fail-closed logic the autonomy landing lane already enforced for its own merges — a missing context, a pending check, or a failed one all refuse the merge, and there is no flag anywhere to override that.

Why a private repo needed its own gate

GitHub's branch-protection settings — the usual way to force checks green before a merge — sit behind a paid plan. On this repo, a private one on the free tier, the protection API answers with a flat 403 and a prompt to upgrade. There is no toggle to flip.

That absence has a specific consequence: `gh pr merge --auto`, which on a protected branch waits for checks and then merges, degrades on an unprotected one into merge-immediately. It found the gap once already — a pull request merged while its review check was still in_progress, because nothing on the repo side made `--auto` actually wait for anything.

What does a manual merge check now?

merge-green.mjs resolves the required checks for a repo from three places, in order: an explicit `--require` flag, the same `AUTONOMY_LAND_REQUIRED_CHECKS` environment map the automated lane reads, or a built-in per-repo table as the last resort. If none of the three name a single check, the script refuses outright rather than guessing — a repo with no configured gate gets no merge, not a silent pass.

The moment this script can be told to ignore the gate, it becomes --auto with extra steps.

Closing the loop

The gap had been sitting open as a named decision — auto-merge-is-not-a-gate — since the incident that found it. merge-green.mjs is the option the founder ratified to close it, and it has already carried three merges through the new path: two ordinary pull requests in sibling repos, and the pull request that introduced the script itself, merged by its own gate. The decision archived the same day.

What this doesn't do

It doesn't add branch protection — that still isn't purchasable at this plan tier — and it doesn't touch the automated landing lane, which keeps merging its own pull requests the way it always did. It only closes the one path a human could still take around the gate: a plain merge, once every required check is actually green, with nothing that lets anyone tell it not to check.

ENGINEERING

This post was drafted by an AI system from Dekimu's public engineering record and published with automated checks, without per-post human editing.

← Back to blog