Route reviews to a different family than the writer
flowctl config set review.backend codex ✓ The writer never grades its own work; the verdict still lands as a receipt on disk.
Review workflow →flow-next is an orchestration layer. The host agent conducts: it fans work out to tiered subagents, routes reviews to a different model family than the writer, optionally drives a second CLI agent through a headless bridge, and runs autonomous build/ship loops. Which model does what is a routing decision - and every routing decision in flow-next is either a parameter or a sentence of intent away. The second kind carries judgment.
Routing is one move on a larger menu. The doctrine (skip, reorder, prompt into, chain, parallelize, all under the same contracts) is Skipping and composing stages; the copy-paste recipes, including a model-routing section, live in the Cookbook. The same doctrine applied to subsystems rather than models is What each layer costs.
Optional chart discovery respects the same automation boundary as the rest of the menu: unattended drivers may fan out one invocation per open unattended D-ID (research / probe / eval); attended decisions (prototype, interview, attended task) terminate NEEDS_HUMAN and never self-resolve. Chart is not a pilot/build-loop stage - it ends at a briefing for capture.
Two words carry the whole routing story. A tier is what kind of model a job wants. Reach is how the active harness obtains one - the in-session model, an in-host subagent, shelling out to another CLI, or not available.
| Tier | What it means |
|---|---|
| reviewer | Anything grading work someone else produced. The only tier carrying a family rule: a reviewer from the writer’s own family is not an independent verdict. |
| implementer | Work handed to another harness. The load-bearing case - plan on the session model, implement somewhere cheaper or faster. Absent, the session model implements. |
| fast scout | Mechanical inventory scanning, where the cheapest model is the correct one. |
| thinking scout | Analysis that degrades badly on a fast model. |
| unset | The default, and the majority: planning, capture, interviews, requirement analysis, every verdict, and the worker run on the session model. This is the never-delegate-judgment doctrine, stated as the default rather than as a special case. |
Four names, chosen once. An unrecognized tier name is treated as unset, with one advisory line - never an error.
A tier says which model executes a stage, not which stages run. Which stages run is decided by what you invoked; asking for a leaner pipeline is a separate instruction that already works.
The family rule is advice, not enforcement. A model’s family cannot be verified from a name you invented, so the reviewer tier documents the rule, the receipt records what ran, and nothing fails closed on it.
Preferences live in your instruction file (CLAUDE.md / AGENTS.md), in your own words, naming models you can verify against your own account. One line per tier:
reviewer: <model>implementer: <model> at <effort>fast scout: <model>thinking scout: <model>An absent tier means the session model. An unparseable line is ignored with one advisory, never an error. Effort semantics stay the host’s - flow-next passes effort through and never translates between vendors’ scales. /flow-next:setup proposes this block commented out, for you to edit; nothing infers availability into it, and nothing rewrites a block a human has edited.
The block is the durable form of an ad-hoc instruction: written once, read every turn, and still beaten by an explicit instruction in the moment. /flow-next:setup offers to scaffold it with every value commented out, so nothing routes until you fill one in; it never asserts which models are installed, never overwrites a block a human edited, and is marker-fenced so /flow-next:uninstall removes it cleanly.
Tier names are durable; model identifiers are volatile. That asymmetry is why routing is expressed as tiers here and as model names only in your file.
Worked example, in a consumer’s own words:
you conduct + review (frontier, medium effort); implementation goes to<another model> via <its CLI>, one task per dispatchHighest first: an explicit argument in the invocation, then the project routing block in your instruction file, then the agent definition’s own default, then the session model.
There is no error surface: the chain terminates at the session model by construction. Agent definitions keep their model: field as the floor - what applies when nothing overrides - which is why a repo with no routing block behaves exactly as it always has.
A model this harness cannot reach - another vendor’s identifier, a retired one, one your account lacks - falls back to the session model, says so once, and continues. No probing, no question, no failure.
The review backend is separate: it keeps its own backend[:model[:effort]] configuration and its own documented precedence. The tiers never touch it.
Reach is documented once per harness, never inside a skill: a skill asks for a tier and never names a spawn primitive, a CLI flag, or a vendor path. The three mechanisms are the in-session model, an in-host subagent, and shelling out to another CLI.
| Harness | In-session model | In-host subagent | Shell out to another CLI |
|---|---|---|---|
| Claude Code | Yes | Yes - an agent definition’s model field is honored | Yes |
| OpenAI Codex | Yes | Yes, but per-spawn model selection is not dependable | Yes - the dependable route here |
| Factory Droid | Yes | Yes - reads flow-next’s agent definitions directly | Yes |
| Cursor | Yes | Yes, but an agent definition’s model field is ignored | Yes |
| xAI Grok Build | Yes | Yes - verified by a full planning fan-out | Yes |
| OpenCode | Yes | Yes (Task-tool subagents; confirm per major) | Yes |
| Anything else / undetectable | Assume yes | Assume no until observed | Assume no until observed |
An undetectable harness takes the last row and says so once. Guessing a harness is worse than naming the fallback: the generic row assumes the least reach and degrades cleanly.
Discovery beats declaration. Where a harness or a CLI can list what it offers, ask it at the moment of use - one command beats a stored fact that goes stale. This is why the tables and examples on this page name no model identifiers: which model fills a tier is a property of your account and your machine, not of a document.
Degradation is the same everywhere: a tier the harness cannot honor runs on the session model and says so once. That is the shipped default, so a harness with no dispatch mechanism at all still runs the whole pipeline - only the tier split is lost.
Two harnesses carry a caveat worth stating outright:
When the session is Cursor itself, orchestration differs from reaching Cursor models from another host via the headless cursor-agent CLI.
| Surface | What happens on a Cursor host |
|---|---|
| Agent-definition model fields | Ignored - subagents inherit the session model. There is no alias-to-slug rewrite mechanism and none is planned. |
| The escape hatch | Caller-side: name the model in the dispatch itself and the harness honors it (it also self-corrects a near-miss identifier). Slugs are volatile - ask cursor-agent --list-models immediately before pinning one rather than copying an identifier from a document. |
review.backend host | Bare only (host:<model> is rejected). Review runs as a host-native fresh-context subagent pinned to a family that did not write the diff - never the session model grading its own diff, no subprocess. Preferred default from inside Cursor. |
≠ the cursor CLI backend | review.backend cursor:… is a separate headless subprocess path (multi-family reach from outside Cursor; circular when you are already inside it). |
| Cross-family rule | Reviewer family ≠ writer family, measured from the writer. Fail-closed: without a cross-family pin, interactive setup asks; autonomous runs stop with NEEDS_HUMAN rather than silent same-family self-review. |
With no caller-side model in the dispatch, every tier resolves to the session model - which is exactly the shipped default and needs no configuration.
# In-session impl + host review (cross-family pin from the AGENTS.md routing block)flowctl config set review.backend host # or per-run: --review=host
# Bridges FROM a Cursor host - the same recipes, reverse directionclaude -p "<self-contained prompt>" --output-format text --allowedTools "Read,Bash" </dev/nullcodex exec -s read-only --skip-git-repo-check "<prompt>" </dev/nullDetails: Install → Cursor, Setup, Review workflow.
Skills are prompts executed by the host agent, not compiled code. That gives you two genuinely different routing methodologies - use both:
| Deterministic - parameters | Prompted - agentic intelligence | |
|---|---|---|
| What it is | Config keys, flags, per-spec/per-task fields. Machine-resolved, same answer every time | Policy described in natural language. The host judges per item - conditionally, mid-run |
| Example | flowctl config set review.backend codex | ”Work the three ready specs - decide per spec, by complexity, whether implementation goes out to a bridge or stays on the session model” |
| Reach | Exactly the surfaces that ship | Anything the host can do - including capabilities that don’t exist as parameters |
| When it wins | Headless/Ralph runs, stable team defaults, reproducibility | Per-item complexity calls, conditional escalation, inventing a routing the registry doesn’t have |
The two compose: parameters set the floor, prompting steers above it. Either can be made durable in CLAUDE.md / AGENTS.md - the host reads your instruction files every session, and flow-next skills inherit them automatically.
Most “will this override that?” questions dissolve once you see which layer you are talking to:
review.backend and the per-spec/per-task backend fields. This is what pilot ticks, Ralph runs, and unattended gates use when nobody is prompting. Standing changes for autonomous runs belong here, not in prose.The practical consequence: a prompt steers only the session it is typed in. If you want the 3am pilot tick to use a different reviewer, that is a config change - at 3am there is no prompt.
Two one-liners to start:
Route reviews to a different family than the writer
flowctl config set review.backend codex ✓ The writer never grades its own work; the verdict still lands as a receipt on disk.
Review workflow →Name an implementer tier once, in your own instruction file
implementer: <your model> at <effort> ✓ One line in CLAUDE.md / AGENTS.md, read every session including unattended ticks. Absent, the session model implements - nothing to enable.
The routing block →The review subsystem is the most routable surface, and it keeps its own configuration rather than reading these tiers: the spec grammar is backend[:model[:effort]] over rp | codex | copilot | cursor | host | none.
flowctl config set review.backend codex # project defaultflowctl config set review.backend host # host-native fresh-context subagent (bare only)flowctl config set review.backend codex:<model>:xhigh # explicit model + effortThe model that writes is never the model that reviews. Route the reviewer to a different family than your session model and blind spots stop being correlated. The ladder, the per-task pins, the precedence chain, and what the reviewer actually receives are in Review backends.
On the codex and host backends, the first review round of a scope draws three reviewers at once instead of one. Each draw runs the same backend, model, and base prompt and differs by a single axis line: correctness and logic of the changed code, contracts and consistency (do docs, tests, and stated promises agree with what the code does), and integration with unchanged code. The coordinator merges the three finding sets into one deduped set and runs a single fix pass. Re-review rounds after that fix are one dispatch carrying the full merged finding set. rp, copilot, and cursor keep a single dispatch every round.
Three draws because one is a sample, not a sweep. Pre-registered evals measured a single review pass as stochastic sampling of the validated finding pool, surfacing roughly 45% of it per draw; the union of three axis-differentiated draws reached 1.56x single-draw recall against a pre-registered 1.5x bar, at flat validity. Most of what used to trickle out across serial rounds now arrives in the first merged round.
Two costs come with that, and both are real. A clean one-round diff pays roughly 3x review tokens for findings one draw would have surfaced anyway. And roughly a third of validated findings eluded every draw, so round 2 shrinks rather than disappears. Those two facts are why the dials below exist - and reviews are optional to begin with, so the fan-out only ever applies to a layer you already chose to switch on.
The topology is steered by a sentence in the invocation. There is no flag and no config key: the coordinator reads your phrasing and hands the machinery explicit per-draw specs, and the machinery never reads prose.
Take the shipped shape - three axis draws, one merged fix pass.
/flow-next:work fn-14 ✓ Say nothing and you get the fan-out. The right default when an agent wrote the diff and it will be merged without a human reading it line by line.
Small, clean diff - one reviewer is enough.
/flow-next:work fn-12 - use 1 reviewer instead of 3 ✓ The round collapses to a single draw, and the roughly 3x token cost of the harvest goes with it. The same phrasing works on /flow-next:impl-review.
High-stakes merge - decorrelate families as well as axes.
/flow-next:impl-review fn-14 - use three different model families for the review fan-out ✓ Each draw routes to a named family, so blind spots differ by model as well as by axis. On the codex backend the primary draw stays on codex and the secondary draws may name codex, copilot, or cursor; on the host backend the per-draw pins are unconstrained.
Offloading the token-heavy part (writing code) to a second CLI is a routing decision you write, not a subsystem you configure. There is no packaged delegation mode and no delegation config: name an implementer tier and drive the other CLI through a headless bridge, either ad hoc in the session or as standing policy in your instruction file.
codex exec -m <model> -c model_reasoning_effort=<effort> "<self-contained prompt>"cursor-agent --model <model> --force "<self-contained prompt>"claude -p "<self-contained prompt>" # the same bridge in reverse, from a Codex/Cursor hostTwo rules survive from the packaged path and are not optional:
Full recipes, including the wrapper pattern for unattended loops, ship into the repo you work in and are read on demand with flowctl usage (## Orchestration & model steering).
Coming from delegate:codex? The packaged mode and its work.delegate* keys were removed in 4.0.0. Leftover keys in .flow/config.json are inert - flowctl names them once in a non-blocking advisory and otherwise ignores them. Run /flow-next:setup, accept the routing-block scaffold, and use the bridge recipes above.
A raw bridge call fails quietly outside an interactive session: codex exec refuses in about a second outside a trusted git directory, and cursor-agent blocks on a workspace-trust prompt and then exits “successfully” with empty output. A loop dies silently on either. The wrapper pattern that fixes it, and its two load-bearing rules, are in Driving a loop.
Applies to ad-hoc bridge reviews only - a hand-rolled review whose output a human reads directly. Put two things in the prompt: P0-P3 severity tiers plus spec-grounded verdicts, so an edge-case finding does not flip a ship gate; and optionally a minimal suggested fix and blast radius per finding when no fix loop follows the review.
The packaged /flow-next:impl-review prompt is deliberately not this shape: its find-vs-fix split (the reviewer returns findings; the internal fix loop investigates and fixes, with validator and iteration caps) is by design.
This is the mode parameters can’t reach: routing policy that’s conditional and per-item, decided against the actual work rather than fixed up front.
Per-item complexity routing - the host classifies, then routes:
Work through the three ready specs. Decide per spec, based on complexity,how the work stage runs: anything touching auth or the migration youimplement yourself on the session model; plain CRUD goes out to theimplementer tier over a bridge. Reviews come from a different family either way.Focus and scope steering - instruction the skill never anticipated, read as intent:
/flow-next:plan fn-12 --depth=deep - focus the research on the migration path; I care about rollback/flow-next:interview fn-12 - push hard on failure modes and operational edges, skip UI polish/flow-next:work fn-12 - the UI tasks stay with you; send the API plumbing out to a bridgeConditional escalation - routing that reacts to outcomes:
Run /flow-next:work fn-12 and bridge implementation out. If a task's reviewcomes back NEEDS_WORK twice, stop bridging that task and implement it yourselfon the session model.Prompting a capability into existence - no registry entry exists for a session-model reviewer; that didn’t stop this repo’s own loop from running fresh-context, session-model-reviewed rounds:
/flow-next:plan-review fn-12 - don't use the configured backend; spawn afresh-context subagent on the session model with the same review criteria,and feed its verdict into the fix loop like any other reviewer.Backends, reviewers, and bridged implementers are prompts plus plumbing - when a rung you want is missing, describe it and the host builds the arrangement on the spot. The deterministic flags (--review=<backend>, --depth=short) still work inline for the parts that are parameterized; prompting composes around them.
The orchestration patterns that emerged in the wild through mid-2026 all have a direct flow-next expression - most need one config key or one sentence:
| Pattern from the field | The idea | flow-next expression |
|---|---|---|
| Orchestrator → executor | The frontier model plans and judges; a cheaper, highly steerable model writes the code | An implementer tier plus a bridge recipe, ad hoc or as standing prose. Host keeps gating/git/review |
| Orchestrator → reader | Token-hungry, low-judgment reads run on fast models that report summaries back | Already the default: scouts run on the fast scout tier and return digests |
| Cross-family reviewer | The model that writes is never the model that reviews | review.backend <backend>; per-task review: pins exceptions |
| Effort discipline | Orchestrator at high, not max - top effort tiers are token furnaces on routine work | Session effort is yours; a bridged child takes its effort inline, and the routing block’s at <effort> makes the floor durable |
| Token-hungry offload | Computer use and live-app verification go to other agents; results come back as evidence | /flow-next:qa drives the app in its own context; workers run fresh-context and return receipts |
The routing this repo runs, stated in tier terms. It names no model identifiers on purpose: which model fills a tier is a property of your account and your harness, and only you can name it.
| Stage | Tier | Why |
|---|---|---|
| Plan (capture / interview / plan / plan-review critique) | unset - the session model | Spec authoring is inline and judgment-heavy; this is the never-delegate-judgment default |
| Plan-review | reviewer, from a different family than the planner | Uncorrelated blind spots on the highest-leverage artifact |
| Work (implementation) | implementer | Well-specified work runs correctly on a cheaper or faster tier; the saving is real only when the spec is clear |
| Impl-review, first pass | reviewer, measured from the writer - not the host | A reviewer from the family that wrote the diff re-correlates the blind spots |
| Impl-review, final gate | unset - the session model | The verdict, the severity call, and the blast-radius judgment stay with the conductor |
Notes that keep this honest:
This page lives in the docs site - outside the repo you’re working in. At use time the host agent reads two things that are always current with the installed plugin:
flowctl usage (the always-loaded CLAUDE.md / AGENTS.md block points agents at it). Its ## Orchestration & model steering section carries the headless bridge commands - codex exec, cursor-agent, and the reverse claude -p - plus the flow-next shortcuts (review.backend, per-task review:) and prompted-orchestration examples. The bridges run in every direction: any harness that can run Bash can be the conductor.CLAUDE.md / AGENTS.md, holding the durable routing block above.flowctl done.