The trick is to use two agents on different models and let them loop until the reviewer says “Ship it.” One agent does the work. Here, it writes the code. The other tests and reviews it.
After each round, the reviewer approves or blocks with specific reasons for what to fix. They loop until the reviewer approves.
demo · Pair programming with two models30 s
$ls .cotal/agents
writer.md reviewer.md
$cotal spawn writer -d
$cotal spawn reviewer -H codex -d
avg.jse1094bf
function avg(xs) {
+ if (xs.length === 0) return 0;
let s = 0;
for (const x of xs) s += x;
return s / xs.length;
}
e1094bf BLOCK7c2e9a1 APPROVE
#pair
Claude CodeClaude Opus 5.5
#pair
CodexGPT-6 Astra
Two roles, two models, two commands.
In the demo, [] is an empty list and NaN means "not a number".
02
Why it works
01
Models favor their own work.
Models tend to rate their own work above equally good work from others, and some favor their model family too. Judges from different families showed less bias. [1][2][3]
02
Models get stuck in their own context.
Models miss errors in their own work that they catch in someone else's, and after a wrong turn they often don't recover. A fresh agent starts without those assumptions. [4][5]
03
Models fix well once told what's wrong.
They are poor at finding their own mistakes and good at fixing them once someone points them out. Without outside feedback, they can even make things worse. [6][7][8][9]
You can also add reviewers from other model families, or several reviewers with a specific focus each, so less gets missed. [3]
New to Cotal? Start with Get started. You'll need Claude Code and Codex signed in, and a Git project with tests.
Add two agent files.
Save these in your project's .cotal/agents folder. agent picks the app, model the model, and both talk only in #pair. Agent files
.cotal/agents/writer.md
---
name: writer
agent: claude
model: claude-opus-5-5
subscribe: [pair]
allowPublish: [pair]
---
You are the code writer. The code reviewer checks your work with another model.
Make the smallest change that does the task. Add a test. Run the tests, commit, and post the commit in #pair for @reviewer.
If blocked, fix valid problems. Say what you left unchanged and why. Post the new commit.
If what the code should do is unclear, ask in #pair and wait for an answer.
.cotal/agents/reviewer.md
---
name: reviewer
agent: codex
model: gpt-6-astra
subscribe: [pair]
allowPublish: [pair]
---
You are the code reviewer.
Review the commit the code writer names in #pair, cold: trust the code and the tests, not the writer.
Check what the change accepts but should reject, and rejects but should accept.
Run it where you can. Say what you only read. Check that each new test fails without the change.
Reply in #pair: BLOCK <commit> with one line per blocker, or APPROVE <commit>.
On a new commit, review only what changed since the last one. Never edit the code.
The first two commands start the agents in the background. The third gives the code writer its first task.
cotal spawn writer -d
cotal spawn reviewer -d
cotal send -t writer "Write avg(xs) in avg.js with a test. Then ask reviewer in #pair to break it."
Watch and make the call.
The console shows commits and verdicts live; to reply, run cotal send -t writer "your message" in another terminal. Once the code reviewer approves, check the code and tests yourself.
cotal console
04
Tips
1
Give the reviewer a stop rule.
Without one, two agents can argue the same point round after round.
Add to reviewer.mdAfter three BLOCKs on the same point, stop and ask the person in #pair.
2
One change per commit.
Small commits keep each review short and each BLOCK precise.
Add to writer.mdMake one change per commit, so each review covers one thing.
3
Ask for a repro with every BLOCK.
A vague blocker wastes a round. A repro shows the writer exactly what to fix.
Add to reviewer.mdFor each blocker, give the file, what breaks, and how to reproduce it.