1# Verification checks (P4, 2026-10-30)2- PASS: clean re-run (deleted results.json/forecasts.csv/exclusions.csv, re-ran analysis.py) → results.json byte-identical (cmp).3- PASS: 32 forecast rows.4- PASS: naive forecast == train_last_value for all naive rows.5- PASS: actual == first-release value of target quarter for all rows.6- PASS: first_release_vintage_date of every target > origin date (no look-ahead in actuals).7- PASS: train_last_date < origin; target_date = train_last_date + h quarters.8- PASS: RMSE ≥ MAE > 0 for every model/horizon.9- PASS: rel_improvement_rmse_h = 1 − rmse_model/rmse_naive (to 1e-12).10- PASS: exclusion ledger: 314 − (1+150+3) = 160 = n_analysed; each row n_before − n_removed = n_after.11- PASS: n_analysed equals n_train of the last-origin model rows.12- PASS: first_origin (2024-01-31) < last_origin (2025-12-31).13- PASS: last-origin AR(1) phi = 0.335 in (0,1).14- PASS: hand check of mean_abs_revision_h1_targets: |1.4−1.6|+|3.6−2.8|+|3.2−2.8|+|2.4−2.3|+|0.1+0.3|+|4.0−3.0|+|3.9−4.3|+|0.2−1.4| = 4.5; /8 = 0.5625 ✓.15- PASS: in analysis.py, assertion that each vintage's last value equals that quarter's first release (where listed) held for all 8 vintages.16- Magnitudes: RMSEs 1.4–2.3 pp, comparable to the size of first-release growth fluctuations (−0.3 to 4.3) — plausible.17- PASS (re-verification after adding last_origin_ar1_implied_mean key): clean re-run byte-identical; all other values unchanged.18