Verification checks
- forecasts rows = 240 (expect 240): True
- 40 origins x 3 h x 2 models unique: True
- target = origin + 3h months: True
- snaive forecast equals infl at target-4q and that quarter <= origin: True
- actuals match data: True
- rmse_snaive_h1 recomputed from csv 2.849126 vs 2.849126; MAE<=RMSE: True
- rmse_model_h1 recomputed from csv 2.191813 vs 2.191813; MAE<=RMSE: True
- rmse_snaive_h2 recomputed from csv 2.846674 vs 2.846674; MAE<=RMSE: True
- rmse_model_h2 recomputed from csv 2.460223 vs 2.460223; MAE<=RMSE: True
- rmse_snaive_h4 recomputed from csv 2.882316 vs 2.882316; MAE<=RMSE: True
- rmse_model_h4 recomputed from csv 2.339685 vs 2.339685; MAE<=RMSE: True
- rel improvements consistent: True
- loss_diff_mean_h4 = rmse_snaive_h4^2 - rmse_model_h4^2: True
- SE>0: True; hac lag 3>=3: True; dm=mean/se: True; p in (0,1): True
- first_origin<last_origin: True
- exclusions: 127-1=126; 126-8=118 = n_analysed True
- magnitudes: model RMSEs 2.19-2.46 vs snaive 2.85-2.88, sd(infl)=2.39 — plausible
- information rule: analysis.py slices y[:i_end+1] (quarters <= origin) for estimation and AIC; asserts target-4 <= origin
- rerun of analysis.py twice -> byte-identical results.json (cmp)