↑↓move ↵open escclose Players, teams and this week's games · type a position like "rb" for the list

Players, teams and this week's games. Type a position like "rb" for the list.

Releases

2.0.3

All releases, newest first

For you

  • Player grades in the track record now use the last projection published before each player's own game started, or the earliest one when none came before it, the rule game grades already used, instead of the first projection published that week. The figures by position move with it. Measured on the published run of 2026-10-10 (UTC). Quarterbacks: average miss 6.23 to 6.04 points, share inside the range stayed at 0.55, rank agreement stayed at 0.36. Running backs: average miss 4.23 to 4.14 points, share inside the range 0.50 to 0.51, rank agreement 0.69 to 0.71. Wide receivers: average miss 4.06 to 4.04 points, share inside the range stayed at 0.50, rank agreement 0.56 to 0.58. Tight ends: average miss 3.22 to 3.21 points, share inside the range 0.44 to 0.45, rank agreement 0.56 to 0.55. Every record published before stays as it was, and the record now carries a dated note saying so.
  • The game page can now show a game played at a neutral site, naming the two clubs with vs rather than at; a postponed game, keeping the call we published for it and explaining which call will be scored; and the last injury report that covered a game, with the time it is from, when a newer one has not come through. No game shows any of these yet, because the data starts carrying them in a later update.
  • Nothing on game pages looks different. Each game page is now built from one checked description of the game, so a panel can only show data it actually has.

Under the hood

  • One scoring module grades every published forecast: a harness that knows no sport (the standing call, Brier, log loss, accuracy, calibration error, range scores) and an NFL adapter that knows weeks, clubs, ties, snap attendance and the closing market. track_record.py now only assembles the file.
  • track_record.json gains engine1.ece, engine1.benchmarks (the closing market's Brier beside ours on the same finished games, ties left out of both, with the count, and a constant home rate from earlier seasons), engine1.by_week, engine2.by_week and corrections. No per game market probability is written to any file. A week's market comparison is shown only once every game in it has been played, including one postponed out of it, and every decided game in it has a closing price, and only when at least 2 games back it; the season figure counts only games in the weeks whose own block is shown. Every reader accepts the file unchanged.
  • The internal standings grade the same calls against the same results as the track record, including finals the facts channel confirmed before the next data refresh, and read a closing price only when it was captured after the final.
  • A golden check regenerates a frozen production run's record and lists every difference; a reduced copy of that run checks the same thing in CI.
  • The assistant tools' track record returns every market comparison block as null, the season one and each week's, and passes everything else through: those tools carry no market data, and a market number is shown only beside the research disclaimer.
  • The restore that runs before each track record now brings back every published edition's player projections and player freeze file, and the game forecasts of the editions a game can be graded on, including the newest of each week, which carries a moved kickoff. A player is graded on the last projection before his game that carries him, so the edition that matters can be any of them. Measured on run 2026-05-inactives-cba8348a, the restore used to grade 9 of 1,838 player weeks differently from a full one (players who did not play, dropped from the later projections before their game, or carried only after it); it now gives back the full restore's record exactly, so every figure by position is as the full record has it and the record counts 439 players who did not play rather than 438. The restore reads 145.9 MB on that run, up from 75.6 MB, and is projected at about 750 MB by week 18 against 291 MB before; its backstop now sits above a whole season's editions.
  • Eight new game page boards (E6 to E9 and ME6 to ME9) join the approved snapshots in design/boards, drawn as clones of the approved boards with only the new state's frames changed.
  • site/src/lib/game-contract.ts builds one typed object per game page: the game, our standing call, its forecast history and calibration, and ten sections, each fresh, last good with its own time, or absent for one named reason. The state types and the check that rejects a section outside its allowed states live in site/src/lib/section-state.ts and are re-exported from game-contract.ts. A section outside its allowed states fails the build, and every game panel renders from it.
  • The live game script and the final chart map their phases onto the same three states. Board builds mark each section's state on the page for the built page checks; production pages are built with no markers.
  • The schedule contract accepts an optional site (home or neutral) on each game and a postponed result. The site reads a game with no site as home. Nothing writes either field yet.
  • Each week's injury report can be read from its own file, injuries-week-NN.json, beside the current one.
  • On a final whose players our rankings did not cover, the Top performers section is now recorded as not covered rather than not yet. Its words on the page are unchanged.