Agents review, fix, merge and release. Every loop in this series ends at the same place: a merge.
What makes that merge safe isn’t the agent pressing the button. It’s what the platform refuses to merge.
In zero-eyes approval, agents review each other until the review is clean, then the PR merges. That assumes the merge itself checks something.
Auditing our seven SDK repos, we found that it didn’t always. main required CI. Some stable/* branches required nothing, so our merge agent could merge a converged PR into a stable branch while CI was red.
The agent did nothing wrong. It merged what the branch allowed it to merge.
main: required checks in the rulesetstable/*: no required checksSame agent, same PRs, same CI. Red squares are PRs with failing CI.
Rules that enforce themselves stops at “blocked in CI”. But a failing job only blocks anything if the branch’s ruleset requires it. Otherwise it’s a red mark next to a merged PR.
And a required check can still be hollow. One of our SDKs required a generation-drift job that had continue-on-error: true. It was always green, because it couldn’t fail.
A gate that fails at random is hollow too. People learn to re-run it, then to ignore it. That’s why there are no flaky tests: our PHP SDK’s “random” red turned out to be an uncached, unretried download.
continue-on-error, || true, a step skipped by a condition. Looks like a gate. Isn’t.Teams protect main carefully. Release branches get whatever was set up the day they were cut, and nobody looks again.
Rulesets, auto-merge, the dependency bot, how releases are triggered: none of it lives in the repo, so none of it is derived or checked for drift. Seven SDKs generated from one spec had grown seven different safety setups.
The fix is the same as for code: pick the source of truth (here, the three most mature SDKs), audit every repo against it, and converge.
Simplified from our audit of the orchestration-cluster-api-* repos. “After” counts changes that are in open PRs.
Renovate opens a fix(deps) PR. Required checks run, including a dependency review that blocks high and critical advisories. If everything is green, the PR auto-merges, and semantic-release turns the fix into a patch release on main and on every supported stable/* branch.
That’s the goal of zero eyes: hours from advisory to published patch. But it’s only safe because every gate in it is real. Take one out and watch what the same loop does.
fix(deps) PRfix → patchTwo of our SDKs only released when someone pushed a tag by hand, and four had never had the dependency bot installed. For those, the loop simply stopped partway. That’s safe, but the fix never ships.
Rulesets, app installs and org-wide security settings need admin rights. That’s deliberate: an agent that can change the rules of the merge can merge anything.
So the agent does everything up to the permission line: the audit, the exact new ruleset, the PRs it depends on. Then it opens an issue a human can apply in one step and check in one look.
“Please improve branch protection” sits in a backlog. “Run this command, here’s why” gets done.
Require the checks that matter, on every branch you release from. Make sure each one can actually fail. Treat repo settings like code: one reference, audited and converged across the fleet. Then let the loop run all the way to a release, with humans holding the keys to the gates.