Browse the docs
Loops
The third process object — a graph you design that repeats under a small brain until a success condition you wrote is genuinely met.
A Loop is a graph you design that runs on repeat under a small brain. Each pass runs your whole graph; then the brain judges the result against a success condition you wrote and — if it isn't met — routes a targeted correction into specific stages before running the graph again. The brain never redesigns your graph. It only judges and corrects.
Reach for a Loop when you know the job but one pass rarely nails it.
Three ways to automate
Destaris has three process objects. A Loop is the third, and it is not a midpoint between the other two:
| Workflow | Loop | Agentic Workflow | |
|---|---|---|---|
| Who designs the graph | You | You | The brain, every iteration |
| Who defines "done" | Nobody — it just runs | You (successCondition) | The brain |
| What the brain does | — | Judges, and routes feedback to stages | Designs, runs, judges, corrects |
| Repeats until done | No | Yes | Yes |
| File | .destaris/workflows/<name>.yaml | .destaris/loops/<slug>.yaml | .destaris/agentic-workflows/<slug>.yaml |
If you already know the steps and they never need to change: build a workflow. If you have a goal and want the brain to figure out the steps itself: build an Agentic Workflow. If you know the steps but want a brain to keep at them — judging and correcting — until a condition you define is genuinely met: build a Loop.
The distinction that matters most: a workflow and a Loop are authored the same way. You build the steps yourself in both. The difference is that a Loop also carries a definition of "done" and reruns itself until that's met. An Agentic Workflow is the one where you don't author the steps.
So the three objects don't sit on a single line. Workflow and Agentic Workflow split on do you already know the steps? A Loop doesn't sit on that axis at all — you supply the steps exactly as you would for a workflow — so it introduces the second question: does running them once actually finish the job?
Don't confuse a Loop with task.loop
task.loop and task.foreach are inline while/until node types used inside the steps of
any of the three objects — a small control-flow primitive for repeating a few steps within one
pass of a graph (see the node reference). They're also what the
four loop-engineering shapes are built from.
A Loop is a completely different, top-level thing: its own file, its own brain, its own
success condition, repeating the whole graph across passes. A Loop stage may itself use
task.loop internally — that has nothing to do with the Loop object repeating.
The shape of a Loop
A Loop is your stages, pinned between two nodes you don't create and can't delete:
[ input ] ──▶ [ your stages: research → implement → verify ] ──▶ [ brain ]
▲ │
└────────────── correction, addressed by stage ◀───────────────┘
inputis the pinned start. It carries the situation this run is working on — either some text, or a file in your workspace. It's resolved once, before the first pass, so what a Loop is working against stays fixed for the whole run even if the file changes underneath it. Every stage can reference it in a prompt.- Your stages are everything in between, and they're ordinary Destaris nodes — the same palette you build a workflow from. Agent steps, commands, HTTP calls, integrations, even a call out to a whole existing workflow.
brainis the pinned end. It's where judging happens, which is why it sits at the end of the graph rather than the start — it can only have an opinion once a pass has actually finished.
The brain is deliberately small and deliberately blind: it has no tools of its own. No filesystem, no shell, nothing it can go and look at. It judges strictly from what this pass's stages produced, plus the reference files you listed on the success condition. If a stage's result isn't visible in one of those two places, the brain has no way to learn it.
The success condition
The success condition is the part that makes a Loop a Loop. It's a bar, written in prose, that the brain checks every single pass:
Every acceptance criterion in the spec is implemented and its tests pass.
Write it as a real bar, not as steps. "Every acceptance criterion in the spec is implemented and its tests pass" is a condition. "Run the test suite" is a step — and it's already in your graph.
Alongside the prose you can list references: workspace paths the brain re-reads fresh off disk before every pass, never a snapshot from when you wrote the Loop. List the files a person would actually open to decide "is this really done" — the spec itself, an acceptance checklist, a house standard.
What happens each pass
Every pass re-runs your whole graph. There's no resuming from halfway. When the pass finishes, the brain returns one of two verdicts:
- Done. The condition is met. The Loop stops.
- Continue — with a correction addressed by stage. Not one blanket note for the run: a
specific message for
research, a different one forimplement, and nothing at all for stages that don't need to change.
Each correction is appended to that stage's prompt before the next pass, in a clearly delimited block:
--- Correction from the previous pass ---
AC-3 (offline retry) is not implemented. The spec defines it in §4.2.
----------------------------------------
Two things make this work in practice. First, it's automatic — you don't wire anything up for it, and you can't forget a placeholder and silently lose a correction. Second, it's fresh, never cumulative: the previous pass's block is stripped before the new one is added, so a stage on pass 3 carries only pass 3's correction rather than a pile of stale ones.
The brain can also address a stage that isn't the one that visibly broke. A gap that only becomes
obvious at verify is often best fixed by telling research to look harder — and the brain is
allowed to say so.
How a Loop ends
| Status | Means |
|---|---|
done | The brain judged the success condition met. |
stuck | Every pass ran cleanly, but the condition was never met before the iteration cap ran out. |
failed | A stage hard-errored — a wedged tool call, a missing secret. The brain is never consulted. |
waiting | A stage parked the pass on an external signal. |
cancelled | You stopped it. |
stuck and failed are deliberately different, and it matters which one you're looking at.
stuck means the graph is fine and the brain simply isn't satisfied yet — feedback was routed
across every pass you spent. failed means the graph broke, which is an environmental problem no
amount of trying harder will fix, so it's never handed to the brain as something to correct.
Every Loop has an iteration cap (maxIterations, 5 by default) as the backstop. It's the same
instinct as the stop rules on everything else in Destaris:
nothing that runs unattended gets to run unbounded.
A Loop can graduate into a workflow
A brain costs tokens. Once a Loop stops needing one, Destaris offers to drop it: export the Loop's stages as a plain workflow and run them for close to nothing from then on.
The bar for that offer is deliberately high — the Loop has to have met its condition on the first pass, five runs running, on an unchanged graph, across at least three distinct inputs. Repetition alone isn't enough. Five clean runs against one spec show the brain has that spec's answer, not that your graph is deterministic. Variety is what proves it.
That's the same bet as deterministic-first, applied to a whole process: intelligence is scaffolding you spend while it's earning its keep, and remove once the structure stands.
Related
- Building Loops — the YAML, a worked example, and the traps.
- Agentic Workflows — the object where the brain designs the graph.
- Deterministic-first — why the brain is the exception, not the default.
- The canvas — how you build the stages in between.
- Node reference — every node type a Loop stage can be.