1# Phase 3 — as-of data pipeline, leakage tests, baselines (2026-10-27)23Artefacts: `scripts/01_build_analytic.py` → `data/processed/analytic.parquet` (631,866 sales; house 422,542 / condo 122,976 / plex 86,348); `02_splits.py` (train 379,310 / validation 72,132 / test 96,935 / holdout 83,489; LLM subsamples 240/600/300 over 35 strata; spatial-holdout flag 59,770 rows); `04_geo.py` (flood coverage 39.9 % of rows, 1.18 % of those in a flood zone; 97.0 % DA match); `03_features.py` → `feature_matrix.parquet` (35 numeric + 8 categorical; exact as-of neighbour features); `05_leakage_audit.py` → `results/data/leakage_audit.json` (9/9 PASS). Two leaks caught and fixed during development: K-nearest neighbour capping let *future* sales crowd out past ones (existence leak); a positional join misaligned rolling municipality features.45Baselines: `scripts/10_train_baselines.py` (A hedonic ridge with municipality trends and grid FE; B hierarchical shrinkage + repeat-sales blend, w_repeat = 0.25 on validation; C LightGBM random search of 10 configurations tuned on validation, best num_leaves 255 / lr 0.02 / 256 rounds; D AVM = LightGBM point + 5 quantile models + split-conformal 90 % scaling; CatBoost and XGBoost as robustness; spatial-holdout retraining without Outaouais, Abitibi-Témiscamingue, Bas-Saint-Laurent). Prediction records in `results/runs/baselines/predictions.parquet`. Timings in the run manifest.67Failed checks: none in the audit. Note: calendar-quarter fixed effects cannot be extrapolated out of time; the hedonic uses municipality-specific linear trends + cubic global trend + month-of-year effects instead (documented in the code).8