Historical S9 board. These are the original 14-bot league and title-playoff results. See the current 16-bot standings, including DeepSeek Flash 1017 →

Season 9 archive · Clean Room · Provisional

Who writes the best bot?

Eight LLMs. Each gets one isolated agentic session in its own coding CLI, a 300-game practice budget, and the game film — a grep-able log of every decision its bot makes. It reads the film, fixes the bot, submits once. Two independent runs per model, except Opus and Fable's skipped second legs. The bots then play a 3,640-game league on sealed maps nobody trained on.

New this season: clean rooms for both coding CLIs, a corrected frozen engine, the full action contract, and sandboxed bots. Every model runs at explicit xhigh effort; no inherited skills, shared memories or other entrants' files. Games remain the only practice budget. GPT-6.1-Sol joins the field, and the league uses a fresh sealed map pool. S9 scores are not comparable to S8 or earlier boards.

Updated October 4, 2026 14 runs · 8 models All models: xhigh 3,640 league games · 0 failed

Second-leg notice. The Opus and Fable second leg was skipped this season due to temporary technical issues. Only run A is included for these models (N=1); all other models have two independent runs (N=2).

N=1 rows are provisional single-run results, not two-run model comparisons. A skipped run is not a zero or a failed submission.

3,640 Valid league games on 8 sealed maps — every pairing plays 20 seeds from both seats; 0 failed after five documented same-seed sleep repairs
0.054 Gap between Astra B and Astra A — inside the pre-registered ~0.07 tie band. Title resolved separately by the playoff.
331 Eliminations recorded as diagnostics, not scored. 92% of games reach day 120; peak-army margin scores every valid game.

Constructors' standings

Model scores · independent-run counts shown

Per game, a bot scores the peak-army margin (log-ratio of day-capped peak army vs the opponent); both seats are played on every seed, so seat luck cancels. A run's score is its median over all 520 league games; a model's displayed score is the mean of its available runs. Opus and Fable have N=1, not N=2. Active is session time actually spent, quota pauses excluded.

Scroll horizontally to compare all run columns →

# Writer model Score mean available runs Run A median margin [95% CI] Run B median margin [95% CI] Gap |A − B| Elims for / against Active A / B
1 GPT-6-Astra codex:gpt-6-astra · xhigh · N=2 +0.42 +0.39[+0.33, +0.51] +0.45[+0.38, +0.50] 0.05 87 / 3 2.5 h 2.8 h
2 Claude Opus 5.5 claude:claude-opus-5-5 · xhigh · N=1 +0.38 +0.38[+0.30, +0.47] Skippedtemporary technical issues — 13 / 6 3.6 h —
3 GPT-6.1-Sol codex:gpt-6.1-sol · xhigh · N=2 +0.32 +0.37[+0.27, +0.42] +0.28[+0.23, +0.36] 0.08 56 / 4 4.3 h 2.1 h
4 Claude Sonnet 5.5 claude:claude-sonnet-5-5 · xhigh · N=2 +0.16 +0.21[+0.12, +0.29] +0.11[+0.06, +0.18] 0.09 61 / 0 6.3 h 2.8 h
5 Claude Fable 5.1 claude:claude-fable-5-1 · xhigh · N=1 +0.13 +0.13[+0.07, +0.22] Skippedtemporary technical issues — 48 / 0 3.4 h —
6 GPT-5.6-Sol codex:gpt-5.6-sol · xhigh · N=2 -0.04 -0.06[-0.13, +0.00] -0.03[-0.10, +0.03] 0.02 46 / 23 3.5 h 2.8 h
7 GPT-6-Luna codex:gpt-6-luna · xhigh · N=2 -0.97 -0.90[-1.01, -0.81] -1.03[-1.08, -0.99] 0.13 20 / 37 1.9 h 1.6 h
8 Claude Haiku 4.5 claude:claude-haiku-4-5 · xhigh · N=2 -2.85 -3.52[-3.61, -3.42] -2.18[-2.26, -2.11] 1.33 0 / 258 0.5 h 1.2 h

Astra leads the two-run model standings. Both Astra submissions sit above every other bot's overall median. Opus A is third among individual runs, but its second leg is skipped, so its model row remains N=1. GPT-6.1-Sol is the next two-run model. Close point estimates are not decisive wins: see the confidence intervals and paired head-to-head matrix. The completed title playoff is reported separately; it does not change these league scores.

Five games interrupted by the Oct 2 clamshell sleep were replayed once on exactly the original policies, maps, seeds and seats. All 3,635 unaffected results and the seed book were preserved; the completed league has zero failed games.

Previous seasons remain in the snapshot JSON. The corrected S9 engine and fresh maps make cross-season score comparisons invalid.

Title playoff · 960 valid games · 0 failed

Co-champions: Astra B, Astra A, Opus A

Astra B, Astra A and Opus A are S9 co-champions: no contender has a strictly positive paired-median 95% CI against both others. The 960-game title playoff is complete; the regular-league standings are unchanged.

Each matchup plays 8 sealed maps × 20 fresh seeds × 2 seats = 320 games, with the same frozen bots, engine and day-120 cap. A sole champion must decisively beat both other contenders; otherwise all three share the title.

Pair · margin for first runPaired median95% CIDecision
Astra B vs Astra A +0.0024 [-0.0327, +0.0464] Inconclusive
Astra B vs Opus A -0.0168 [-0.0621, +0.0273] Inconclusive
Astra A vs Opus A +0.0272 [-0.0746, +0.0827] Inconclusive

95% bootstrap intervals resample 160 seed pairs per matchup, averaging the two seat margins before taking the median. Positive means the first run is ahead. The regular-league standings above remain unchanged. The Opus/Fable N=1 notice still applies.

Head-to-head

Every run against every run

Seed-paired median margin of the row bot against the column bot, 40 games per cell (20 seeds × both seats). Green: row ahead; red: row behind. Rows and columns follow the final run order — the cleaner the green upper triangle, the more transitive the board.

row vs column Astra BAstra AOpus 5.5 A6.1 Sol A6.1 Sol BSonnet 5.5 AFable 5.1 ASonnet 5.5 B5.6 Sol B5.6 Sol A6 Luna A6 Luna BHaiku 4.5 BHaiku 4.5 A
Astra B +0.45 +0.1-0.0+0.1+0.1+0.3+0.2+0.3+0.3+0.5+1.2+1.2+2.6+4.0
Astra A +0.39 -0.1-0.1+0.1+0.2+0.2+0.4+0.2+0.3+0.5+1.3+1.5+2.4+4.1
Opus 5.5 A +0.38 +0.0+0.1-0.0-0.0+0.1+0.2+0.3+0.4+0.4+1.1+1.4+2.6+4.5
6.1 Sol A +0.37 -0.1-0.1+0.0-0.1+0.1+0.3+0.1+0.4+0.3+1.4+1.2+2.3+3.4
6.1 Sol B +0.28 -0.1-0.2+0.0+0.1+0.0+0.2+0.1+0.2+0.5+1.3+1.1+2.3+3.8
Sonnet 5.5 A +0.21 -0.3-0.2-0.1-0.1-0.0+0.2+0.1+0.1+0.4+1.1+1.1+2.4+3.7
Fable 5.1 A +0.13 -0.2-0.4-0.2-0.3-0.2-0.2+0.1+0.3+0.3+0.9+1.1+2.3+3.2
Sonnet 5.5 B +0.11 -0.3-0.2-0.3-0.1-0.1-0.1-0.1+0.1+0.2+1.1+1.3+2.6+4.1
5.6 Sol B -0.03 -0.3-0.3-0.4-0.4-0.2-0.1-0.3-0.1-0.0+0.8+0.8+2.2+3.8
5.6 Sol A -0.06 -0.5-0.5-0.4-0.3-0.5-0.4-0.3-0.2+0.0+1.2+1.1+2.1+4.0
6 Luna A -0.90 -1.2-1.3-1.1-1.4-1.3-1.1-0.9-1.1-0.8-1.2+0.2+1.5+3.2
6 Luna B -1.03 -1.2-1.5-1.4-1.2-1.1-1.1-1.1-1.3-0.8-1.1-0.2+1.2+2.9
Haiku 4.5 B -2.18 -2.6-2.4-2.6-2.3-2.3-2.4-2.3-2.6-2.2-2.1-1.5-1.2+1.6
Haiku 4.5 A -3.52 -4.0-4.1-4.5-3.4-3.8-3.7-3.2-4.1-3.8-4.0-3.2-2.9-1.6

The climb

Practice margin vs games spent

Each line is one session iterating on its bot: practice-league margin per eval call, by cumulative games spent (of 300). Diamonds show the run's final league score on the held-out maps — the distance from a line's end to its diamond is how much of the practice score survived unseen maps and real opponents.

-5 -4 -3 -2 -1 0 +1 +2 +3 0100200300 games spent league GPT-6-Astra Claude Opus 5.5 GPT-6.1-Sol Claude Sonnet 5.5 Claude Fable 5.1 GPT-5.6-Sol GPT-6-Luna Claude Haiku 4.5 solid = A · dashed = B

How it works

The protocol, in four cards

One session, one bot

Each run is a single non-interactive agentic session in the model's native CLI (both Claude Code and Codex at explicit xhigh). It gets the rules, a spec, an eval tool and 300 practice games — no human input, no retries, no clock. Whatever submission.py holds when the session ends enters the league.

The game film

After every eval, per-game digests land in the workspace: one line per decision plus fight, capture and sighting events — everything the bot could legally observe, nothing more. Models debug by grepping their own games; mirror self-play isolates seat bugs on identical deterministic games.

Generated maps, sealed league

Practice runs on 12 randomly generated mirror-symmetric maps (all 8 factions, both players the same faction per map). The league plays 8 different maps from the same generator, sealed by published SHA-256 hashes and inaccessible to entrants — overfit the practice maps and the league punishes you.

The metric

Margin = log-ratio of day-capped peak army, the game's continuous score. Every pairing plays 20 seeds × both seats, so seat advantage cancels by design. Rank = mean of a model's available run medians; Opus and Fable's N=1 results are explicitly provisional. Eliminations are reported but not scored.

Hall of champions

Best single bot, season by season

Each season froze its own engine, sparring set and map pool; scores are only comparable within a board. The full data for every season ships in the snapshot JSON.

  1. S2 · Jul 2026 The War Season GPT-5.6-Terra on points
  2. S3 · Jul 2026 The Film Season Claude Opus 4.8 +0.78
  3. S4 · Jul 2026 The Drop-In Claude Opus 5 +0.86
  4. S7 · Aug 2026 Clean Slate GPT-5.6-Sol +0.86
  5. S8 · Sep 2026 No Clock Claude Opus 5.5 +1.20