# Verification checks (P4) | check | outcome | |---|---| | Clean re-run (deleted outputs, ran twice) -> results.json and forecasts.csv byte-identical | PASS | | forecasts.csv has 32 rows, 8 per (model,horizon) | PASS | | Exclusion ledger: 314 - 151 - 1 - 3 = 159 = n_analysed; each step n_before-n_removed=n_after | PASS | | RMSE >= MAE for every model/horizon; all RMSE > 0 | PASS | | rel_improvement_rmse_h{1,2} == 1 - rmse_model/rmse_naive | PASS | | target_date > train_last_date for all rows; vintage_date == origin_date | PASS | | train_last_value and n_train (naive) equal last value / row count of the origin's vintage file | PASS | | Naive RMSE independently recomputed from forecasts.csv matches results.json | PASS | | first_release_vintage_date of every target > origin (assert in analysis.py) | PASS | | SHA-256 of all inputs match data/README.md | PASS | | Magnitudes: RMSEs 1.4-2.3 pp, same order as GDP growth volatility; AR(1) phi 0.33-0.34, implied mean 2.6-2.7% — plausible | PASS |