Loop engineering is the term of the season. Andrew Ng put it at the center of his newsletter, and the description is correct. Production AI systems are not one prompt and one answer. They are a cycle. The model acts, a tool runs, the result comes back, the model acts again.
Part 1 of this series called the model the brain and the engineering around it the harness. Part 2 showed three failures that wrote the rules.
This article is about the one piece the loop framing names and leaves undefined.
Who decides the work is finished.
Three loops, running at different speeds
Ng describes building software as three nested loops.
The inner loop is the agent coding loop. Seconds to minutes. The agent runs it. You give a specification, the agent writes code, tests its own work, and iterates.
The middle loop is the developer feedback loop. Tens of minutes to hours. You run it. You review what got built, steer it, and update the spec.
The outer loop is the external feedback loop. Hours to weeks. The world runs it. Real users, real traffic, real data.
The insight worth keeping is the asymmetry between them. The further out the loop goes, the more verification depends on human judgment instead of an automated check. The agent verifies its own code. Only a customer verifies whether the product is any good.
The map is good, and it stops one step short.
Every loop needs something with the authority to say no
A loop without a designed stopping point fails in one of two directions.
The agent spins. It keeps calling the tool, keeps re-reasoning, keeps working a task it will never finish, and every pass costs money.
Or the agent decides the work is finished and is wrong. This one is quieter and far more expensive.
Two failures from Part 2 were exactly this shape.
The GoviHub migration reported success. Ten tables had failed to create. Something inside the system said finished, and finished was false. We spent five days on the consequences.
The smoke test passed with curl -k. The flag skips certificate chain validation. The test confirmed the process was running. The product was unreachable by every strict TLS client, which is every real client. Something inside the system said finished, and the product took zero external traffic for days.
Both loops had a verifier. Both verifiers answered a question nobody needed answered.
The rule: the gate runs outside the model
This is the rule the rest of the article hangs on.
Claude Code does not mark its own homework. When the session tries to stop, a hook fires a script the model does not control. The script runs the checks. A non-zero exit puts the session back in the loop. The model is not consulted.
That single arrangement separates an agent reporting success from an agent producing proof. Everything else in our process sits downstream of it.
Nothing here is exotic. The gate is a script and an exit code. Boring is the point. The only property a gate needs is independence from the thing being graded.
What a gate has to say
"The tests pass" is not a gate. The same run wrote the tests and the code.
Our gates are written as the commands a real client runs.
Against the real host, never localhost.
Strict TLS, no -k flags, chain validated with openssl.
Authenticated with a real token.
A non-empty payload in the response, not a 200 status.
Table and row counts above a stated floor after any migration.
The rule underneath all five: if the gate does not reduce to a command, you do not have a gate. You have an opinion about whether the work is finished.
Writing the gates before the work starts is the discipline. It takes twenty minutes and returns more than any other twenty minutes in the process. A goal without gates is a wish. The same goal with four commands under it is a contract.
Three limits that keep the loop from eating you
A gate that never passes produces an endless run, so the gate needs limits around it.
A hard cap on passes. Stop after N and report, so an unreachable gate ends the run instead of running up the bill.
A time cap, for the same reason.
A blocked file. When a run hits a permission wall or a product decision, it writes the item to BLOCKED.md and continues the rest of the plan. It never stalls waiting for me. I hand off a goal and leave. Coming back to a paused session holding a question is a failed run, even when the answer takes five seconds.
Context is a budget, not a container
One more thing the loop framing gets right and most implementations get wrong.
Every pass appends to the context window. Tool results, intermediate reasoning, observations. Long runs degrade well before they reach the hard limit, because the window fills with stale tokens.
We run each pass as a fresh session reading a state file. Every pass starts clean and reads only the ledger and the goal. We adopted the pattern to stop mid-run stalls. The context benefit arrived free, and it turned out to be the larger of the two.
Where the human stays
The cost of verification decides where automation ends.
Cheap and reliable to check, the gate handles it. Table counts, TLS chains, HTTP status, row floors, build exit codes.
Expensive or subjective to check, a person handles it. In RegScope, our regulatory intelligence pipeline, two checkpoints are human by design. A compliance officer reviews uncertain entity matches before an assessment gets written. A senior reviewer approves the assessment before it publishes. Neither check has a cheap automated version, so neither one gets automated.
Deploy is the third. Every run in our process executes end to end without stopping, except the deploy step, which waits for me.
The humans do not disappear from the loop. They move to the places where judgment beats a script.
What this bought
Five intelligence systems in production, built and operated by one engineer.
An eval instrument whose release gate blocked its own release. Three real defects caught before shipping, each documented with a trace. That is the gate doing the only job it has, which is saying no to me.
And the number on the other side of the ledger. Five days lost on GoviHub, because nothing outside the model said no.
The loop is the easy part. Everyone has one now.
The gate is the part nobody ships, because it is boring, because it takes twenty minutes of thinking before any code gets written, and because its entire function is to tell you the work is not finished.
Build it anyway. Nothing else in the system will tell you the truth.
