Skip to content

Stage 5 · Loop

Stage 5 hands your backlog to an autonomous coding loop. The loop implements each item in a fresh context, runs your verification command, and commits per item. The default runner is rauf; the runner is configured, not hardcoded (see the loopRunner config).

The loop picks the next pending backlog item, spawns a coding agent with that item as its entire brief, runs the project’s test/type-check command, and — on success — commits the item and advances. Because each item runs in a fresh context (no memory of prior items), backlog items must be self-contained. See fresh context per item.

The Stage-5 loop: pick the next pending item, spawn a fresh-context coding agent, run the verification command; on pass commit and mark done then advance; the agent can also signal BLOCKED or NEEDS_HUMAN; when no items remain, the loop completes. The Stage-5 loop: pick the next pending item, spawn a fresh-context coding agent, run the verification command; on pass commit and mark done then advance; the agent can also signal BLOCKED or NEEDS_HUMAN; when no items remain, the loop completes.
Terminal window
/feature-forge:forge-5-loop <feature-name>

(/feature-forge:forge-5-rauf-loop is an equivalent alias.) Before launching, Feature Forge previews the run, checks prerequisites, and — if your runner supports agent selection — lets you choose the coding agent. The loop runs in the background and is supervised live; you don’t need to babysit it.

  • A complete backlog.json (from Stage 4).
  • The loopRunner config from forge.config.json (defaults to rauf).
  • The project’s verification command (testCommand / typeCheckCommand).
  • Implemented source code, committed per backlog item by the runner.
  • Loop state and logs under the runner’s state dir (rauf: .rauf/, with state.json, events.ndjson, and rauf.log).
  • An updated .pipeline-state.json (Stage 5 marked complete when all items are done).
  • The run preview (command, backlog summary) and any agent selection.
  • The live progress as items complete.
  • Whatever the loop flags as blocked or needing a human (see signals below).
  • Run the Verify & Fix gate on the implementation — recommended before generating docs. With autoVerify enabled for forge-5-loop, this impl-verify runs automatically once the loop completes.
  • Generate documentation with Stage 6.

When the loop finishes, forge prints the next command in a copyable code block, so it’s a single tap to copy on mobile or a remote host.

The loop runs in the background and survives the session that launched it. Each backlog item gets its own fresh agent session (no memory of prior items), which is why items must be self-contained. State for each feature is isolated under the runner’s state dir — {backlogDir}/{loopRunner.stateDir} (rauf default .rauf/) — so concurrent features never collide.

While the loop runs, Feature Forge supervises it live by reading rauf’s native events.ndjson event stream (it does not redirect the loop’s output). As items finish, item_completed events tally progress; item_blocked and loop_error are surfaced immediately. When an item emits needs_human, the session pushes you a notification and collects your answer for a post-run retry — the loop does not pause, it keeps working the rest of the backlog. You don’t need to babysit a terminal, though you still can with the rauf commands below.

See Sessions & monitoring for how loop sessions fit alongside pipeline state and the navigator’s context checks.

The loop records which branch a feature’s work lives on, but treats that record as a self-healing hint, not gospel. This matters on hosted surfaces (Claude.ai remote, cloud agents) that impose an arbitrary session branch (e.g. claude/<slug>): that imposed name can get recorded, and if you later move the work to your intended topic branch, the stale record would otherwise make the loop offer to switch you back. Before launching, the loop’s pre-flight reconciles against where your pipeline state actually resolves:

  • Adopt the current branch — you’re on a non-default topic branch where the state resolves and the recorded name differs. The loop updates the record to match your current branch, with a visible one-line note. It never pushes you back to the stale name.
  • Warn on drift — you’re on the default branch while the state records a topic branch. The loop recommends creating/switching to the topic branch, but still lets you proceed on the default branch.
  • Nothing to do — the record already matches; the loop proceeds.

The current classification is also captured (as branchReconcile) by the doctor diagnostic — python3 <plugin-root>/scripts/forge-session.py doctor --json — if you want to inspect it outside a run.

You can observe and steer the rauf loop directly from a terminal:

Terminal window
rauf status <path> # one-shot snapshot: state, current item, counts
rauf status <path> --follow # live-refreshing status
rauf follow <path> # rich live event view
rauf log <path> --follow # tail the human-readable log
rauf loop stop <path> # stop a running loop
rauf resume <path> # continue where it left off

Each item’s agent reports one of three outcomes:

  • RAUF_DONE — all acceptance criteria passed; the item is committed and the loop moves on.
  • RAUF_BLOCKED — a missing dependency or unclear requirement; the item is set aside as blocked.
  • RAUF_NEEDS_HUMAN — a decision, secret, or API key is required; the item is set aside and the loop keeps working other runnable items.

The runner does not pause for input. Blocked and needs-human items are surfaced live (watch them with rauf follow/rauf status) and set aside while the rest of the backlog runs to completion. To resolve a set-aside item, supply the missing decision or secret and then re-run the loop — it picks up the items that were set aside:

Terminal window
rauf resume <path> # continue the loop; retries set-aside items

If the answer changes the plan, stop the loop early (rauf loop stop <path>), adjust the backlog, and re-run.

  • The backlog should be created (and ideally verified) first.
  • rauf must be installed and meet the minimum version (0.6.0), and set up in the project (rauf install . creates .rauf.json). See Install.
  • The runner refuses a dirty working tree; the stage commits pipeline state before launching.
  • If you run a non-default agent but your items carry Claude model aliases, the loop warns and offers to strip them. Agent precedence: item.model > run --agent > project defaultAgent > runner default. See Cross-agent usage.
  • For epic members, an unmet dependency triggers a gate you must explicitly clear.
  • rauf internals (full CLI, recovery, archives) live in the rauf repository.