Loop engineering: design the environment

17/06 · 10 min

Loop engineering illustration

When you prompt, you are the loop

Think about what you do in a long session with an agent. You give the instruction, read the output, judge it, catch the false claims, remind it what it forgot, and decide when it's done.

The model does the typing. You are the quality control, the memory, and the off switch.

That's fine for a single task. It quickly becomes impractical when you want to run really long sessions that span hours. Not because the model isn't smart enough; Anthropic's Fable 5 can pretty much one-shot most single tasks you can think of. It's that you don't scale. You can't review two hundred actions an hour. You can't stay awake overnight. The moment you stop watching, the system has zero verification left.

Loop engineering is the fix. You design a small system around the model, a goal, a check, a memory, a stopping rule, and the system does the steering. You build the loop once. The loop does the prompting.

A loop is five words

Act, check, keep, revert, repeat.

The agent does something, checks the result, keeps what works, reverts what doesn't, and repeats until the work passes.

The whole thing depends on one question: what can the loop use to check its own work? That question, not the model and not the prompt, decides whether a loop converges or just produces more output faster.

Five things I learned

1. The rubric is doing more work than the model.

Anthropic gave Fable 5 nine checkable criteria and eight hours on an ML optimization challenge. Same loop, it beat the previous model generation by roughly 6x. The model is the easy part now. Writing down 'done' in a form a command can check is the skill.

2. Never let the worker grade its own homework.

Ask a model 'is it done?' and it says yes while the tests fail. It isn't lying; it's the same blind spot every author has. The fix that measures best is a second agent with fresh eyes: separate context, never saw the worker's reasoning, re-runs every check itself, instructed to refute the claims rather than confirm them. Maker and checker must be different minds.

3. Memory is a loop across sessions.

Every new session is day one unless you build otherwise. The progression that compounds: fail, investigate, verify, distill, consult. Weak models write notes and never read them. The strongest complete the cycle and get better week over week, but only if there's a place to write. Memory is built; it doesn't emerge.

4. Every loop needs a stopping rule.

Two agents once got into a polite ping-pong, handing work back to each other with nobody watching. 264 hours. A $47,000 bill. An unattended loop without a budget isn't autonomous; it's unexploded.

5. Loops only work where 'done' is checkable.

A coding loop has gravity:

  • ·Tests pass
  • ·Build passes
  • ·Benchmark improves
  • ·The bug is gone

The environment tells the agent when it's wrong. Green means done.

Most other work has no clean score at the moment it's made. A weak landing page still loads. A bland post still publishes. Nothing in the environment stops it. For that work you either build judgment gates (is the claim sourced, is this specific or filler, does it sound like us) or you end the loop at 'worth a human decision' instead of 'done.'

Knowing which kind of task you're holding is half the job. Agents that copy the motion of coding loops without the verification layer just produce more work, faster, with less taste.

Which tasks this is for

Loops win on long, multi-step work with a checkable end state: refactors, migrations, perf hunts ('p95 under 200ms without breaking contract tests'), bug investigations, twenty-experiment optimizations, overnight runs.

Prompting stays right for short, judgment-shaped work you'll read in full anyway. Your thirty-second review is the verification.

The problem: wiring this yourself is a lot

Here's the bill of materials if you build it by hand: a goal file with machine-checkable criteria. A hook that intercepts the agent every time it tries to stop. A separate verifier agent with restricted tools and adversarial instructions. Protection against the agent editing the checks it's graded on. Turn budgets. Stop conditions. A memory system that won't let the agent confidently write down things that aren't true. And escape hatches, so none of it can ever trap you.

I built all of that once, made every mistake available, and packaged it.

That's ultragoal: a plugin that wires this loop into your coding agent (Claude Code today, with Codex and more on the way).

npx ultragoal        # one-time install

Then, inside any repo, run /ultragoal:goal <your messy brief>. First use scaffolds .ultragoal/ and asks three preference questions, about sixty seconds. Or skip the editor entirely:

npx ultragoal run "checkout is slow, get p95 under 200ms without breaking contract tests"

That launches your agent with the goal armed and full autonomy on. npx ultragoal update keeps every install current.

What the loop guarantees

You ramble; it interviews you on the two to five forks that change the outcome; it compiles a rubric where every line is checkable by a command; you confirm a short recap; and the loop arms. Then you walk away. While you're gone:

It can't stop early.

A gate intercepts every attempt to finish. An unfinished rubric means back to work, with the remaining items listed. The agent can't leave by being confident, only by being checked.

It can't grade itself.

Before any box is checked, a fresh-eyes verifier re-runs every check and tries to refute the claim. No command output, no pass.

It can't move the goalposts.

Every verdict is bound to a fingerprint of the exact rubric it judged. Edit a check, and every prior approval voids automatically.

It can't run forever.

Turn budgets and stop conditions are mandatory. Hit them and you get an honest report of where every item stands, then a pause.

It can't forget.

The loop won't release until lessons are written to memory, each tagged with how it's known: verified, read, or merely inferred. Your repo gets smarter every goal.

It can't trap you.

The gate fails open on any error, /ultragoal:stop bails instantly, and an abandoned goal still distills what it learned. Failure is memory too.

Everything it produces (goal, rubric, verdicts, memory) is plain markdown in your repo. Diffable, editable mid-flight, shared through git. No dashboard, no database, no lock-in.

The honest version of the reliability claim: it's not that the model became trustworthy. It's that no claim survives the loop without a command output behind it. The trust lives in the structure, not the model's mood.

Under the hood, briefly

The loop driver is a stop hook: about 150 lines of POSIX shell that run every time the session tries to end. Exit 0 releases; exit 2 blocks, and stderr (the unchecked items plus the protocol) becomes the model's next instruction. There's no model call in the driver. The intelligence is in the worker; the discipline is deterministic.

Goals are per-session files (.ultragoal/goals/active/<slug>/goal.md) with budget and session id in frontmatter. Parallel sessions can run parallel goals in one repo; pair that with a git worktree when they touch the same files.

The verifier recomputes the rubric checksum itself, never accepting one quoted to it, re-runs the checks, and appends ULTRAGOAL-VERIFIED: PASS rubric=<hash> to the goal file. The gate only accepts a verdict whose hash matches the current rubric.

Memory files are two layers: compiled claims above a divider, rewritten freely, each carrying a provenance tag; below it, an append-only dated evidence log that's never edited. Synthesis can be wrong; evidence can't.

Metric goals ('make this number better') compile to a ratchet: commit before measuring, keep only strict improvements, git reset on regression, log every attempt. The measure command is frozen at arm time and the verifier diffs it against the baseline commit. The agent improves the number, never the measurement.

Borrowed parts

None of this is invented from zero. The best loop systems are assembled from proven pieces, and I'd rather credit them than pretend otherwise.

The core thesis, verifier subagents over self-critique and the fail-investigate-verify-distill-consult memory progression, is straight from Lance Martin's loop experiments at Anthropic.

The behavioral prompts ultragoal injects (grounded progress claims, autonomy, scope discipline, communication) are Anthropic's official Fable 5 prompt blocks, shipped verbatim. They published what works; no reason to paraphrase it worse.

The stop-hook architecture, the loop living inside the session, cancellable and permission-aware, instead of a bash wrapper restarting the agent from outside, follows Anthropic's ralph-loop plugin pattern.

The experiment ratchet is Karpathy's autoresearch loop: baseline first, one change per experiment, commit before measuring, keep only strict wins, and never, ever let the agent touch the evaluator.

The memory format is Karpathy's llm-wiki pattern plus Garry Tan's gbrain: compiled truth above the line, append-only evidence below, provenance on every claim, and user corrections written the moment they happen.

Deliberately not borrowed: swarm orchestration (one worker, one verifier, and cheap scouts is the recipe that actually works), bash-wrapper loops, and custom project-management layers. Goals are files. Git is the tracker.

Where it honestly falls short

The rubric bounds everything.

The loop converges on whatever the checks say is good. A wrong rubric means confident convergence on the wrong thing, green checkmarks all the way down. The system attacks its own draft rubrics for vagueness before you see them, but rubric quality stays partly on you.

Fresh eyes, same species.

The verifier is an independent context, not an independent mind. It catches fabricated progress and stale claims; it won't catch a check that's subtly wrong in a way that fools the whole model family.

Evidence, not proof.

Verdicts carry command outputs you can audit, but the trust boundary is your own machine. Proving to an outside party what an agent executed is attestation territory; this isn't that.

Judgment work stays hard.

If 'done' can't be made checkable, ultragoal refuses the vibe rubric rather than faking one. Right failure mode, still a boundary.

Loops cost tokens.

Independent verification roughly doubles the work behind every claim. Budgets cap the blast radius; pick goals worth the spend.

Understanding stays your job.

The final report names the two or three diffs most worth reading with your own eyes. Verification proves the work passes; reading is how you keep understanding your own codebase. Nobody has automated that, including me.

The takeaway

Prompt engineering asks: how do I phrase it so the model does it right? Loop engineering asks: what structure would make it impossible to call this done when it isn't?

The first is persuasion. The second is engineering: a checkable goal, fresh-eyes verification, memory that survives, a stopping rule. That's the whole idea.

The model is the easy part now. Design the loop.

this site is a work in progress