Start With the Contract
The mistake in advanced agent automation is designing the loop around the model’s next thought. Design it around the harness. A useful loop contract has four parts: trigger, executable skill, verifier, and durable output. The trigger decides when work begins. The skill constrains how work is done. The verifier decides whether the loop may stop. The output records what changed, what passed, what failed, and what state the next run inherits.
This contract matters because overnight autonomy is mostly a state-management problem, not a prompting problem. A human prompt can tolerate ambiguity because the human is still present to redirect. A loop cannot. If the trigger is vague, it runs at the wrong time. If the skill is not executable, the agent improvises. If the verifier is subjective, it burns tokens trying to satisfy a moving target. If output is not durable, the next iteration pays again to rediscover the same facts.
Write the contract before writing instructions. For a code agent, that may be: on PR creation, check out an isolated branch, run the refactor skill against files matching a dependency graph slice, run tests plus typecheck plus a spec evaluator, then persist a patch, logs, token usage, verifier results, and a short failure summary. The model is not the loop. The loop is the system that decides when to call the model, what context to give it, how to judge it, and when to stop calling it.
Make Skills Executable
Once the contract exists, the execution phase should become a skill, not a bag of advice. A skill is a procedure the harness can invoke repeatedly with bounded inputs: inspect these files, modify only this surface, preserve these invariants, run these commands, report in this schema. Store it outside the schedule or event configuration so the routine can improve without changing how it is triggered.
The higher the autonomy target, the less prose the skill should leave unresolved. Include repo rules, tool permissions, allowed commands, forbidden paths, expected intermediate artifacts, and rollback behavior. Put architectural memory in project files such as `claude.md` or equivalent, but keep run-specific state out of the prompt. Use markdown for lightweight memory when that is enough. Use Postgres or another external store when runs must be resumable, queryable, or coordinated across agents.
Do not ask the model to perform deterministic orchestration. Let code enumerate changed files, compute dependency cones, allocate work units, create worktrees, branch databases, collect logs, enforce timeouts, and meter cost. Let the model reason where ambiguity is real: interpreting intent, planning a local change, deciding between implementation strategies, and explaining verifier failures. The harness should be boring where correctness is mechanical and agentic where judgment is useful.
Verifier First, Then Loop
After the skill is executable, the verifier becomes the real definition of done. Strong loops terminate on objective signals: tests pass, benchmark latency drops below a threshold, lint and typecheck are clean, migration applies, endpoint returns the expected schema, or a numerical score improves. These are cheap, repeatable, and hard for the model to rationalize around.
Some projects need model-based verification, but treat it as a second-class verifier unless you can constrain it. Give the evaluator a spec, a rubric, and a binary or scored output. Better yet, pair it with deterministic evidence: test output, logs, screenshots, traces, diffs, benchmark tables. A verifier that says “looks good” is not a verifier. A verifier that says “fails requirement 3 because the API accepts invalid enum values; repro command attached” is loop fuel.
Run new loops in training mode before trusting them overnight. Pause after trigger expansion, after plan generation, before edits, before commit, and before any external write. Every manual correction should become a harness change: a rule, pre-tool hook, verifier check, fixture, denylist, or memory entry. If a loop repeatedly makes the same class of mistake and you only adjust the prompt, you are leaving reliability inside the weakest part of the system.
Parallelize With Isolation
Once verification is credible, scale throughput by splitting the loop into focused sessions instead of stretching one context window. Planning, implementation, and validation should often be separate agent runs with explicit artifacts between them. The planner writes a scoped plan and acceptance criteria. Implementers consume one work packet each. Validators run fresh, with less conversational baggage, and judge the result against the contract.
Parallelism only works if isolation is real. Use separate git worktrees or branches per agent. If the app depends on state, give each run a branched database or disposable environment. Namespace temp files, ports, queues, and caches. Make merge arbitration deterministic where possible: one owner per file slice, generated patch bundles, explicit conflict handling, and a final integration verifier that runs from a clean checkout.
This is also where memory design changes. Context memory helps a single agent avoid repetition, but fleet memory needs structure. Store run records with task id, trigger, model, skill version, input hash, files touched, commands run, verifier outcome, cost, duration, and final artifact. That data lets you answer operational questions: which skill versions regress, which verifiers flap, which model is wasting tokens, which file areas cause repeated failures, and which loops should be killed rather than tuned.
Route Models, Cap Cost
With trigger, skill, verifier, and output in place, model routing becomes an engineering decision rather than a preference. Use cheaper models for classification, queue triage, file selection, summarization, and simple plan validation. Reserve stronger models for ambiguous implementation, architecture tradeoffs, and failures that require synthesis across code, logs, and spec. The harness should choose the model per step, not per project.
Cost control must be part of the stop condition. Set iteration caps, wall-clock caps, token budgets, retry budgets, and escalation thresholds. Persist partial progress before each expensive phase. On verifier failure, feed back the smallest useful packet: failing command, relevant diff, narrowed logs, and acceptance criteria. Do not rehydrate the full conversation unless the failure actually needs it.
The mature version of loop engineering is not “let the agent keep trying.” It is a contract-driven harness that spends model reasoning only where reasoning has leverage. The trigger starts the right work, the skill makes execution repeatable, the verifier prevents self-deception, and durable output lets the system learn across runs. Design those four pieces first, and the loop can run longer without becoming less predictable.
Key takeaways
- Specify every loop as a four-part contract: trigger, executable skill, verifier, and durable output.
- Push deterministic work into code: orchestration, isolation, command execution, state storage, retries, and cost limits.
- Use model reasoning for ambiguity, not for bookkeeping or checks a script can perform exactly.
- Treat verifier design as the definition of done; weak verification is the usual cause of expensive infinite loops.
- Parallel agents need isolated worktrees, isolated state, and structured run records before they can scale safely.
- Every repeated agent failure should become a harness rule, hook, fixture, verifier, or memory update.