feed your machine

Revision policy

Upstream republishes whole seasons. This is the decision about which of those republications create a queryable revision of history — the setting that determines both storage cost and whether backtests are honest.

observed changes → always a revision remodel_creates_revision = True float_precision = 6

The two options

active — full fidelity

remodel_creates_revision = True

A model refit opens a new version for every affected row. An as-of query returns the EPA nflverse actually published on that date.

  • Backtests are lookahead-free
  • The feature nobody else sells
  • One refit writes ~5,979,895 row versions at current scale
  • Refits are not rare
alternative — compact

remodel_creates_revision = False

Only real-world corrections get versions. Model output always reads latest.

  • Store stays small
  • Corrections still fully tracked
  • Every backtest silently inherits lookahead bias
  • Which is the defect fbdata exists to fix

Two decisions baked into the current default

Precedence when both groups move

Observed changes win. If a genuine league stat correction lands in the same republication as a refit, it is recorded as a correction, never a remodel — a real correction is the one revision class a customer cannot reconstruct from anywhere else, so it must not be masked.

There is a third option, currently blocked

Model outputs could be versioned against the upstream model version rather than per row. A refit would then cost one row instead of ~5,979,895, and as-of would still resolve correctly. Strictly better — except nflverse does not publish a model version, so there is nothing to key on. Worth raising with them.

Implemented in src/fbdata/store/revision.py::assess.