A loop that cannot stop is an invoice
You're in the agent studio. What you're doing this lesson: give the AI helper a stop rule — a maximum number of steps and a maximum spend — so a stuck retry cannot become an invoice. You do not need to have shipped loops at work to start.
A loop here means: look at the failing job, try one action, look again, repeat. Without a stop rule, "again" never ends.
That's the triage helper from the last lesson, stripped of mystique: look at the state, pick one allowed action, check it, run it, write down the result, go again. A person deciding "try once more" is cheap. A model deciding the same thing, on a real API bill plus real CI compute (the automated tests that run when someone pushes code), with an exit condition of "the model feels done," is not.
The model does not reliably feel done. Here's the failure you'll actually see: job j-118 is red because a dependency registry is having a bad day. The agent reads the log, decides flake (a test that fails randomly), reruns. Still red — the registry is still down. Reads the log again. Same log. Reruns again. Every iteration looks locally reasonable; the run as a whole is a money fire. No single step is a bug you could point to in review. The bug is that nothing above the steps is counting.
The two caps, and why they're both mandatory
- Step cap. A hard ceiling on iterations. Triage should finish in six steps; a run at step seven isn't being thorough, it's stuck. The cap converts "stuck" from a silent state into a named outcome you can alert on.
- Cost cap. Steps aren't priced equally — reading a log tail is pennies, rerunning a job is compute. A run can be four steps long and still be too expensive if three of them are reruns. The cost cap meters dollars, not iterations, and fires before the overspending call runs, not after.
You need both. A step cap alone lets six expensive steps through. A cost cap alone lets forty cheap steps loop forever below the price ceiling. They fail differently, so they gate differently.
Stop reasons are part of the return value
The lazy loop returns its answer or nothing. Yours returns why it stopped, every time, as a short label from a closed set: plan-complete, step-cap, cost-cap. This is the same idea as an exit code on a program — "done" versus "killed" — and you'd never ship a service that couldn't tell you which.
The distinction earns its keep in the metrics, a week after launch. plan-complete trending down while step-cap trends up means your agent is getting lost more — maybe a prompt regression, maybe a new failure mode in the queue. cost-cap firing at all means some job class is eating reruns. You can only see the trend if the loop names the reason, and the loop can only name the reason if the caps are inside the loop definition — not a wrapper someone adds after the first incident, because by then the first incident has happened.