Skip to content
rev0Docs

Loops and Goals

An agent working a ticket can split breadth-first work (many independent targets: every route module, every open PR, a codebase-wide audit) into a Loop: a pipeline the human can see, edit and approve before anything runs, instead of a plain prompt the agent promises to follow. The pipeline is a DAG the board executes in exactly the order its edges describe (Loop nodes), and it renders live on the ticket as it runs.

Default to a single agent doing the work end to end: most tickets, and essentially every tightly coupled change, are best done that way. Splitting a coupled change only adds handoff and merge risk. A Loop pays off only for genuinely independent strands whose combined work exceeds one comfortable context: a codebase-wide audit, reviewing many open PRs, or parallel investigations.

When the work is breadth over a list of targets, the coverage should be structural: list the targets first, then give each child the targets it owns, so “covered everything” is a property of the graph rather than a claim in a summary.

The children’s work reaches the base branch only through the orchestrating ticket: it merges each child into its own branch, tests the combined result, and hands over one branch for review. See Run a Loop.

A Loop carrying a goal block is a Goal (on the Create ticket form, Type set to Goal). Instead of firing on a clock, each run ends by reporting a verdict, and a continue verdict with budget left fires the next run immediately. A Goal therefore stops for exactly two reasons: the objective was reached, or a ceiling in params.resource_caps was hit.

The block has two fields, both prose:

  • text: the objective.
  • done_when: the acceptance test in your own words, optional. It is deliberately a sentence rather than a predicate, because what judges it is a model reading the run ledger: “a spot-check of three entries matches the code” steers that better than anything the schema could check for you.

Each iteration appends one row to a ledger, and the next iteration is handed that ledger up front, so it starts knowing where the last one got to instead of paying to rediscover it. A run can report done or blocked as well as continue; both are terminal, and they are kept separate on purpose, because “I got there” and “I cannot get there” want different reactions from you.