Documentation

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

ProviderNeeds
OpenRouterOPENROUTER_API_KEY — one key, every model
Claude subscriptionthe claude CLI, signed in · macOS
Codex subscriptionthe codex CLI, signed in · macOS
Anthropic APIANTHROPIC_API_KEY
OpenAI APIOPENAI_API_KEY
OpenAI-compatibleCOMPATIBLE_BASE_URL + COMPATIBLE_API_KEY
Ollamanothing — talks to localhost:11434
Training dummynothing — 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

  1. Each gladiator defends a body: a process whose death ends its match.
  2. Its one weapon is a shell: ps and pgrep to look, kill to strike.
  3. Every blow is struck by the referee, and only at processes in the match.
  4. Striking a decoy stuns you. Striking your own body loses the match.
  5. First body to die loses. Both falling together, or the clock running out, is a draw.

Difficulty

BodiesDecoysWrong blowGates
Easyopponent’s pid givennone——
Normalshared marker in argv23s stun10s
Harddisguised, no marker6, breathing9s stun15s · 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:

CommandEffectCost
feint <name>plants a look-alike process; whoever strikes it is stunned ≥ 4s2s · up to 3
disguise <name>renames your own body in the process table3s · 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.

SandboxWhereWhat models can do
Guardedyour Mac, under Seatbeltlook at the match’s processes — no network, no home directory, no writes outside their corner, no signals
Sealeda throwaway containeranything, inside a read-only, capability-free, network-less container
  • Signals cannot leave the sandbox by any route; kill asks 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.

OptionMeaning
-g, --gladiatoradd a gladiator (repeat, or comma-separate)
-m, --modeduel, trial, or both (default)
-d, --difficultyeasy, normal, hard (default normal,hard)
-r, --roundsrounds per pairing per difficulty
--seedfirst arena seed, to replay a benchmark exactly
--time-limitseconds per match (default 180)
--dry-runprint 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

WhereKeys
Menus & wizard↑ ↓ move · ⏎ choose · ← back · l hall of champions · q leave
Model listtype to filter · r replace a stored key (provider list)
Arenav compact / full output · q leave
Verdictr rematch · n new match · s save preset · a the arena · l hall
Replayspace pause · ← → speed · s skip · esc leave
Seriesw watch a fight · r run again · esc stop a running series

Command reference

Command
colosseumopen the arena
colosseum --preset <name>fight a saved matchup straight away
colosseum replay [id]watch a recorded match again
colosseum presetslist saved matchups
colosseum series …the same matchup many times at once, with charts
colosseum bench …run a benchmark headlessly
colosseum leaderboardstandings from every match on record