# Verification checks (P4) — 2026-10-30 | check | outcome | |---|---| | Clean re-run (deleted results.json, forecasts.csv, exclusions.csv; reran analysis.py) gives byte-identical results.json and forecasts.csv | PASS | | All 23 required results keys present (gate_spec.json) | PASS | | forecasts.csv has 32 rows, 8 per (model, horizon) | PASS | | Exclusion ledger: 314 − (0+1+150+3) = 160 = n_analysed; each row n_before − n_removed = n_after | PASS | | RMSEs positive; RMSE ≥ MAE for every model/horizon | PASS | | rel_improvement = 1 − rmse_model/rmse_naive (to 1e-12) | PASS | | Chronology: first_origin < last_origin; train_last_date < origin_date; target_date > train_last_date | PASS | | Actuals equal first_release.csv values; first_release_vintage_date > origin for every target (no look-ahead in actuals) | PASS | | Naive forecast equals train_last_value (last value in the origin vintage) | PASS | | SHA-256 of every input matches README/bundle | PASS | | current_vintage.csv used only in revision statistic (code inspection: cur_map used only in `revs`) | PASS | | Magnitudes: RMSEs 1.40–2.27 pp, same order as the cross-origin spread of growth (−0.3 to 4.3); model forecasts stay near unconditional mean ≈ 2.6 | PASS (plausible) | | n_input_rows match README row counts (307…314, 318, 13) | PASS |