diff --git a/docs/grill-sessions/2026-06-09-rdsap-20-0-0-remapper.md b/docs/grill-sessions/2026-06-09-rdsap-20-0-0-remapper.md index 8af2b5f1..e46ece6c 100644 --- a/docs/grill-sessions/2026-06-09-rdsap-20-0-0-remapper.md +++ b/docs/grill-sessions/2026-06-09-rdsap-20-0-0-remapper.md @@ -1,11 +1,33 @@ # Grill session — RdSAP-Schema-20.0.0 → EpcPropertyData remapper -**Date:** 2026-06-09 (resumed 2026-06-10) · **Branch:** `feature/junte+khalim` · **Status:** GRILL COMPLETE — all branches resolved (windows, lighting, glazing, ventilation, hot-water, schema fix, trivia). Ready for ADR + TDD. +**Date:** 2026-06-09 (resumed 2026-06-10) · **Branch:** `feature/junte+khalim` · **Status:** IMPLEMENTED — Reduced-Field Synthesis shipped via TDD (ADR-0027). All 1000 corpus certs parse, map, and score; corpus guard flipped to strict. Resume by re-running `/grill-me` and feeding it this file. --- +## IMPLEMENTED (2026-06-10 TDD session) + +Shipped per ADR-0027 as vertical TDD slices (one test → one impl), commits tagged 🟩: + +- **Schema parse fix** — `RdSapSchema20_0_0` made `kw_only` with data-driven required→optional defaults; `SapBuildingPart` fields all Optional (conservatory parts carry only `{double_glazed, floor_area, glazed_perimeter, room_height}`, no `identifier`). 993→1000/1000 parse. +- **Window synthesis** — `_synthesise_20_0_0_sap_windows`: 4-way N/E/S/W split, `width = 0.148 × TFA × band_multiplier / 4`, `height = 1.0`, glazing via `_api_cascade_glazing_type`. The 7 rich certs use lodged `window_area` (`_measurement_value`) for geometry. +- **Lighting** — low-energy outlets → LEL path; remainder → incandescent. +- **Ventilation** — `open_fireplaces_count` → `open_chimneys_count`; `percent_draughtproofed` passthrough; `sheltered_sides` from `built_form`. +- **Hot water** — `number_baths` / `mixer_shower_count` derived from `instantaneous_wwhrs` room counts. +- **Corpus guard** — `test_mapper_corpus.py`: 20.0.0 promoted into `SUPPORTED`, xfail dropped → strict **2000/2000** (1000 21.0.1 + 1000 20.0.0) parse+map. Verified all 1000 also score through `Sap10Calculator` without crashing. + +**Deliberately left to the calculator (ADR-0027 "leave defaults to the calculator"):** +- `wet_rooms_count = 0` → calculator's `>0 else 1` fallback (only consumed on the decentralised-MEV path). +- Window **U / g** — calculator defaults U from `glazing_type` (Table 24) when `window_transmission_details` is absent; verified scoring works without the mapper supplying it. +- `mechanical_ventilation` decode (5 MEV certs) — not yet decoded to `mechanical_ventilation_kind`; calculator's natural-ventilation default applies. + +**Deferred (user):** formal SAP-score validation test ("we'll do a sap calculation test later"). Scoring is proven crash-free for all 1000; the score-value guard is the next slice when picked up. + +**Pre-existing failure (NOT a regression):** `TestFromRdSapSchema21_0_1::test_total_floor_area` fails on `main`-state too (confirmed via `git stash`). + +--- + ## RESOLVED in 2026-06-10 grill **Spec sources (authoritative):** RdSAP10 Specification (9 June 2025) + **SAP 10.2** (already in repo) for anything RdSAP10 doesn't cover. The band→m² glazing rule exists in *neither* (both measure all windows); it was a RdSAP-2012-only convention — hence Q2 below resolved by fitting from our own data.