← The ADLC library
Foundations · 8

Autonomy versus control is a false binary

The choice everyone thinks they face is how much to let agents do. The actual choice is how much you can verify, and it is verification, not restriction, that buys autonomy.

The argument happens in every engineering organisation that has got serious about agents, usually about four months in, usually in a room with a whiteboard.

One side wants to open it up. Let agents pick up tickets, open pull requests, run the tests, iterate. The productivity case is obvious and the people making it are usually the ones who have been doing exactly this on their own work for a while and can point at results.

The other side wants guardrails. Restricted repositories, human approval on every merge, no autonomous action on anything touching production, an allowlist of what agents may modify. They are not being obstructive. They have thought about what happens when it goes wrong and they do not like the answer.

Both sides are arguing about a dial. The dial runs from “locked down” to “let it run,” and everyone in the room believes the question is where to set it. The debate is about a number.

The dial does not exist. Or rather, it exists, but it is the wrong instrument, and the reason the argument never resolves is that both sides are right about a system that has no verification layer, and both would change their position immediately in a system that has one.

The real variable

Here is the reframe. Ask what actually makes autonomy dangerous.

It is not that the agent acts. Your CI system acts. Your autoscaler acts. Your dependency bot opens pull requests. Nobody is arguing about those, and the reason is not that they are less capable. It is that when they do something, you can tell what they did, you can tell whether it was right, and you can undo it.

Autonomy is dangerous exactly to the extent that its results are unverifiable and its actions are irreversible. That is the whole thing. Those two properties, not the amount of independence, determine the risk.

Which means the dial everyone is arguing about is derived rather than fundamental. How much autonomy you can safely allow is a function of how much you can verify and reverse. Set those two and the safe level of autonomy falls out. Argue about the level directly and you are arguing about a symptom.

This is why the whiteboard debate never converges. Both camps are reasoning correctly from the same missing premise. In a system where you cannot check outcomes and cannot cleanly undo, the restrictors are simply right: broad autonomy is reckless. And in that same system the accelerators are also right that the restrictions are arbitrary, because a human approving forty pull requests an hour is not verification either. It is theatre with a name on it.

Checkable and reversible

Most code changes. Autonomy is close to free here and restricting it buys almost nothing.

Checkable, irreversible

You can confirm it was right, but not undo it if it was not. Gate on the check, then act.

Unverifiable, reversible

You cannot tell if it worked but can undo it. Tolerable with detection and a fast revert.

Unverifiable and irreversible

Sends, deletes, charges, publishes. No amount of model quality makes this safe.

The dial everyone argues about is derived from these two axes. Set verification and reversibility and the autonomy question answers itself.

What each side gets wrong

The restrictors mistake human approval for verification. This is the deep error, and it is comfortable because it looks like diligence. A required human sign-off is a control in the same way a signature is a control: it establishes who is accountable, and it does not establish that anything was checked. When the queue is short and the reviewer is fresh, the two coincide. When the queue is long, they come apart completely, and nothing in the process notices, because the artefact produced (an approval) looks identical in both cases.

So the restrictive posture often delivers less actual safety than it appears to, while imposing its full cost. You get the slowdown for certain and the assurance only sometimes.

The second thing restrictors get wrong is subtler. Restrictions push work into the shadows. If the official path is slow and the unofficial path is an engineer running an agent locally and committing the output under their own name, you have not prevented autonomous work. You have made it unobservable, which is strictly worse than the thing you were afraid of. This is not hypothetical, it is the predictable response of competent people to a process that gets in their way, and it is what heavy-handed policy reliably produces.

The accelerators mistake reversibility for safety. “We can always roll back” is true of the code and false of everything the code touched. Emails sent. Webhooks fired. Data migrated. A schema change that dropped a column. Customer-visible behaviour that someone acted on. Git makes code reversible and does not make consequences reversible, and the gap between those two is where the genuinely bad outcomes live.

The other accelerator error is treating the model’s confidence as evidence. Output that is fluent, well-structured and includes a convincing explanation of why it is correct is exactly what you get whether or not it is correct. Human work carried a rough correlation between confidence and competence, and years of professional instinct were built on that correlation. It does not transfer, and the transfer failure is invisible because everything still looks the same.

What restrictors get wrong

  • Human approval mistaken for verification
  • It is accountability, and only assurance when reviewers have time
  • Full cost of the slowdown, partial safety
  • Restriction pushes work into shadow tooling

What accelerators get wrong

  • Reversibility of code mistaken for reversibility of consequences
  • Emails sent, webhooks fired, data migrated
  • Model confidence mistaken for evidence
  • Fluent and wrong is the expected failure shape
Both camps reason correctly from the same missing premise, which is why the argument runs for months without resolving.

The trade you actually control

If autonomy is a function of verification, then the productive question in that whiteboard meeting is not “how much do we let it do.” It is “what can we currently check, mechanically, without a human.”

That question has a real answer, and the answer is usually a specific and slightly embarrassing list. Tests pass. Types check. Lint is clean. No secrets committed. Coverage did not fall. Maybe a performance budget. Maybe a security scan.

Now look at what is on that list and what is not. Everything on it is a check that the change did not break something. Almost nothing on it checks that the change does the thing that was asked. That is the gap, and it is the entire reason autonomy feels frightening. You have a machine that can produce a change which passes every check you own and still does the wrong thing, and no automated way to notice.

So the path to more autonomy is not a policy decision. It is closing that gap, one piece at a time. Every acceptance criterion you make machine-checkable moves a decision out of the human queue permanently. Every irreversible action you put a real gate in front of shrinks the blast radius. Every automated change that lands with a signed record of what was changed, by what, on whose authority, converts an unknowable event into an auditable one.

What we can check mechanically today:
  tests pass          types check         lint clean
  no secrets committed                    coverage held

What none of those establish: does this do the thing that was asked for?

Everything on the first list checks that the change did not break something. Almost nothing checks that it does what was requested. The gap between those two lists is the exact amount of autonomy you cannot safely grant.

Do enough of that and the autonomy question answers itself, quietly, without a meeting. The agent can act freely in the region where outcomes are checkable and consequences are reversible, and that region grows as you invest in it. This is the actual design of a control layer, and it is what GroundTruth is built to be: not a brake on agents, but the thing that makes taking the brake off defensible.

Two categories worth separating

One distinction that makes the whole conversation easier, and it is the one both camps usually skip.

Reversible actions with checkable outcomes. Most code changes. A pull request that fails its criteria can be closed. A merge that turns out wrong can be reverted. This region should be as autonomous as you can make it, and the argument for slowing it down is almost always weaker than it feels.

Irreversible actions, or actions with unverifiable outcomes. Anything that sends, deletes, migrates, charges, publishes or changes something a customer already saw. Here, autonomy is genuinely a different kind of decision, and no amount of verification makes an unsendable email sendable-back. These need a human in the loop, and crucially a human with time, which means the first region needs to be autonomous enough to free that time.

Most organisations treat these two as one category and apply a uniform policy, which is why the policy is simultaneously too slow for the first and too loose for the second. Splitting them is cheap and it dissolves most of the argument.

Where this breaks down

Now the objections, and the first one is the strongest thing anyone has said to me on this subject.

Some of the most important properties are not mechanically checkable, and probably never will be. Whether an abstraction is right. Whether a change makes the system harder to reason about. Whether this pattern will be a problem in eighteen months. If you follow my argument literally, you would grant autonomy in exactly the region where checks exist, and the checkable properties are the shallow ones. A codebase could pass every automated gate on every change and still degrade steadily in every way that matters. My framing does not solve that. It reallocates human attention toward it, which is the best I can honestly claim, and it depends on people actually spending the freed attention on architecture rather than on more tickets.

Verification cost is not free and I have implied it is. Making criteria machine-checkable takes real work, and for a change that will be made once and never touched again, that work exceeds the value. There is a break-even, it varies by codebase, and a rule that says “make everything checkable” is as wrong as a rule that says “let it run.” The judgement about where the line sits is itself unautomatable, which is a slightly uncomfortable place for this argument to land.

Reversibility is more theoretical than teams believe. I said code changes are reversible. In a system with schema migrations, cached state, feature flags, downstream consumers and events already published, a revert of the code is not a revert of the world. If your architecture makes rollback genuinely hard, the region I called safe is smaller than I described, and the honest first move is to fix your rollback story before touching your autonomy policy.

And there is a governance dimension I have skated over. In regulated environments, the requirement is often not “the outcome was verified” but “a named human accountable person approved this.” That is a legal fact, not an engineering one, and no amount of superior verification satisfies it. You can make the approval better-informed and faster, and you cannot remove it. If that is your world, the binary is less false than I have argued, because one end of it is fixed by something outside your control.

The takeaway

The autonomy dial is not the real control. Autonomy is safe exactly where outcomes are checkable and actions are reversible, so the question that produces progress is not how much to allow but what you can currently verify.

Human approval is not verification, it is accountability, and the two only coincide when reviewers have time. Reversibility of code is not reversibility of consequences. Separate the reversible-and-checkable region from the irreversible one, make the first as autonomous as you can, and put your scarce human attention on the second.

The next piece goes back further than any of this, to the thing the whole series is named after. Every team has a development life cycle whether or not anyone designed it, and the ones nobody designed are the ones that break first under speed.