Skip to main content
Give one model a brief and another model the job of checking it. This file has a Claude seat write a function and its test, runs the test with Node, and has a Codex seat read the files and the test result. If the reviewer sends the work back, the writer runs again with the findings, once.

The file

Change the brief, the file list and the test command to your own. Run it from the directory the work belongs in.

What a run printed

The output below is from one real run of this file, with the two command line tools signed in on the machine.
The writer left two files behind. src/add.mjs:
and test/add.test.mjs:
The reviewer wrote its decision to reviews/reviewer.json:

The team’s shape

The reviewer runs after the test, so it reads a result and not a promise. A rejection is a revision request aimed at writer, and maxKickbacks (default 1) bounds how many times the pair goes round.

Gotchas

  • The two seats must be different model families. The team refuses to build when writer.identity.modelFamily equals the reviewer’s. The check reads the identity you declare, so declare what runs.
  • A seat is an engine and its identity. The plugin runs the model; the identity is the record of what ran, and it is what the run record and the family check use.
  • The writer needs permission to write. A Claude or Codex seat started in a read-only mode returns a plan and no files, and the writer step then fails by name for the first missing file.
  • The test command runs in the workspace. Its arguments are relative to the directory you pass as workspace, which the file above sets to the current directory.
  • A writing seat can write anywhere the process can. The files above start their Claude and Codex seats with permission prompts off, which is what lets a model write files. Run them in a directory you are willing to let a model change, and give a reviewing seat a read-only mode if its plugin has one.

Source

The file is examples/teams/writer-reviewer-pair.ts. The teams package page lists every input.