v1.4.0next
Chain nodes

Fix loop and judge

When a node's fix loop opens, what its repair tasks are told, when the judge runs, and what each verdict does.

An exec node's fix_loop repairs the node and measures it again until it passes. This page is the loop's contract: when it opens, what runs in each cycle, and how the judge's verdict is read. For why loops and caps work the way they do, see Caps and budgets.

Keys

KeyMeaning
tasks or stepsThe repair. Runs as an ordered group, like a node's own steps. No task or step in it may take an on_failure.
judgeOptional. One task of any kind, which may not take an on_failure. The shipped one is strict_judge.
max_attemptsOptional, above 0. The loop's attempt limit.

The loop's limits resolve narrowest last, each replacing only what it sets:

  1. policy.yaml's loops.<node>.fix_loop entry, else its default (attempts and wall_clock_s);
  2. the node's policy: max_attempts, and timeout_minutes for the wall clock;
  3. the loop's own max_attempts;
  4. the work item's own max_attempts (kraft item set-policy).

See Policy. A node with a fix_loop cannot be read_only.

When the loop opens

After the node's tasks run (and after any on_failure recovery), Kraft reads every measuring task's findings and records a findings_measured event. The loop opens when either is true:

  • a finding's severity is in findings.loop_severities in policy.yaml (default critical and important);
  • a task failed without reporting any findings. Kraft writes one critical finding for it, as a subprocess task describes.

Otherwise the node completes. Findings below the loop severities are kept and shown at the review gate.

One cycle

Each cycle runs these checks in order:

  1. A measuring task ended needs_context: the item stops with its question.
  2. Every failure came from a task Kraft runs itself (a builtin or forge task), and nothing else reported a finding: the item stops, because no worker commit can change the outcome.
  3. A token or dollar budget is spent: the item stops.
  4. The judge, when it is due.
  5. The attempt count or wall clock is past its limit: <node>.fix_loop exhausted after N fix cycle(s).
  6. After a repair, the same set of loop-severity findings came back, or one finding came back unchanged three cycles running: stuck: ....

Steps 1 to 3 stop the item for you. Steps 5 and 6, and a judge's stop_needs_human, leave the node stuck: its escalation runs before the item stops.

If nothing stopped the loop, Kraft records fix_cycle_started, runs the repair, and measures the whole node again from its first step.

A repair that ends done, or that fails in an agent or subprocess task, spends the attempt. A repair that was paused, rate limited or refused to start, or whose builtin or forge step failed, did not try anything: Kraft gives the attempt back (fix_cycle_refunded) instead of measuring again.

What a repair task is told

A repair task's own prompt is not used. Its harness, profile, model and skill still are. Kraft writes its instruction instead:

  • which tasks failed, or that a review reported findings;
  • the loop-severity findings, each with its tag, a finding that was in the last measurement marked REPEAT;
  • the judge's reasoning, when the judge ran this cycle;
  • once there are two rounds, every round so far, with any finding that was fixed and came back;
  • the path of the previous attempt's result file and session summary.

The judge

The judge runs before every cycle except the first one of each entry into the node, which repairs without asking. It does not run when a steer from a person or a gate review is waiting to be delivered: the steer is the answer to the trend the judge would rule on.

Its own prompt is not used either. Its instruction lists every round so far with each finding's tag, the attempts used of the limit, and the seconds used of the wall clock. It answers in its result file: verdict, and its reasoning in concerns.

verdictWhat happens
continueThe cycle goes ahead. The repair task gets concerns as the judge's reasoning.
stop_needs_humanThe node is stuck with judge: and the reasoning.
stop_downgradeThe node completes with the remaining findings unresolved, and concerns is the note you see at the review gate. Only when no task in the node failed outright; otherwise the cycle goes ahead.

Kraft reads a verdict only from a judge that ended done or done_with_concerns. Any other status, a missing verdict or an unknown one counts as continue. A verdict never buys a cycle past the attempt limit or the wall clock: step 5 runs after the judge. A loop with no judge always continues. Each verdict is recorded as a judge_verdict event.

Copyright © 2026