Open source · Python · runs on the logins you already have
Four AIs walk into a repo. One of them is paid to disagree.
Roundtable seats Claude, Codex, Grok, Gemini and your local models at one table and makes them do what a good team does: propose, attack the proposal, revise, build, run the tests, and report the argument honestly. No voting. No group hug.
Illustration. The real transcript is further down.
Asking one model to grade its own homework is not a review.
Sending the same prompt to five models and taking a vote is not a team either. It is a focus group. Roundtable gives each model a job, a limited view, and a reason to be difficult. The critic never learns who wrote the plan. The validator never sees the plan's reasoning, only the code and the test output. A model claiming something works is filed under "claims", not "evidence".
How it works
A meeting with an agenda, a bouncer, and a test suite.
A Python orchestrator owns the workflow. The models never talk to each other directly; everything goes through it, as validated JSON, into a SQLite log you can read afterwards.
Propose
The proposer turns your objective into a plan, assumptions, risks, and a checklist of acceptance criteria. If the job is too big for one sitting it says so instead of pretending.
Attack
The critic looks for wrong assumptions, missing edge cases, untestable criteria and unearned confidence. It is not allowed to accept with an open blocker, or to accept without saying what it checked.
Revise
The proposer answers every problem: fixed, rejected with a reason, or deferred. Ignoring one is not an option. Repeat until accepted or the round limit hits.
Lock
The acceptance criteria are hashed and frozen before any code exists. Nobody gets to move the goalposts after seeing the score.
Build
The engineer works inside a fresh git worktree on its own branch, with its own tools, the way you would run it by hand. The orchestrator commits the diff.
Test
The orchestrator runs your test command itself, with API keys stripped and a timeout. Exit code and output are recorded verbatim. This is the only source of truth.
Verify
A different model checks each locked criterion against the files and the real test output. "The code looks right" is rejected as evidence.
Report
What was built, what the tests said, every disagreement with both sides, the remaining risks, and the single most useful next experiment.
Budgets for calls, tokens, dollars, rounds and minutes are checked before every call. When one trips, the run stops and you still get the report. A halted run that explains itself beats a finished run that lies.
From an actual run
Four rounds of a team being useful to each other.
Objective: a small max-drawdown function with tests. Condensed from the audit log of run 53f500 on 2026-09-25. The names are the real models; the bugs were real too.
The point is the third Grok message. The tests all passed, and Grok noticed they would also have passed for a wrong implementation. That is the entire job of a critic, and it took twelve calls and twenty-five minutes on subscriptions, no API keys.
The seats
Every chair has a job. Nobody has all the tools.
Roles are config, not code. Point any seat at any backend: the CLIs you already pay for, a vendor API, or a model running on your own machine.
Writes the plan
Turns an objective into a claim, an approach, assumptions, risks and a definition of done. First it judges scope; an objective too big for one task gets split, not bluffed.
Sees: objective, requirements. Cannot touch files.
Finds what is wrong
Reads the plan cold, without knowing who wrote it, and hunts for wrong assumptions, logic errors, security holes, overfitting, missing edge cases and criteria that cannot be tested. Padding the list to look thorough is as bad as rubber-stamping.
Sees: the plan. Owns nothing; can only block.
Builds it
Runs as a real agent inside a disposable git worktree on its own branch, with its own editor and shell, and runs the tests itself before handing back. May not weaken a test to make it pass.
Sees: plan, locked criteria, the repo. Only writable seat.
Checks the receipts
Gets the locked criteria, the changed files and the real test output. Not the plan's reasoning, not the critic's opinions. Every criterion needs a citation: a file and line, a test name, a line of output.
Sees: artifact and evidence only.
Tells you the truth
Writes the report from the records, not from vibes. Keeps every disagreement with both positions. Its ACCEPT requires evidence; a plan-only or halted run is never a success.
Sees: everything, after the fact.
Runs the meeting
Plain Python. Picks the next stage from a fixed table, builds each seat's limited view, validates every reply against a schema, enforces budgets, commits diffs and runs tests. It is the only thing in the room that never has an opinion.
Sees: all of it. Is not a model.
House rules
Rules that make the disagreement worth having.
A model saying it works is never evidence.
Only an executed test, a cited line, or a quoted output counts. Confidence scores are recorded so you can see who was wrong and how sure they were.
The critic is not paid to agree.
An ACCEPT with no problems must list what was checked. An ACCEPT with an open blocker fails schema validation and goes back for repair.
Goalposts lock before the ball is kicked.
Acceptance criteria are hashed when the plan is accepted. The same idea protects your trading research from "tune until the backtest looks good".
Disagreements are kept, not averaged.
A criticism the proposer rejected or deferred appears in the report with both sides. Consensus is not forced, because forced consensus is how bugs get tenure.
Nobody gets everything.
Each seat receives a purpose-built context, never the whole transcript. Calls stay the same size in round three as in round one, and no seat can read another's mind.
The meeting has a budget and an end.
Calls, tokens, dollars, rounds, minutes. When one runs out the run stops and writes its report anyway. "Insufficient evidence" is a valid and respected outcome.
Nothing merges without you.
The engineer works on a branch in its own worktree. Your checkout is untouched. Read the diff, run it, merge it or delete it.
Everything is on the record.
Which model, which prompt, what it saw, what it produced, how many tokens, how long, what changed after. One SQLite file per project; one command to print it all.
Get started
Five minutes, zero API keys.
If you already run claude, codex or grok from a terminal, you already have everything Roundtable needs. It drives those same CLIs with your existing logins.
# get it git clone https://github.com/bronette/roundtable cd roundtable && uv sync # what can run right now? uv run roundtable providers -c examples/project.yaml # hold a meeting uv run roundtable run examples/project.yaml # read the minutes uv run roundtable calls <run_id> --full
project.repo to any directory. Git repos get a worktree on a new branch. Set test_command to whatever proves the work.project.yaml.