Verification checks (P4) — all PASS
- Clean re-run (deleted results.json, forecasts.csv, exclusions.csv; reran): byte-identical results.json and forecasts.csv. PASS
- forecasts.csv has 192 rows; 48 origins per (model, horizon). PASS
- target_date = origin + h for every row. PASS
- last_target_date_used ≤ origin−2 (all rows); last_predictor_date_used ≤ origin−1 (model rows); empty for naive. PASS
- actual equals data gdp_yoy at target; naive forecast equals gdp_yoy(t−2). PASS
- RMSE/MAE recomputed independently from ledger match results.json (<1e-5); MAE ≤ RMSE for all four. PASS
- rel_improvement = 1 − rmse_model/rmse_naive. PASS
- Exclusion ledger: n_before − n_removed = n_after each step; 345 − Σremoved = final n (310 for h1, 306 for h3); n_analysed = 310. PASS
- last_target_date_available = 2026-02-01, last_predictor_date_available = 2026-03-01. PASS
- Leakage test: perturbing gdp_yoy > 2023-11 and emp_yoy > 2023-12 with noise leaves origin 2024-01 forecasts unchanged. PASS
- Magnitudes: model RMSE (0.67, 0.85 pp) below naive (0.81, 1.14 pp), same order of magnitude; no NaN. PASS
- Uncertainty: DM stats finite, p-values in [0,1]. PASS