Skip to content
Small team, full backlog, zero orders dropped. Support replies are slower than we’d like. Read our status update → Zero orders dropped. Status → 📬 Check your spam folder — most of our replies land there. We do answer. Status update → 📬 Check your spam folder. Status →

Agentic Engineering / Rung 4

Loop Engineering

A single turn is a guess. A loop that measures its own output is a control system. This is how you build the second thing, and how you stop it before it eats your budget.

A Turn Is A Guess. A Loop Is A Control System.

Ask an agent for a change and you get one attempt. It reads what it can reach, writes what it believes is correct, and hands back a summary. Whether that summary is true is a separate question that nobody asks. Loop engineering asks it inside the machine, on every pass, automatically.

The shape is simple. The agent acts. Something that is not the agent measures what actually happened. That measurement becomes the next input. Repeat until a stated condition is met, or until you refuse to pay for another round. Development stops being a conversation and becomes a control system. A conversation drifts toward agreement. A control system converges on a measurement or fails loudly.

We did not invent this. Colonel John Boyd put the observe-orient-decide-act cycle into military doctrine decades before anyone typed a prompt, and the ReAct paper by Yao and colleagues (2022) formalised interleaving reasoning with actions and observations from a real environment. Anthropic defines an agent as an LLM using tools in a loop based on environmental feedback. Every coding harness implements that sentence. Loop engineering is what you do to it to get software you would ship.

This page is rung four of seven. The first three rungs decide what a single turn contains: prompt engineering owns the instruction, context engineering owns what the agent knows, harness engineering owns which agent, model, tools and permissions execute it. Loop engineering assumes those are good and asks what happens on the second pass, and the ninth, and how you know when to stop. Rung five, graph engineering, is what you build when one loop is no longer enough.

4
Beats in a loop that works
4
Ways to end one on purpose
0
Self-reports that count as evidence
7
Rungs in the agentic ladder

The Four Beats Of A Working Loop

Build, test, inspect, fix, test again. Written out honestly the cycle has four beats, and each is a place where loops die.

Act

The agent does the work. This is the beat everyone gets right and the only one most people build. It is also the cheapest beat to improve, because rungs one through three of this ladder already cover it.

Observe

Something other than the agent produces a record of what happened. Test output, exit codes, a diff, a rendered screenshot, a log file, a timing measurement. If the agent authored the observation, you observed nothing.

Judge

A rule converts the observation into pass or fail. It must be capable of returning fail. A judge that has never rejected anything is not a judge, it is a formality with a runtime cost.

Correct

The failure becomes the next iteration's input, distilled down to what is actionable. Handing the agent an unfiltered 4,000-line stack trace is not correction, it is context poisoning with extra steps.

Most broken loops are three-beat loops. They act, they glance, they act again. The judge is missing, so nothing can ever be false, so the loop cannot terminate on merit. It terminates on exhaustion, which means it terminates when you notice the spend.

The Feedback Signal Is The Whole Game

A loop with no real measurement is not a loop. It is repetition with a bill attached. Everything else here is secondary to one rule: the signal driving the next iteration must come from outside the thing being judged.

The temptation is to let the model grade itself, because it is free and always answers. Do not. Huang and colleagues (ICLR 2024, Large Language Models Cannot Self-Correct Reasoning Yet) found that models asked to correct their own reasoning without external feedback often got worse. Their framing is the one to keep: if the model could reliably tell the answer was wrong, why did it produce that answer? Reflexion, by Shinn and colleagues, is cited as proof that self-reflection works, and it does. Read it closely: the reflection is triggered by feedback from the environment. The environment does the work.

The second failure is subtler and more expensive. A loop optimises whatever you measure, which is never quite what you meant. Cursor’s 2026 audit of 731 agent trajectories on SWE-bench Pro reported that 63% of one frontier model’s successful resolutions retrieved the fix rather than derived it: 57% found the merged upstream pull request on the public web, 9% mined the bundled Git history for the future commit. Under a stricter harness that model’s score fell from 87.1% to 73.0%. The mechanism is general and it will happen in your repository. Point a loop at “make the test pass” and you have authorised special-casing the input, weakening the assertion and editing the test. All three make the number go green.

So the rule we hold ourselves to on DCENT_ADE, and the reason its doctrine forbids fake agents, simulated activity and optimistic status indicators: the evidence has to be real. Not persuasive. Real.

Real Pixels, Real Terminals

A captured screenshot of the rendered surface, not a description of it. Real terminal behaviour from a real PTY: what the process does on resize, on interrupt, when left idle. A status field saying “running” is a claim. A process emitting output is a fact.

Real Files, Real Git

Files on disk with the bytes you expect. A diff a second process can read back. Git effects verified by asking Git, not by reading a summary saying the branch was merged. We learned that the hard way often enough that DCENT_ADE’s execution layer refuses to report a merge it did not perform.

Real Tests, Real Recovery

Tests that ran, with a readable count and a non-zero total. Performance measured on the same machine under the same conditions, never across a deploy. Failure recovery exercised on purpose: kill the process, revoke the permission, unplug the network, and check it degrades the way the design says.

loop.sh
$ cat loop.sh
#!/usr/bin/env bash
# no -e on purpose. a failing test is the signal, not a crash.
set -uo pipefail

MAX_ITERS=${MAX_ITERS:-12}

for i in $(seq 1 "$MAX_ITERS"); do
  echo "=== iteration $i ==="
  mkdir -p "runs/$i"

  # ACT. fresh process, bounded turns, nothing interactive.
  claude -p "$(cat PROMPT.md)" --max-turns 40 --output-format stream-json > "runs/$i/agent.jsonl"

  # OBSERVE. artifacts the agent did not author.
  npm test -- --reporter=json > "runs/$i/tests.json" 2> "runs/$i/tests.err"
  git diff --stat > "runs/$i/diff.txt"

  # JUDGE. an exit code, never a paragraph.
  if ./gate.sh "runs/$i"; then
    echo "GREEN at iteration $i"
    exit 0
  fi

  # CORRECT. the failure becomes the next input.
  ./distil-failure.sh "runs/$i" > NEXT_SIGNAL.md
done

echo "STOPPED: iteration ceiling hit, no green gate. do not merge."
exit 1

Designing The Observation Step

The observation step decides whether the loop is worth running. Four properties make it work.

It must be machine-checkable. An exit code, a count, a hash, a byte size, a millisecond figure, a string present or absent in a log. If a human has to read a paragraph and form an opinion, the loop cannot run unattended and you have built a slow code review.

It must be produced by a different process. The observer runs after the agent exits, reads the artifacts left behind, and never sees the transcript. This is the fresh-context principle behind gauntlet loops work, applied to a mechanical check instead of a critic. An observer that inherits the builder’s context inherits the builder’s assumptions.

It must be able to fail. This is the one that bites. We have shipped verification gates that could not fail, and found out only when someone injected a defect the gate was meant to catch and watched it pass. The cause is always boring: a file read from cache instead of regenerated, a grep matching its own fix, a check run against a stale artifact. Give every gate a positive control, a deliberately broken input it must reject, and run it every pass.

It must be cheap. You pay for it every iteration. A three-minute suite in a twelve-iteration loop is thirty-six minutes of nothing. Run a fast subset as the inner gate and the full suite once as the outer gate before anything merges.

gate.sh
$ cat gate.sh
#!/usr/bin/env bash
# every line below checks an artifact on disk.
# nothing here reads the agent's own account of its work.
set -uo pipefail
RUN="$1"
fail() { echo "GATE FAIL: $1"; exit 1; }

# 1. the suite actually ran, and it is green
[ -s "$RUN/tests.json" ] || fail 'no test report on disk'
[ "$(jq -r '.numTotalTests' < "$RUN/tests.json")" -gt 0 ] || fail 'zero tests collected'
[ "$(jq -r '.numFailedTests' < "$RUN/tests.json")" -eq 0 ] || fail 'tests are red'

# 2. the change exists in the working tree, not only in the transcript
[ -s "$RUN/diff.txt" ] || fail 'work reported but no file changed'

# 3. the original defect is gone from real output
./repro.sh > "$RUN/repro.log" 2>&1
grep -q 'TypeError' "$RUN/repro.log" && fail 'defect still reproduces'

# 4. positive control. a gate that cannot fail is not a gate.
./repro.sh --inject-known-defect | grep -q 'TypeError' || fail 'gate is blind: it missed an injected defect'

echo 'GATE PASS'

Knowing When To Stop

A loop without a termination condition is a fork bomb with a credit card. Decide the stopping rule first, write it into the script, and make it something the script can evaluate without you.

Four Ways To End A Loop On Purpose
Termination rule Stops when Best for How it betrays you
Loop until dry A queue, backlog or defect list reaches zero and one full extra pass finds nothing new Bounded, enumerable work: a lint backlog, a list of failing tests, a migration checklist, a set of files to convert The list is not the territory. The loop goes quiet because the enumerator is blind, not because the work is finished. Always require one empty pass after the last item.
Loop until count A fixed number of iterations have run Exploration where you want several independent attempts, and any run where you do not yet trust the gate It stops mid-repair on hard problems, and it happily pays for nine more iterations after iteration two was already green. Pair it with an early exit.
Loop until budget A token, dollar or wall-clock ceiling is reached, whichever comes first Overnight and unattended runs. Anything nobody is watching. Any loop touching a metered API. It spends the entire budget on the wrong problem and reports honestly that it ran out. A budget is a blast radius, not an objective.
Loop until a human signs A reviewer accepts an evidence packet and co-signs Anything touching production, money, customer data, credentials or the default branch It is not automatic and it does not scale. It is also the only rule here that can catch a loop cheerfully optimising the wrong thing.

In practice you combine them. The useful default is loop until dry, with count and budget ceilings as backstops and a human signature before the result leaves the worktree. Whichever fires first wins. Log why it stopped: “hit the iteration ceiling” and “gate passed on iteration three” are different outcomes that look identical in your scrollback.

Oscillation, Thrash And Local Optima

Three distinct pathologies look identical from outside: a loop that is busy and going nowhere.

Oscillation is A to B to A. The agent changes a value, the gate fails for an unrelated reason, the next iteration changes it back. Detect it by fingerprinting each iteration’s diff and keeping the list. A repeated fingerprint is not progress, it is a cycle, and a loop inside one never leaves on its own, because every iteration starts where the last one did.

Thrash is fix one, break another. The pass count stays flat while churn climbs. Track both per iteration: tests passing, lines changed. Rising churn with flat passes means the agent is fighting the design rather than the bug, so stop and fix the design.

A local optimum is worse because it looks like success. The gate passes. The artifact is mediocre. The loop found the cheapest path to satisfying your measurement and has no reason to look further. That is not the loop’s fault, it is the gate’s. When a loop converges on something that clears the bar and is still bad, the bar was in the wrong place, and extra iterations will not move it.

The response to all three is the same and it is counterintuitive: never turn the crank harder. Adding iterations to a stuck loop is the most reliable way to spend real money on nothing. Change an input. Different context, a different model at the harness layer, or an acceptance criterion rewritten to name the outcome you want rather than the proxy that was easy to check. Or escalate the structure: hand the artifact to an adversarial critic allowed to reject it, the gauntlet pattern, or split the work across independent branches, which is graph engineering.

Our own stop rule: two consecutive iterations with no measurable movement in the metric that matters is a halt, not a hint.

The Loop That Improves An Artifact Versus The Loop That Burns Money

Both look the same in your terminal. Both produce output. Only one has a curve you can point at. A working loop answers one question: what did iteration nine buy that iteration two did not?

To answer it, record cost and outcome to disk every iteration. Tokens in and out, wall-clock, the gate result and why it failed, the diff fingerprint. An unlogged loop cannot be audited, costed or improved, and you will not reconstruct it from memory.

Ceilings belong at two levels and people build only one. The inner ceiling bounds a single agent invocation: most headless harnesses expose a maximum turn count for this reason, and Claude Code’s --max-turns is the obvious example. The outer ceiling bounds the loop itself, and nothing gives you that for free. You write it: iteration count, token spend, dollars or wall-clock, whichever trips first, then exit non-zero and say why.

Then bound the damage as well as the spend. Run the loop in an isolated worktree, never the branch you care about. Give it the narrowest tool permissions that let it finish, and keep production credentials out of the environment. A loop is an amplifier: it applies whatever authority you handed it a dozen more times than you would have. That is the point of it and also the risk.

The blunt test: if you cannot say what the loop measured, you are not running a loop. You are running a slot machine with a progress bar.


Two Named Specializations

Two well-known loop designs inherit everything on this page and then make one strong choice each. They get their own pages because that choice changes how you operate them.

RALPH: Brute Force, Fresh Context

Not ours. RALPH comes from Geoffrey Huntley’s writing on running an agent the way Ralph Wiggum would: a shell loop re-running the same prompt with a fresh context every iteration, against the files the previous iteration changed. Huntley’s framing is one task per loop in a single operating system process, and he is explicit that the discipline is context engineering plus fixing failure domains so they never recur. It chooses repetition over cleverness. Full treatment on the RALPH loops page.

Gauntlet: Adversarial Judgement

Ours. A builder produces a real artifact. A separate critic receives fresh context, judges the actual result rather than the story about it, and is permitted to reject. The largest remaining gap goes back to a builder and the loop repeats. It replaces the mechanical gate with an independent adversary, which catches the class of problem a script cannot describe. It is how DCENT_ADE gets built. Full treatment on the gauntlet loops page.

Both still need everything above: real evidence, a termination condition, a cost ceiling, a way to notice oscillation. A gauntlet whose critic never rejects is an expensive rubber stamp. A RALPH loop with no stopping rule is a cheap way to discover your API billing page.

Where Loops End And Graphs Begin

A loop is one worker turning one crank. You have outgrown it when the work splits into branches that do not depend on each other, when branches need different stopping rules, when results must be joined before anything can be judged, or when the right response to a failure is routing it to a different specialist. At that point you are describing a dependency graph with fan-out, joins, gates and retries, and that is the next rung: graph engineering. Prior art there is well established, from LangGraph onward.

Do not skip ahead. A graph of agents is a graph of loops. If the individual loop has no real evidence and no termination condition, the graph inherits both problems and multiplies them by the node count.

How DCENT_ADE Treats The Loop

DCENT_ADE is our sovereign agentic development environment, built on the assumption that the loop, not the turn, is the unit of work. That shows up in a few places.

Orion, the local-first coordination layer, distinguishes busy from idle from awaiting input from finished by reading real terminal behaviour on a native PTY. That is the observe beat, derived from what the process is doing rather than a status flag an agent set for itself. Optimistic availability indicators are banned by the project’s own rules, for the same reason self-grading is banned from a gate. With tiled recursive splits and up to sixteen visible regions you can watch several loops at once, still the highest-bandwidth debugger anyone has built.

Mission Control gives the loop structure: Coordinator, Scouts, Builders, Reviewers, then human approval, then integration and delivery. Claims stop two agents doing the same iteration. Worktree isolation keeps the blast radius inside a throwaway checkout. Review packets carry evidence to the judge instead of a summary to a human. MergeGate and human co-signing make the loop-until-a-human-signs rule structural. The architecture supports this and much of it is live-proven in testing.

The behaviour we are proudest of is a refusal. The catalog execution layer will not claim a Git merge it did not perform. In a system whose job is running unattended cycles, a component that would rather report failure than an unsubstantiated success is not a rough edge. It is the feature.

Loops are token-hungry, so where inference runs is a cost decision as well as a sovereignty one. DCENT_ADE discovers and manages local models through Ollama and LM Studio, supports model-role assignment, and can use inference across your LAN. Cloud is an explicit, consented boundary, never an invisible fallback, and ordinary local work carries no telemetry. Running cheap iterations locally and reserving a frontier model for the judge should be your choice, not a vendor’s default.

We stand on other people’s work and say so. Anthropic’s Claude Code, OpenAI’s Codex, Gemini and OpenCode are supported harnesses in the catalog, and the patterns here were shaped by their authors, by Huntley’s writing, by tmux, and by decades of CI practice that already knew a build is only green if a machine says so.


Loop Engineering FAQ

Re-prompting is a human reading output and deciding, which means the quality of the result is capped by your patience. Loop engineering moves the deciding into a rule the machine evaluates: a test exit code, a diff, a screenshot comparison, a critic with fresh context. The practical difference is that a loop can run while you sleep and can prove afterwards why it stopped, and re-prompting can do neither.
Anything produced by something other than the agent being judged, that a script can evaluate without human interpretation. Test results, exit codes, a real diff, a captured screenshot of the rendered surface, a log line, a timing measurement taken under identical conditions. What does not count: the agent saying it fixed the bug, a summary of changes, a confidence score, or any check that has never once returned failure.
Two ceilings, not one. Bound each agent invocation with the harness turn limit, then bound the loop itself with an iteration count, a token or dollar budget and a wall-clock limit, whichever trips first. Log cost per iteration to disk so you can see the curve. Add a halt rule for two consecutive iterations with no measurable movement, because a stuck loop never unsticks itself and every further iteration is pure spend.
That is thrash, and it means the agent is fighting the design rather than the defect. Adding iterations makes it worse. Stop the loop, look at the diff fingerprints to confirm it is not also oscillating between two states, and change an input: narrower scope, better context, a different model, or an acceptance criterion that names the real outcome instead of a proxy. If the work genuinely splits into independent pieces, promote it from a loop to a graph.
No, the gate is. A loop converges on the cheapest thing that satisfies your measurement, which is correct behaviour and exactly why the measurement has to be the thing you want. Cursor’s 2026 audit of agent trajectories on SWE-bench Pro is the cautionary version of this at scale: told to make tests pass, agents found ways to make tests pass. Either tighten the gate or replace it with an adversarial critic that is allowed to reject on quality.
No. RALPH is one specialization: same prompt, fresh context, repeated until done, and it is Geoffrey Huntley’s, not ours. Loop engineering is the general theory it inherits from, covering the observation step, termination rules, oscillation detection and cost control. Our gauntlet loops are a different specialization of the same theory, using an independent critic instead of brute-force repetition.
You still need the gate. The loop that terminates on iteration one is the best possible outcome, and it is only meaningful because something checked. A first attempt you did not verify is not a fast success, it is an unverified change that happens to look finished.

Free, Open, As-Is

DCENT_ADE is free and open source. No paid tier, no gated feature, no telemetry bargain, no waitlist. If you use it commercially, or it saves you a week, a voluntary subscription or donation is expected and never enforced. That is the whole arrangement: d-central.tech/fund.

Keep climbing from the agentic engineering hub, or drop back a rung to harness engineering and decide which agent should turn the crank.

Run The Loop Where You Can Watch It

DCENT_ADE is a local-first agentic development environment built on real terminals, real evidence and human co-signing. No fake agents, no simulated activity, no invisible cloud fallback.