Every team building deployment automation arrives at the same sentence: "of course there is a human in the loop."
Then you watch what actually happens. A pipeline posts a diff to Slack. Someone clicks approve within about eleven seconds. The change ships. That loop contains a human in the way that a turnstile contains a security guard.
This is not a discipline problem, and telling people to read more carefully does not fix it. It is a design problem, and it gets worse rather than better once an AI agent is generating the changes, because volume goes up and the reviewer's context goes down.
So: where should the human actually be, and what should they be doing when they get there?
Why does "human in the loop" mean so little by default?
Because the phrase describes a position, not a job.
A gate placed without a decision attached to it degrades in a predictable order. First it is genuinely useful, because the system is new and things break. Then it is mostly noise, because the same change type has passed forty times. Then it is reflex. Nobody decides to stop reading; the base rate of "this was fine" just climbs until reading stops being worth it.
The tell is simple and worth measuring: when did an approver last say no? If the honest answer is "I cannot remember", the gate is not a control. It is an audit log with an extra step, and you are paying deployment latency for it.
That does not necessarily mean delete it. An audit log has value. But you should know which one you own, because you are currently paying for a control and receiving a log.
What is the human actually checking?
This is the question that makes a gate real, and most pipelines never answer it explicitly.
There are only a few things a person can check that a machine cannot:
Is this the right change at all? Machines verify that a change is valid. They cannot tell you the ticket was misunderstood, or that the feature was descoped last week and nobody updated the issue.
Is now the right time? A correct change during a payments freeze, an incident, or the hour before a demo is still the wrong change. Calendars, incidents and organisational context are the things a pipeline genuinely does not have.
Is the blast radius acceptable? Not "is this valid" but "if this is wrong, what happens, and can we get back?" A person who knows the system answers that in seconds. Nothing in the pipeline can.
Does this look like something we do? Pattern recognition against the last two years of changes. It is the least articulable check and frequently the most valuable one.
Everything else on a typical review checklist is better done by a machine. Formatting, policy compliance, whether the plan applies cleanly, whether tests pass, whether the tags are present: all of these are faster, cheaper and more reliable in CI. Every one of them you leave to a human is attention taken from the four things above.
If your approval step is mostly checking things a linter could check, the gate is in the wrong place and pointed at the wrong target.
Where should the gate sit?
Three candidate positions, and the trade-off is the same each time: earlier is cheaper to reject, later is more accurate about what will happen.
At intent, before any work. Cheapest possible rejection, because nothing has been built. Also the weakest, because nobody can see consequences yet. Worth having when the work itself is expensive.
At the proposed change, before apply. The pull request with the plan attached. This is the right default for infrastructure: the change is concrete, the plan says exactly what will happen, and rejecting costs only the generation. Everything below assumes this position.
After apply, before traffic. Canary and progressive rollout. This catches what neither of the earlier gates can, because the change is now real and observable. It is also the most expensive place to be wrong.
Most teams need two of these, and reach for all three. The question to ask about each one is whether it is checking something the others cannot.
What makes an approval real rather than a rubber stamp?
Four properties, and the first one carries most of the weight.
The approver can see the consequence, not the cause. A diff of Terraform is the cause. A plan is the consequence. "3 to add, 1 to change, 1 to destroy" is a sentence someone can act on; forty lines of HCL is a document they have to compile in their head. Put the plan in front of them, and put the destroy count where they cannot miss it.
Rejecting is as easy as approving. If approve is a button and reject means writing a paragraph explaining yourself in a thread, you have priced one option out of the market. People are strategic about effort; they will approve and mention their doubt verbally, which is the worst of both.
The approver is not the author. Obvious, routinely violated at 6pm. Enforce it in the tool rather than the culture, because at 6pm the culture loses.
The gate is scoped to what is risky. A gate on everything is a gate on nothing, because volume is what kills attention. Which brings us to the actual lever.
How many gates is too many?
The failure most teams have is not too few gates. It is too many gates all checking the same thing.
Symptoms worth recognising: the same person approves at two different stages. An approval that has never once been rejected after the previous one passed. A gate everybody knows to click through because "CI already checked that."
Each of those is latency with no decision attached.
The better shape is a small number of gates with genuinely different questions:
- Machine gate: is this valid, compliant, and does it apply cleanly?
- Human gate: is this the right change, now, and is the blast radius acceptable?
- Observation gate: now that it is real, is it behaving?
Three checks, three different questions, no overlap. Adding a fourth is only worth it if you can name a question the other three do not ask.
What about the change that has to ship at 3am?
Every gate design meets this eventually, and the honest answer is that you need a break-glass path.
The mistake is treating it as a failure of the design. A system with no emergency path gets one anyway, informally, and the informal one has no logging.
What makes a break-glass path acceptable:
- It is louder, not quieter. Using it pages someone, posts in a channel and writes a record. The cost moves from before the change to after it.
- It expires. A temporary elevation that lasts an hour, not a permanent role somebody accumulated during an incident in March.
- It is reviewed after the fact, ideally as a standing agenda item. A break-glass used four times a month is not an emergency path, it is your actual process, and the gate it bypasses needs redesigning.
Does an AI agent generating the change alter any of this?
The structure holds. Two things shift, and both make the earlier points sharper rather than obsolete.
Volume goes up. An agent proposes changes faster than a person, which means a fixed pool of reviewer attention is now spread across more changes. If your gate was already marginal at ten changes a week, it will not survive fifty. This is the argument for machine gates absorbing everything they can: not because review is unimportant, but because reviewer attention is the scarce resource and you cannot buy more of it.
Reviewer context goes down. When a person writes the change, they carry the reasoning. When an agent writes it, the reviewer is reading someone else's work cold. This makes "the approver can see the consequence" more important, not less, and it makes a stated intent alongside the change genuinely valuable: not "here is the diff" but "here is what was asked for, and here is the plan that resulted."
What does not change: the gate belongs in the same place, checking the same four things. An agent that opens a pull request inherits the review process you already have. An agent that applies directly does not have one, and no amount of prompt engineering substitutes. That distinction is worth more than any model capability claim.
What does a good gate look like in practice?
Concretely, for an infrastructure change:
- Machine first, and exhaustively. Format, validate, policy check, plan. Fail before a human sees it. A human should never be the first thing to notice a syntax error.
- Summarise the consequence at the top. Counts of add, change and destroy, and the destroy list in full. Not a link to logs. The summary is the artefact under review.
- Escalate on destroy. A plan with zero destroys and a clean policy check is a different risk class from one that replaces a database. Treat them differently, automatically. Detecting that reliably is mechanical, so make the machine do it.
- One human, not the author, with the authority to say no and no social cost for using it.
- Then observe. The gate that catches what review cannot is the one after the change is real.
None of that is novel. It is just rarely written down, which is why it drifts.
The short version
A gate is worth its latency only if the person standing at it can plausibly say no. Everything else in this post is downstream of that.
Measure the one number: when did an approver last reject something? If the answer is embarrassing, you do not have a broken team. You have a gate asking a question nobody needed answered, and the fix is to move it, narrow it, or delete it and stop pretending.
DevLift generates infrastructure changes and opens a pull request rather than applying them, so the plan is the artefact under review and your existing approval path runs unchanged. Book a walkthrough, or read what has to be true before an AI agent touches production.