Skip to main content
Run the checks directly and give the writer their output when the work needs another pass. Use it for tests, builds, format checks or commands that check a deployed system. The command’s exit code decides what happens next. It can return the work to the writer or select the next part of the workflow, without a model interpreting the result. When the check needs judgement, get a second opinion.

Shape

The two commands

The tests run as a command with a target. When the command exits non-zero, the step returns a revision request aimed at implement, with the captured output as the finding:
examples/command-kickback.ts (excerpt)
Pass a command as an array when an argument has spaces or quotes of its own. Each entry is one argument. The string form splits on spaces and refuses a quote. The graph then puts a second command, size, between the test and two reviews, and each review carries a when:
examples/command-kickback.ts (excerpt)
passed('size') runs one review when the command exited 0, failed('size') the other when it didn’t. Both read the named dependency’s outcome through ctx.needs; a name the node doesn’t need is a configuration error, not a quiet false. The deciding node is optional: true, so its red result blocks nothing and the branches decide. Without that, a red result would block every step that needs it and the failed branch could never run; the dag refuses that shape and says why. The step whose condition isn’t met is skipped and recorded as skipped. Leave when off any branch that must run, because a skip doesn’t fail the run. failed means the command ran and failed; a dependency that never got to decide meets neither condition. maxKickbacks limits how many times the writer runs again. A number is one count for the whole graph; a map gives each target its own number of refinements. When a count is spent, the run fails with the last output as its reason instead of looping. The test node lists implement in acceptsKickbackTo: a node names every step it can send work back to, and a send-back anywhere else fails it with an error that names both steps.

What the run did

The writer here is a function that gets add wrong once, so the red test has something to carry. Run it with npx tsx command-kickback.ts:
Output
implement ran twice: the first attempt subtracted, the test exited 1, and its output went to implement, which ran again with it in hand. The change was small, so size exited 0 and only quick-review ran. No agent read the test output to decide any of that. The exit code did.
examples/command-kickback.ts

Next steps

  • Feature delivery: a test command that sends a red result back to the builder, as one of seven steps.
  • Feedback loops: the limit, and the other shapes a check can take.
  • Runtime: commandJob, passed, failed and dag.