| 1 |
Clean re-run (deleted results.json, forecasts.csv; re-ran analysis.py): byte-identical outputs |
PASS |
| 2 |
forecasts.csv has 240 rows, 40 per (model, horizon) |
PASS |
| 3 |
target_date = origin_date + h quarters for every row |
PASS |
| 4 |
actual equals infl_annualised of target quarter (tol 1e-6) |
PASS |
| 5 |
snaive forecast equals infl_annualised of target − 4 quarters (≤ origin) |
PASS |
| 6 |
Leakage test: added +50 to all quarters after 2020Q3 in a temp copy; forecasts at origins ≤ 2020Q3 unchanged |
PASS |
| 7 |
rel_improvement = 1 − rmse_model/rmse_snaive (all h) |
PASS |
| 8 |
RMSE ≥ MAE for every model/horizon |
PASS |
| 9 |
loss_diff_mean_h4 = rmse_snaive_h4² − rmse_model_h4² |
PASS |
| 10 |
dm_stat_h4 = loss_diff_mean_h4 / loss_diff_se_h4; SE > 0 |
PASS |
| 11 |
hac_lags_h4 = 3 ≥ h−1 = 3 |
PASS |
| 12 |
Exclusion ledger: 127 − 1 − 4 = 122 = n_analysed |
PASS |
| 13 |
first_origin 2015-10-01 < last_origin 2025-07-01; n_origins 40 |
PASS |
| 14 |
Magnitudes: snaive RMSE ≈ 2.85–2.88 pp vs target sd 2.39 over full sample (surge period inflates errors) — plausible |
PASS |