workflow(), the reviewer must come from a different model family than
the writer. If the decision needs several views, ask a panel.
Shape
The team
Two roles and three stages. The writer is a Claude seat, the reviewer a Codex seat, and the test between them is a command:examples/teams/writer-reviewer-pair.ts (excerpt)
writes is checked after
the stage: a missing or empty file fails it by name, and so does a change to
another declared file. Node runs the test, and a red run carries its output
to write, which runs again with it. The reviewer reads the code, the test
and its result only after the test passes, and a rejection goes the same
way. refine: 1 on the writer allows one
refinement: the first build
and one more.
When the rounds run out before the reviewer passes the work, the run fails
with the last findings.
The two seats must come from different model families; workflow()
refuses the team before any model runs when they share one, so a model
never approves its own work.
What the run did
The brief isbriefs/add.md beside the file: its body is the task, and its
front matter names the files the writer must produce. Run the file from the
directory the work belongs in, with the Claude Code and Codex command line
tools signed in. One real run printed:
Output
src/add.mjs:
src/add.mjs
test/add.test.mjs:
test/add.test.mjs
claude('claude-sonnet-4-5') and
codex('gpt-5.6-luna') carry the identity the plugin records, and the
record and the family check read it. The Codex seat runs sandboxed to the
workspace with approvals off. Each helper takes an options object to choose
otherwise.
Full file
Full file
examples/teams/writer-reviewer-pair.ts
Next steps
- Feature delivery: the same builder, test and reviewers inside a seven-step team, from a ticket to a person’s approval.
- Runtime:
workflow,stage,briefFromFileand the keys of a stage. - Feedback loops: the shapes a review can take and the limit that stops the loop.