Verification checks (P4) — all PASS
- Clean re-run: deleted results.json/forecasts.csv/exclusions.csv, re-ran analysis.py; byte-identical results.json and forecasts.csv (cmp). PASS
- forecasts.csv has 192 rows = 48 origins x 2 horizons x 2 models (48 per cell). PASS
- Chronology: last_target_date_used <= origin-2 for all rows; last_predictor_date_used <= origin-1 for model rows; empty for naive. Internal asserts in script also check estimation sample max target month <= t-2. PASS
- target_date = origin + h for all rows; actual equals data gdp_yoy of target month for all rows, none missing. PASS
- All RMSE > 0; RMSE >= MAE for each model/horizon. PASS
- first_origin 2022-05-01 <= last_origin 2026-04-01; last_target_date_available 2026-02-01 and last_predictor_date_available 2026-03-01 precede last origin. PASS
- Exclusion ledger: 345 - (7+3+25) = 310 = n_analysed (asserted in script). PASS
- Magnitudes: model RMSE (0.74/0.90) of same order as naive (0.81/1.14); naive h3 > naive h1 as expected. PASS