Skip to main content
T3 · engineering: for_each + agent: is the swarm pattern. Every changed file gets its own mini-agent with read-only tools (default-deny means exactly that), a turn budget and a token budget. jq flattens the typed findings; one model writes the summary.

The job

Big PRs get shallow reviews because attention doesn’t scale. Here it does: each changed file is reviewed in isolation by an agent that can READ and nothing else, in parallel, four at a time. A deterministic nika:grep sweep counts the TODO debt beside the LLM pass, and the final REVIEW.md ends with a verdict.

The shape

Watch the graph execute: the human gate first, independent branches in parallel behind it, the agent fan-out mid-graph, and the join that waits for both branches before summary:

The file

pr-review-fanout.nika.yaml

How it works

1

exec output becomes a collection

git diff --name-only is a string; the jq split("\n") turns it into the array the fan-out iterates. Workflows turn ANY tool output into a collection this way.
2

Each agent is least-privilege

tools: ["nika:read", "nika:done"]: the reviewer can read source and end its loop. It cannot write, fetch, or wander. Budgets (max_turns: 6, max_tokens_total: 30000) bound the worst case.
3

Typed findings merge deterministically

Every agent returns {file, findings[]} per its schema. The jq fan-in flattens and sorts: blockers surface first in REVIEW.md.

Constructs you just used

Make it yours

  • Specialize the swarm: route *.rs files to a Rust-prompted agent and *.sql to a migrations-prompted one with two filtered fan-outs.
  • Add mcp:git/* to the tools to let reviewers read blame and history (still no write).
  • Fail CI on blockers: end with nika:assert on size() of the blocker slice.

Level up · T4 epic

Final tier: multi-stage pipelines. Plan, budgeted agent, thinking synthesis, self-reporting runs.