Tactical Reroll
⋯

Outcomes per unit, and the faction tables' terms (T-571)

From reports/tiers/2026-10-03-outcomes.md , rendered when the site is built.

3 Oct 2026 (UTC). Step 1 of design/tier-plan.md's queue: the outcome yardsticks (plan section 5, items 2 and 3; design/matrix.md sections 6.3 and 9). This is a report only. Nothing in it reaches the site.

Credit. The tournament lists come from grimstat-corpus at commit 570b8c6. The compilation is published under CC BY 4.0, and the lists were published by their players and organisers on MiniHeadQuarters (miniheadquarters.com). We didn't read the corpus's listhammer/ folder. Everything below is our own counts and averages. It holds no list text and no player or event names.

In one paragraph

From the corpus's last three months (July to September 2026) we placed 382 lists from 23 events across 33 armies. Every list has a final placing and none has a game record: the corpus's top-level files carry final placings only, with no round-by-round results and no win-loss records. We matched unit names to our stubs with the app's own list importer. 6,337 of 7,340 unit lines matched (86%), and every matched name is in docs/data/index.json. We set aside 92 lists because fewer than 85% of their units matched; most were exported from the GW app in French. A unit's lift is the mean finishing percentile of its army's lists that include it, minus the mean of the lists that don't, and it is noisy. Of the 418 units with three or more lists on each side, 33 (7.9%) have a 95% interval clear of zero, where chance alone would give about 21 (5%). There is a signal, but at today's volume it is only strong enough to test the engine across many units at once. It can't grade a single unit. Nobody lets a machine read their faction-versus-faction tables: no candidate's terms allow it:

All of them are listed in tools/sources.json, switched off. Jordan decides whether to ask.

What was loaded

node tools/outcomes.js --corpus build/grimstat-corpus --out reports/tiers/2026-10-03-outcomes.json runs in about a second. The corpus is cloned at run time (a shallow clone of https://github.com/N041M/grimstat-corpus) into build/grimstat-corpus/, which git ignores like every file under build/.

Coverage

Count
List entries in the window513
Set aside: under 85% of units matched92
Set aside: under 1,500 points39
Lists kept, all placed382
Events23 (France and Belgium, mostly 2,000-point singles)
Armies33 of 36
Unit lines in all parsed lists (matched)7,340 (6,337, 86%)
Matched names not in our stubs0
Distinct army-unit pairs in kept lists933
Lists with game records0

Lists per army:

ArmyLists
Necrons32
Adeptus Custodes28
T'au Empire23
Tyranids23
Dark Angels22
Emperor's Children19
Orks16
Chaos Daemons15
Aeldari15
Death Guard13
Astra Militarum13
Grey Knights13
World Eaters12
Adeptus Mechanicus12
Imperial Knights12
Drukhari12
Chaos Space Marines11
Adepta Sororitas11
Blood Angels11
Leagues of Votann11
Space Wolves10
Ultramarines10
Thousand Sons8
Salamanders7
Chaos Knights5
Genestealer Cults4
Black Templars3
Raven Guard3
Imperial Fists2
Iron Hands2
Space Marines2
Deathwatch1
Agents of the Imperium1
Every Adeptus Astartes chapter, pooled73

Unmatched names: 1,003 unit lines across 767 distinct names. The JSON's unmatched lists them all, by army, with counts. About four in five come from the GW app's French export ("Ligne 1 : 20 Carnivores Kroot", "Héros épiques 2 : …"), which the importer doesn't read. The rest are spellings and allies the importer misses:

Teaching roster.js these forms would bring back up to 92 lists, about a quarter more data. That is a later card. The prefix forms and counts are a parsing change; French names would need a name table of our own.

Game results: what exists

That is exactly what both yardsticks need: the win rate with and without a unit, and faction-versus-faction results we would compute ourselves. It waits on Listhammer's OK (T-411; the permission email is on T-418). tools/outcomes.js will read records as soon as a source that has them is switched on.

The sanity view: top and bottom 10 by placing lift

These tables show units with three or more lists on each side, ranked by lift. The percentiles and lifts are in percentile points, where a list's finish runs from 0 to 100. The samples are small: Tyranids and Orks have only 23 and 16 lists in all.

Tyranids: 23 lists, mean percentile 54; 31 units with 3+ lists each side

Top 10

UnitLists with / withoutPercentile withwithoutLift (points)95% interval
The Swarmlord13 / 107033+3711 to 62
Tyrant Guard4 / 197050+20-19 to 58
Exocrine4 / 196851+18-21 to 56
Gargoyles3 / 206851+17-27 to 61
Tyranid Prime with Lash Whip11 / 126048+13-17 to 42
Tyranid Warriors with Melee Bio-Weapons4 / 196452+12-27 to 51
Norn Emissary8 / 156150+11-20 to 42
Lictor11 / 125750+7-23 to 37
Broodlord9 / 145851+7-24 to 37
Norn Assimilator5 / 185753+5-32 to 41

Bottom 10

UnitLists with / withoutPercentile withwithoutLift (points)95% interval
Zoanthropes16 / 74475-30-60 to 0
Carnifexes4 / 192959-30-67 to 8
Old One Eye4 / 193258-26-64 to 12
Neurotyrant17 / 64871-23-56 to 9
Von Ryan's Leapers12 / 114662-15-45 to 14
Hormagaunts13 / 104762-15-45 to 14
Screamer-killer3 / 204355-12-56 to 32
Hive Tyrant6 / 174856-8-42 to 26
The Red Terror10 / 135057-7-37 to 23
Trygon6 / 174955-7-41 to 27

Space Marines (every chapter pooled): 73 lists, mean percentile 48; 90 units with 3+ lists each side

Top 10

UnitLists with / withoutPercentile withwithoutLift (points)95% interval
Wolf Scouts4 / 698846+4211 to 73
Heavy Intercessor Squad3 / 708446+381 to 74
Venerable Dreadnought4 / 697746+31-1 to 63
Arjac Rockfist5 / 687746+312 to 59
Company Heroes9 / 646845+220 to 44
Captain6 / 676646+19-7 to 46
Logan Grimnar9 / 646346+17-5 to 39
Wolf Guard Terminators9 / 646346+17-5 to 39
Storm Speeder Hammerstrike4 / 696347+16-17 to 48
Wolf Priest6 / 676247+15-12 to 42

Bottom 10

UnitLists with / withoutPercentile withwithoutLift (points)95% interval
Ballistus Dreadnought6 / 671951-32-58 to -6
Reiver Squad4 / 692150-29-61 to 3
Vanguard Veteran Squad with Jump Packs6 / 672350-28-54 to -1
Librarian19 / 542855-28-43 to -12
Commander Dante8 / 652651-25-48 to -2
Chaplain with Jump Pack6 / 672650-24-50 to 3
Librarian in Phobos Armour4 / 692749-22-54 to 10
Sternguard Veteran Squad11 / 623251-19-39 to 2
Uriel Ventris4 / 693149-18-50 to 15
Aethon Shaan3 / 703149-17-55 to 20

Orks: 16 lists, mean percentile 40; 21 units with 3+ lists each side

Top 10

UnitLists with / withoutPercentile withwithoutLift (points)95% interval
Flash Gitz9 / 75816+4217 to 67
Beastboss on Squigosaur4 / 126631+351 to 70
Meganobz4 / 126232+31-5 to 66
Tankbustas6 / 105531+24-9 to 57
Bigboss4 / 125734+23-15 to 61
Painboy10 / 64530+15-19 to 50
Zodgrod Wortsnagga4 / 125036+14-25 to 53
Wazdakka Gutsmek11 / 54430+14-23 to 50
Trukk9 / 74434+10-24 to 45
Bannernob5 / 114238+4-33 to 41

Bottom 10

UnitLists with / withoutPercentile withwithoutLift (points)95% interval
Big Mek Dakkarig7 / 92253-31-61 to -1
Mozrog Skragbad8 / 82752-25-56 to 7
Warboss9 / 72953-24-56 to 8
Beast Snagga Boyz5 / 113044-14-50 to 23
Lootas [Legends]4 / 123043-13-52 to 26
Stormboyz7 / 93741-4-39 to 31
Beastboss4 / 123740-4-43 to 36
Squighog Boyz7 / 93841-3-38 to 32
Kommandos10 / 64038+2-34 to 38
Big Mek with Shokk Attack Gun8 / 84138+2-32 to 37

Reading it

A single unit's lift should not move its letter.

Faction-versus-faction tables: the terms

Each site was checked on 2 Oct with tools/sources/check.js (its robots.txt and the pages about terms, one request a second under our named agent). statcheck, goonhammer and metawatch were added to its list of platforms, and Stat Check's dashboard, Tabletop Battles and Tableau Public were checked by hand. Nothing was scraped and nothing was stored except our notes.

SourceWhat it hasrobots.txtTermsMay a machine read the numbers?
Stat Check (stat-check.com/the-meta)11th-edition faction and faction-versus-faction win rates, as a Tableau Public dashboard embedded in the pageLets general agents read the page (keeps them off /api/, /static/, /search and others), and names a list of AI crawlers to keep out entirelyNone: no terms, legal or licence page in the site or its sitemap; only a contact address. The dashboard sits on Tableau Public, whose own terms page refused our read (403)No permission given. Silence isn't a licence, and its robots.txt shows it doesn't want AI-driven crawling. Ask first
40kstats (40kstats.tabletopbattles.com; 40kstats.goonhammer.com redirects there)Win rate faction against faction, by detachment, by missionNone (the address serves the app page)None on the stats site. tabletopbattles.com and goonhammer.com answer machines with a bot check (HTTP 202, empty), so their terms are unreadable to usNo. The bot check is a no to machines. Ask first
Metawatch (Games Workshop, warhammer-community.com)Faction win rates in articlesAllows readingIts terms of use forbid reproducing, duplicating or copying any part of the site without express permissionNo, and our hard rule is never to host GW content. Cross-check by eye only
Listhammer (/stats)Faction win rates, from Best Coast Pairings and Tabletop Herald eventsKeeps machines off /api/, /events/, /players/ and /list/No licence on the site. The corpus's copy of its results is outside CC BYNo, until Listhammer agrees (T-411, T-418). Its data would let us compute faction-versus-faction ourselves, which is the cleanest route
Hutber (stats.hutber.com)Faction statsHTTP 429 to machines (bot checkpoint)Unreadable (already noted for T-412)No

Verdict: none allows it today. Jordan's 30 Sep rule already treats these tables as a cross-check only (T-332: nothing of theirs on the site, not even a link). That rule still holds.

In what form a yardstick could be stored, if a source agrees:

  1. Never their table. Their numbers, even reformatted, stay out of the repository and out of docs/.
  2. Our computed agreement only. From design/matrix.md 9, we would keep the ρ between our predicted pair margins and their pair win rates (over pairs with 30+ games, weighted by games), the Brier score against an army-only baseline, and the number of pairs. Their numbers would be read at run time into memory or build/, which git ignores, and thrown away. This needs the source's yes for a machine to read it, even though nothing of theirs is kept.
  3. Better: compute faction-versus-faction ourselves from game records a source licenses (Listhammer's games through the corpus, once agreed). Then the yardstick is entirely ours: our counts of games between armies, credited, with no one's table involved. This is the recommendation.

Until one of these is open, the army-against-army yardstick can't run. The per-unit outcomes above can.

Files

Doubts

For the supervisor

Ready to paste into design/decisions.md:

3 Oct: T-571 outcomes per unit and the faction tables' terms (queue step 1, yardsticks)

  • What changed: tools/outcomes.js reads every placed list from the sources switched on (grimstat-corpus's top-level files, CC BY 4.0; listhammer/ not read) and writes, per army and unit, lists with and without the unit, the mean finishing percentile each side, the lift with a 95% interval (Student's t, pooled variance), and win rates whenever a source gives game records. Report: reports/tiers/2026-10-03-outcomes.md and .json.
  • Numbers: 382 lists, 23 events, 33 armies (July to September); 86% of unit lines matched, 0 outside our stubs; 92 lists set aside under 85% matched (mostly French exports) and 39 under 1,500 points. Of 418 units with 3+ lists each side, 33 (7.9%) have an interval clear of zero, against about 21 (5%) by chance.
  • Game results: none. The licensed files carry final placings only. Round-by-round games exist only in listhammer/, which waits on Listhammer's OK.
  • Faction tables: none allows a machine read (Stat Check: no terms, AI crawlers named out; 40kstats and Goonhammer: bot check; Metawatch: no copying; Listhammer: no licence). All are listed off in tools/sources.json.
  • Decided alone: the latest 3 months as the window; lists under 1,500 points dropped; the field size taken as the larger of lists held and top placing; Student's pooled-variance t in place of Welch (Welch gave intervals far too narrow for 3-list sides); chapters pooled as an extra view, not in place of the per-chapter rows.
  • Use: a yardstick in aggregate only (the correlation of letters with lift, weighted by the smaller side; the S/A hit rate on positive lift). A single unit's lift should never move its letter. If a source agrees, the army-against-army yardstick stores our agreement numbers only, never their table; computing it ourselves from licensed game records is preferred.
  • Next: teach roster.js the French export and the missing spellings (up to 92 more lists); Jordan's call on asking Stat Check and Tabletop Battles; the Listhammer reply (T-418).

Ready to paste as a scoring.md changelog line:

  • 3 Oct 2026 (T-571): outcome yardstick added, not used in scoring: tools/outcomes.js, the placing lift per unit (mean finishing percentile of the army's lists with it minus without, Student's t 95% interval, pooled variance) and win rate with and without when game records exist (none today); reports/tiers/2026-10-03-outcomes. No published number changes.