Level 3 · Loop Engineering

Turn Goals Into Verification Loops

Long-running agents become dependable when the loop is built around external evidence: explicit triggers, executable completion tests, review gates, proof artifacts, and hard stop conditions.

Start With The Trigger Contract

The central mistake in autonomous agent work is treating the agent's plan as the control system. For overnight loops, the harness must be the control system. The model can reason, edit, inspect, and propose, but the loop decides when work starts, what state is loaded, which tools are allowed, when progress is accepted, and when the run is killed.

Define the trigger as a typed contract, not a vibe. A manual goal, cron job, pull request event, failed health check, benchmark regression, or production log sweep should normalize into the same envelope: `goal_id`, repository or service target, allowed write scope, required checks, budget, deadline, approval policy, and memory keys. This makes a scheduled docs sync, a performance optimization loop, and a PR repair loop observable in the same way. It also prevents the agent from expanding the task after it has already started.

The trigger should choose the initial execution mode. Low-risk loops can run in auto mode with pre-tool hooks blocking destructive commands. State-changing infrastructure work should start in diagnose-only mode and request approval before mutation. Large implementation work should spawn isolated worktrees so planning, implementation, and validation can run without file conflicts. If you cannot express the trigger as data, the loop is not ready to run unattended.

Turn The Goal Into Tests

Once the loop starts, the definition of done must live outside the model. Deterministic checks are the highest trust signal: unit tests, type checks, lint, CI, benchmark thresholds, page-load budgets, API health probes, or reproducible browser assertions. For example, `all routes under 50 ms p95 on fixture data` is a loopable goal. `make the app feel faster` is only loopable after it becomes a measured budget.

A strong harness keeps verification close to the state machine. The implementation agent edits. The validation step runs checks. If checks fail, the harness feeds back the failing output and returns to implementation. If checks pass, the loop advances to review. Do not ask the agent whether it is done. Ask the harness whether the evidence satisfies the stop predicate.

Subjective goals still need gates, but they require different handling. Architecture quality, documentation usefulness, or spec parity can use a judge agent, but the judge must receive a narrow rubric and produce structured output: pass/fail, score, violated constraints, required fixes, and cited evidence. Keep the judge separate from the implementer. A self-reviewing agent will often rationalize its own work, especially after a long context run. For judged loops, add tighter token budgets and maximum iteration counts because non-deterministic gates are where loops drift and costs spike.

Require Proof Of Work

After tests, require artifacts that prove the loop actually touched reality. The harness should store command transcripts, exit codes, hashes of test output, benchmark JSON, screenshots, Playwright videos, diff stats, and the final commit SHA. For frontend work, a passing build is not enough. Have the loop open the changed screens, capture screenshots or video, and attach them to the run record or PR. For ops work, store the diagnostic commands requested, whether approval was needed, what fix was applied, and the post-fix health result.

Proof artifacts solve two problems. First, they make the loop auditable when it wakes you up or opens a PR. Second, they deny the model an escape hatch. Agents will sometimes claim they ran a check they did not run, summarize stale output, or stop after a plausible edit. A hash of the test log, a browser recording, or a benchmark file produced after the final diff is harder to fake accidentally.

Design the artifact schema before scaling parallelism. A useful run record includes `trigger`, `attempt`, `model`, `tools_used`, `files_changed`, `checks_run`, `check_artifacts`, `judge_result`, `cost`, `duration`, `stop_reason`, and `memory_updates`. This lets another loop compare runs, detect repeated failures, and route future work differently.

Use Parallelism Without Losing Control

Parallel agents are useful when the harness can merge evidence, not opinions. Worktrees are the default isolation boundary for code. Run multiple implementation attempts against the same spec, or split planning, coding, and validation into separate sessions with compact handoffs. The orchestrator should compare concrete outputs: test pass rate, performance delta, diff size, risk classification, and review findings.

Avoid giving every worker a giant skill library. Frontier harnesses often get better results by deleting broad context and keeping only curated gotchas: repo-specific failure modes, dangerous commands, deployment constraints, flaky tests, protected services, and review rules that have actually prevented mistakes. Large instruction dumps inflate cost and increase conflict. Small memory files, read at the right phase, improve accuracy because they bias the agent toward known local hazards.

Model routing belongs in the same control plane. Use cheaper models for log summarization, fixture generation, doc syncs, and first-pass lint repair. Route multi-step diagnosis, architectural review, or tool-heavy debugging to stronger models. Escalate only on evidence: repeated failed attempts, ambiguous test failures, judge disagreement, or commands requiring high confidence. The loop should record why it upgraded, because model choice is part of the run's reproducibility and cost profile.

Stop Conditions Are Safety Features

A loop without stop conditions is just an unbounded spend primitive. Set stop predicates at several layers: success, irrecoverable failure, budget exhaustion, repeated identical failure, unsafe tool request, missing dependency, review rejection, or required human approval. The important detail is that each stop reason is explicit and machine-readable. `stopped because tests still fail after five distinct patches` is operationally useful. `agent gave up` is not.

Training mode is the right way to introduce a new loop. Make the agent pause before each state transition until the workflow proves stable: trigger accepted, memory loaded, plan generated, first edit made, checks run, review passed, artifact stored, memory updated. Once the shape is reliable, remove approvals only from low-risk transitions. Keep approvals around destructive commands, production mutations, credential access, and broad refactors.

The final step is retrospective memory. Treat failures as harness bugs, not mysterious model behavior. If the agent repeatedly misses an environment constraint, add a preflight check or memory note. If it runs the wrong test, change the verifier. If it loops on the same failed patch, add duplicate-failure detection. The mature loop does not trust the agent's claim of completion. It turns the goal into evidence, routes work until the evidence is sufficient, and stops with a record that another system can inspect.

Key takeaways

  • Make the harness, not the model, responsible for trigger handling, state transitions, verification, and stopping.
  • Prefer deterministic completion tests; use judge agents only with narrow rubrics, structured output, and strict budgets.
  • Store proof-of-work artifacts such as logs, hashes, benchmark files, screenshots, videos, diffs, and final SHAs.
  • Parallelize with isolated worktrees and compare evidence across attempts instead of asking agents which result is best.
  • Keep memory small and operational: curated gotchas, environment constraints, repeated failures, and verifier fixes.
  • Every loop needs machine-readable stop reasons for success, failure, budget, safety, approval, and repeated non-progress.