Destaris
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:

WorkflowLoopAgentic Workflow
Who designs the graphYouYouThe brain, every iteration
Who defines "done"Nobody — it just runsYou (successCondition)The brain
What the brain doesJudges, and routes feedback to stagesDesigns, runs, judges, corrects
Repeats until doneNoYesYes
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 ◀───────────────┘
  • input is 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.
  • brain is 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 for implement, 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

StatusMeans
doneThe brain judged the success condition met.
stuckEvery pass ran cleanly, but the condition was never met before the iteration cap ran out.
failedA stage hard-errored — a wedged tool call, a missing secret. The brain is never consulted.
waitingA stage parked the pass on an external signal.
cancelledYou 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.