The rules of the arena.
Colosseum is a terminal game and a benchmark: two language models, each defending a real process, hunt each other with a shell until one body falls. This is everything you need to run it, fight in it and rank models with it.
Install
Node 20 or newer. Clone, build and link the CLI:
$ git clone https://github.com/jstEagle/Colosseum.git$ cd Colosseum$ npm install && npm run build$ npm link # makes `colosseum` available everywhere
The guarded arena and subscription gladiators need macOS (they are confined by Seatbelt). The sealed arena runs anywhere Docker does.
Your first match
$ colosseum
The arena opens on the main menu. Choose New match and the wizard walks you through both gladiators — provider, model, reasoning effort — and then the match: sandbox, difficulty and arena. Two cards at the top always show who is being set up and which field you are choosing.
With OpenRouter, paste your key when asked: it is checked against the provider and stored in ~/.colosseum/env with owner-only permissions. With a Claude or Codex subscription there is no key at all — the CLI must simply be installed and signed in. For your first fight, try one model against the training dummy on normal.
Providers
| Provider | Needs |
|---|---|
| OpenRouter | OPENROUTER_API_KEY — one key, every model |
| Claude subscription | the claude CLI, signed in · macOS |
| Codex subscription | the codex CLI, signed in · macOS |
| Anthropic API | ANTHROPIC_API_KEY |
| OpenAI API | OPENAI_API_KEY |
| OpenAI-compatible | COMPATIBLE_BASE_URL + COMPATIBLE_API_KEY |
| Ollama | nothing — talks to localhost:11434 |
| Training dummy | nothing — never fights back |
The model list comes live from the provider; type to filter it. Reasoning effort maps to each provider’s native control. A gladiator is only ever handed its own provider’s key.
The rules
- Each gladiator defends a body: a process whose death ends its match.
- Its one weapon is a shell:
psandpgrepto look,killto strike. - Every blow is struck by the referee, and only at processes in the match.
- Striking a decoy stuns you. Striking your own body loses the match.
- First body to die loses. Both falling together, or the clock running out, is a draw.
Difficulty
| Bodies | Decoys | Wrong blow | Gates | |
|---|---|---|---|---|
| Easy | opponent’s pid given | none | — | — |
| Normal | shared marker in argv | 2 | 3s stun | 10s |
| Hard | disguised, no marker | 6, breathing | 9s stun | 15s · 1.5s between blows |
On hard the decoys breathe: every few seconds they burn CPU and run a sandboxed ps wrapped exactly as a gladiator’s own commands are. Activity alone gives nobody away — a gladiator has to read what each process is doing, over time.
Defence
A gladiator is not only a hunter. Two moves make it harder to find, both enforced by the referee:
| Command | Effect | Cost |
|---|---|---|
feint <name> | plants a look-alike process; whoever strikes it is stunned ≥ 4s | 2s · up to 3 |
disguise <name> | renames your own body in the process table | 3s · once |
On normal and hard, every match opens with the gates closed: blows are refused for the first 10 or 15 seconds, so there is time to scout, plant feints and slip into a disguise before the fight begins.
Sandboxes & security
Colosseum hands language models a real shell, so a match always runs inside a sandbox. There is no unconfined mode.
| Sandbox | Where | What models can do |
|---|---|---|
| Guarded | your Mac, under Seatbelt | look at the match’s processes — no network, no home directory, no writes outside their corner, no signals |
| Sealed | a throwaway container | anything, inside a read-only, capability-free, network-less container |
- Signals cannot leave the sandbox by any route;
killasks the referee, which refuses bystanders. - Shells get a clean environment: no API keys, no cloud credentials.
- Each side’s scratch corner is unreadable to the other, and named at random.
- Subscription CLIs get one tool, a shell — none of your MCP servers, hooks or settings — and may not write to your home directory.
- Everything printed to your terminal is stripped of escape sequences.
Series: many fights at once
For a quick answer to which of these two is stronger, choose a series at the last step of setup — 3, 5, 10 or 20 fights. They run at once, each in its own sandbox, the two gladiators swapping sides every other fight. When the last one ends you get the verdict and the charts: win share with a 95% interval, an exact binomial test saying whether the gap is real, fight by fight, kill times on one axis, and the tally. w opens any fight as a replay.
$ colosseum series -g openrouter:stealth/space-bunny-alpha@low \$ -g openrouter:stealth/space-bunny-alpha@high -n 10 -d hard
Benchmarking
$ colosseum bench -g openrouter:openai/o4-mini@high -g claude-cli:sonnet -d normal,hard -r 2$ colosseum leaderboard
A gladiator is provider:model[@reasoning]. A benchmark runs duels — every pairing, from both sides, on the same seeded maze — and trials against the training dummy. Each match is appended to ~/.colosseum/matches.jsonl the moment it ends, with its config, seed, outcome, every blow and every token.
| Option | Meaning |
|---|---|
-g, --gladiator | add a gladiator (repeat, or comma-separate) |
-m, --mode | duel, trial, or both (default) |
-d, --difficulty | easy, normal, hard (default normal,hard) |
-r, --rounds | rounds per pairing per difficulty |
--seed | first arena seed, to replay a benchmark exactly |
--time-limit | seconds per match (default 180) |
--dry-run | print the schedule and stop |
The leaderboard rates duels with Bradley–Terry on the Elo scale and reports kill time, trial success and hunt time, wrong blows, feints that fooled, and tokens per match. It counts only matches from the current version.
Presets & replays
Every match is recorded. The main menu offers a rematch, your saved presets and recent replays; on the verdict screen r rematches and s saves the matchup.
$ colosseum --preset "my ladder"$ colosseum replay # the latest match$ colosseum presets
Controls
| Where | Keys |
|---|---|
| Menus & wizard | ↑ ↓ move · ⏎ choose · ← back · l hall of champions · q leave |
| Model list | type to filter · r replace a stored key (provider list) |
| Arena | v compact / full output · q leave |
| Verdict | r rematch · n new match · s save preset · a the arena · l hall |
| Replay | space pause · ← → speed · s skip · esc leave |
| Series | w watch a fight · r run again · esc stop a running series |
Command reference
| Command | |
|---|---|
colosseum | open the arena |
colosseum --preset <name> | fight a saved matchup straight away |
colosseum replay [id] | watch a recorded match again |
colosseum presets | list saved matchups |
colosseum series … | the same matchup many times at once, with charts |
colosseum bench … | run a benchmark headlessly |
colosseum leaderboard | standings from every match on record |