How it works
An execution limit sits outside the model’s reasoning and counts some finite resource consumed by a run. The harness checks that counter before or after each controlled transition. When the configured boundary is reached, it takes a predetermined action instead of asking the model whether it should continue.
A typical control sequence is:
- Initialize counters and deadlines from the run contract.
- Allow one model turn, tool call, retry, or workflow transition.
- Record the result and update the relevant counters.
- Test each counter against its limit.
- Continue, checkpoint, escalate, or stop according to policy.
Useful limits include wall-clock duration, loop iterations, tool calls, retries per operation, total retry attempts, tokens, and cumulative cost. These controls cover different failure modes. A step limit catches circular reasoning. A retry limit contains a failing dependency. A time limit catches blocking operations that may not advance a step counter.
The terminal action matters as much as the number. A safe limit can produce a resumable checkpoint, a partial result marked incomplete, or a failure requiring operator review. It should not silently label unfinished work as successful. If the outcome of the last action is uncertain, the harness must preserve that uncertainty rather than retrying blindly.
Why it matters in an agent harness
Agents can continue producing plausible next actions after useful progress has stopped. A model may reformulate the same plan, alternate between tools, retry an unavailable service, or keep searching because it lacks enough evidence to declare completion. Without an external bound, the loop’s willingness to continue becomes the system’s operating policy.
Execution limits turn open-ended delegation into bounded authority. They give the operator a defensible answer to a basic question: how much work can this run perform before control returns? That boundary limits resource consumption, but its larger value is failure containment. A confused or poorly instructed agent cannot keep acting forever merely because each individual action remains permitted.
Limits also improve observability. A run that repeatedly exhausts its search budget signals a different defect from one that repeatedly reaches its retry ceiling. The first may have an inadequate stop condition or weak evidence criteria. The second may indicate an unavailable dependency or non-idempotent operation. Recording which limit fired, along with current counters and the last confirmed state, makes those cases distinguishable.
Reversibility depends on what happens at the boundary. Read-only exploration can often stop immediately. A run that mutates external state may need to finish an atomic operation, verify its outcome, or record a compensating action. A wall-clock timeout that kills execution during a write can create an unknown outcome: the harness no longer knows whether the operation completed. For consequential tools, pair limits with idempotency keys, execution journals, and durable checkpoints.
Limits should be scoped to the work. A single global ceiling is easy to configure but often hides where capacity was spent. Per-tool, per-phase, and per-retry limits expose the structure of the run and prevent one activity from consuming the entire allowance. The global limit remains useful as the final containment boundary.
Execution limit vs stop condition
Both mechanisms end runs, but they answer different questions. A stop condition asks whether the intended work is complete. An execution limit asks whether the system is still allowed to keep trying.
| Design axis | Execution limit | Stop condition |
|---|---|---|
| Trigger | A measurable allowance is exhausted | A completion or termination state is detected |
| Main purpose | Contain cost, time, and authority | End work at the correct semantic point |
| Typical implementation | Deterministic counter, deadline, or budget check | Workflow state, verifier result, or policy decision |
| Meaning when fired | The run used its allowance | The run completed, failed, or became inapplicable |
A healthy harness uses both. A strong stop condition avoids unnecessary work under normal operation. An execution limit contains cases where that condition is unreachable, incorrectly implemented, or repeatedly disputed by a non-deterministic model. Reaching the limit should therefore be recorded as a distinct terminal reason, not treated as ordinary completion.
The Rifty take
We treat execution limits as authority boundaries, not cost-tuning knobs. We accept that a useful run may stop incomplete because bounded, legible failure is safer than invisible overrun. The boundary must return enough state to explain what happened and support a deliberate resume, escalation, or rollback.
Implementation checks
- Define limits in the run contract rather than relying on prompt instructions.
- Cover at least iterations, retries, tool actions, and elapsed time where each can fail independently.
- Specify the terminal action for every limit: stop, checkpoint, escalate, or compensate.
- Record the limit name, configured value, observed value, and last confirmed state.
- Keep limit exhaustion distinct from successful completion and content-level rejection.
- Use per-phase or per-tool budgets when one activity could starve the rest of the run.
- Test boundary values, including the final permitted action and the first forbidden action.
- Treat interrupted writes as potentially unknown outcomes until verified.
- Require an explicit policy decision before increasing a repeatedly exhausted limit.
Frequently asked questions
Which execution limits should an agent run have?
Most production runs need limits on loop iterations, elapsed time, tool actions, and retries because each contains a different failure mode. Add token, cost, or phase-specific budgets when those resources affect operations. The correct set follows the run’s tools, side effects, and recovery requirements.
Should reaching an execution limit count as a failure?
Reaching an execution limit should be a distinct terminal outcome, not automatic success. Whether the surrounding job treats it as failure, escalation, or resumable interruption depends on the contract. The artifact must still state that work ended because an allowance was exhausted rather than because completion was verified.
How should a harness choose the limit value?
Choose the value from the expected workflow shape, the maximum acceptable blast radius, and observed run traces. Leave enough room for normal variance without accommodating persistent loops. If valid runs regularly hit the boundary, inspect the workflow and stop condition before simply raising the limit.
Can a prompt instruction replace an execution limit?
No. A prompt can tell the model to stop after a number of steps, but the model remains responsible for interpreting and obeying that instruction. A reliable execution limit is enforced by the harness with counters, deadlines, or budgets that the running model cannot silently ignore or redefine.
How should execution limits work with external writes?
Limits around external writes must preserve outcome certainty. Do not terminate an in-flight mutation and assume it failed. Record the invocation, use idempotency where available, and verify the resulting state before retrying. If verification is impossible, surface an unknown outcome for deliberate recovery.