> /writing/who-decides-what-your-agents-may-merge

Who decides what your agents may merge?

gtm engineering·7 min read·September 6, 2026

This post is one boundary of a five-boundary architecture. The map, and how the pieces work together, is in Deterministic controls for probabilistic systems.

An agent fleet can now write more code in a week than you can read in a month. The hard question stopped being whether the code can get written.

It became who decides that a given change may merge.

Two defaults dominate. Either a human reads every diff, which hands back the throughput the agents just bought.

Or the agent's own report gets accepted, a green suite and a confident summary, and unreviewed code walks into production wearing a success label.

Both defaults treat trust as a judgment call made fresh on every pull request. At fleet volume, judgment calls are exactly what you run out of.

What is the split that scales?

Probabilistic systems do the work. Deterministic systems decide whether the work may proceed.

The agents that build are probabilistic. So are the agents that review, and they should be, because finding a subtle bug takes the same kind of reading that writing one does.

The merge decision is different. It runs as a script, takes five pieces of evidence, and returns one verdict with its reasons named.

bash
node lib/lane-report.mjs --gate --repo my-service \
  --has-tests yes --tests-pass yes \
  --ship-check-passed yes \
  --ship-check-agent reviewer-1 --build-agent builder-1 \
  --scope-clean yes
# => AUTO-MERGE

Flip one input and it parks the change, and it tells you why.

bash
# => PARKED
#    - no tests in the build, so green means nothing ran
#    - ship-check ran as the build agent, so the lane blessed its own work

That second reason is the load-bearing one. The gate checks reviewer independence mechanically, so an agent grading its own work is a parked merge, never a fast one.

No model is consulted at the gate. A rule that can be sweet-talked sits with the judges, and the judges do not hold the merge button.

What did one measured week produce?

In the week of September 1st, twelve build lanes ran through this system in parallel.

Each lane held one agent, in an isolated worktree, bound to a spec commit and a test-first contract.

Twenty-two adversarial review gates ran across them, every verdict recorded in the repo it judged.

One public repo, gtm-architect, went from 138 tests to 1,264. I reran that suite while writing this, and 1,264 still pass. The repo is public, so you can run it too.

Two agents were killed mid-run by session caps. Zero work was lost, because every lane commits per test cycle and no work lives in a chat transcript.

One merge into a production repo was parked for a human. Zero merges auto-merged by mistake.

Out the other end came working tools, each hardened by the same review pressure.

A GTM strategy instrument at 1,264 tests. A PII gate at 151. A webhook engine at 140. And the review system itself, extracted at 131.

That last one matters for the story. The system that produced the tools was eventually run on itself, and the gate said no.

What mistakes should you skip?

The extract failed open, and its own gate caught it. When the review system was extracted into a standalone tool, the first version passed a malformed lane board instead of halting on it.

Failing open on bad input is the exact class the tool exists to prevent. Gate one blocked the merge and named the rows. The fix wave made it fail closed. Gate two blessed it.

A gate you built is not exempt from the gates you built. That inversion is uncomfortable and it is also the proof the system works on things its author likes.

Trusting the lane's green suite. A build agent reporting green is a claim, the same as a commit message or a README.

The reviewer contract requires watching the test actually fail at assertion level before the fix, because a suite that never went red proves nothing about what it guards.

Letting the work live in the conversation. The two killed agents cost nothing because worktree isolation and commit-per-cycle made the transcript disposable.

An agent whose progress exists only in its context window loses everything on a cap, a crash, or a bad tool call.

Letting the agent propose its own trust tier. The production-repo park happened because deterministic rules override whatever the agent classified its work as.

A misclassification can inconvenience a lane. It cannot escalate privilege.

How do you run it on your own lanes?

The gate and its parsers are public, MIT, zero dependencies, Node 18 or newer.

bash
git clone https://github.com/derrtaderr/ship-check.git
cd ship-check
npm test

The repo splits in two, and the split is honest. The gate engine is runnable, tested code. Clone it, feed it evidence, get a verdict.

The orchestration contract ships as templates and documentation, the dispatch procedure, the execution-agent contract, the reviewer contract, the fix-wave discipline.

The templates need an agent harness such as Claude Code to execute. Nothing in the repo pretends to run your agents for you. The documents are what you bind your agents to.

Start with the gate alone if you have even one agent opening pull requests. Independence and tests-went-red are checkable today, with no orchestration at all.

$ ship-check --repo redaction-gate \
    --has-tests yes --tests-pass yes \
    --ship-check-passed no \
    --ship-check-agent agent-7 --build-agent agent-7 \
    --scope-clean yes

## Merge gate, repo redaction-gate

PARKED
- ship-check did not pass
- ship-check ran as the build agent, so the lane blessed its own work

Both reasons print, not just the first. The second one is the load-bearing check: the same agent reviewed its own diff, and no verdict from that arrangement is worth anything.

What does this not do?

The gate is only as honest as the evidence fed to it, and the templates are methodology rather than software.

It does not replace CI. It sits above CI and decides what a green pipeline is allowed to mean.

It does not make the reviewers reliable. They stay probabilistic, which is why their verdicts are inputs to the gate instead of being the gate.

FAQ

Is this the same idea as your redaction gate? Same signature, different layer. The redaction piece argues a checker must be able to fail. This one puts the mechanical no above a whole fleet.

Why not just write better agent prompts? Prompts shape behavior and cannot bound it. The gate exists for the day the prompt fails, which is a day that arrives on a schedule nobody sets.

Do I need twelve lanes for this to pay off? One lane is enough. The self-blessing check and the tests-went-red rule catch real failures at N of one.

Isn't the human still in the loop? Yes, on purpose. The gate shrinks the human's queue to the parked changes, where judgment is actually needed, and it writes down why each one is there.

— jd

# discussion

"What in your pipeline can tell an agent no, and is it a model or a script?"