{
 "claim": "ChessLFM says chess has 1,968 geometrically possible moves and turns each into one vocabulary token. I rebuilt that action space from scratch \u2014 every queen-like and knight-like (from, to) pair on an 8x8 board, plus every promotion move for all four pieces on both back ranks \u2014 and diffed it against the released tokenizer. The 1,968 is exactly right and the sets are identical, move for move. The tokenizer ships 1,969 move tokens, not 1,968: the extra one is <m:0000>, the UCI null move, which is not a move at all but the left-padding for the 8-ply history window. Every other token group matches the shipped vocabulary to the unit, and 1,969 + 64 + 73 = 2,106, the count surgery_meta.json reports.",
 "method": "Reconstructed the move set in Python from board geometry alone, then set-differenced it against the <m:*> keys in token_ids.json from the model repo. Group counts taken by prefix from the same file; totals cross-checked against surgery_meta.json (base_vocab_len 64402, num_added 2106, vocab_len 66508) and against config.json's vocab_size.",
 "source": "https://huggingface.co/mlabonne/LFM2.5-230M-Chess/blob/main/token_ids.json",
 "captured": "2026-09-18",
 "note": "Castling and en passant need no special tokens: the king's two-square move (e8g8) and the pawn's diagonal capture are already members of the geometric set. That is why an action space this small is closed under the rules of chess.",
 "columns": [
  {
   "key": "group",
   "label": "token group"
  },
  {
   "key": "reconstructed",
   "label": "rebuilt from geometry",
   "align": "right"
  },
  {
   "key": "shipped",
   "label": "in the released tokenizer",
   "align": "right"
  },
  {
   "key": "match",
   "label": "match"
  }
 ],
 "rows": [
  {
   "group": "queen-like and knight-like (from,to) pairs",
   "reconstructed": 1792,
   "shipped": 1792,
   "match": "yes"
  },
  {
   "group": "promotion moves (q, r, b, n; both colours)",
   "reconstructed": 176,
   "shipped": 176,
   "match": "yes"
  },
  {
   "group": "total geometric move space",
   "reconstructed": 1968,
   "shipped": 1968,
   "match": "yes"
  },
  {
   "group": "UCI null move <m:0000> (history padding)",
   "reconstructed": 0,
   "shipped": 1,
   "match": "no \u2014 extra"
  },
  {
   "group": "<m:*> tokens in the released tokenizer",
   "reconstructed": 1968,
   "shipped": 1969,
   "match": "no \u2014 extra"
  },
  {
   "group": "<v:*> win-probability bins",
   "reconstructed": 64,
   "shipped": 64,
   "match": "yes"
  },
  {
   "group": "board-cell tokens <c:*> (12 pieces + empty)",
   "reconstructed": 13,
   "shipped": 13,
   "match": "yes"
  },
  {
   "group": "castling-combination tokens <cast:*>",
   "reconstructed": 16,
   "shipped": 16,
   "match": "yes"
  },
  {
   "group": "en-passant file tokens <ep:*> (- plus a-h)",
   "reconstructed": 9,
   "shipped": 9,
   "match": "yes"
  },
  {
   "group": "halfmove-clock buckets <hm:*> (floor(min(hm,100)/4))",
   "reconstructed": 26,
   "shipped": 26,
   "match": "yes"
  },
  {
   "group": "repetition-count tokens <rep:*>",
   "reconstructed": 3,
   "shipped": 3,
   "match": "yes"
  },
  {
   "group": "side-to-move tokens <stm:*>",
   "reconstructed": 2,
   "shipped": 2,
   "match": "yes"
  },
  {
   "group": "structural tokens (pos, hist, eval, bestmove)",
   "reconstructed": 4,
   "shipped": 4,
   "match": "yes"
  },
  {
   "group": "TOTAL added by the tokenizer surgery",
   "reconstructed": 2105,
   "shipped": 2106,
   "match": "no \u2014 the null move"
  }
 ]
}