diff --git a/docs/HANDOVER_API_PROFILING.md b/docs/HANDOVER_API_PROFILING.md index 426db63c..7edf26fa 100644 --- a/docs/HANDOVER_API_PROFILING.md +++ b/docs/HANDOVER_API_PROFILING.md @@ -437,6 +437,36 @@ table. **Verified 0/909 corpus raises; eval unchanged 54.9%/909/0** — pure fut `u_roof` (→0.4). The `age_band is None` branches above each are justified absent-data defaults; only a typo/unknown band silently passing is the gap. +### SESSION-9 (cont. 2) — glazing single/secondary/triple per RdSAP 10 Table 24, `a0432977` (BIGGEST WIN) +Chasing Tier-2 turned up the session's biggest lever. `_API_GLAZING_TYPE_TO_TRANSMISSION` mapped +only the DOUBLE-glazing codes [1,2,3,13,14]; single (5/15), secondary (4/11/12), triple +(6/8/9/10) returned None → the cascade routed them to the `u_window` all-None default **U=2.5** +instead of their Table 24 value. **Single glazing (U=4.8) modelled at half its heat loss** was +the killer — 79 corpus certs carry code 5; the 94 certs with any unmapped glazing code sat at +**32% within-0.5 vs 54.9% baseline**. Extended the transmission + gap-override tables with the +RdSAP 10 Table 24 (spec p.50) (U, g, FF) rows for every RdSAP-21 glazing code. **Eval 54.90% → +56.66% within-0.5** (net +16: 22 in, 6 offsetting-error out), within-1.0 70.2→71.9, mean|err| +1.224→1.203, 909/0. 7 AAA tests, goldens + gate green, pyright net-zero. **Method that found it: +profile by `sap_windows[].glazing_type`, split known vs unmapped codes, decode against +`epc_codes.csv` `glazed_type`.** + +### OPEN — KNOWN bugs still on the board (ranked) +1. **Glazing SOLAR/LIGHT g mis-keyed** (the natural follow-on): `_G_PERPENDICULAR_BY_GLAZING_TYPE` + (solar_gains.py) + `_G_LIGHT_BY_GLAZING_CODE` (internal_gains.py) are keyed on the SAP-10.2 + Table-6b cascade ordering (1=single…) but `_api_cascade_glazing_type` only translates {1:2} — + every OTHER API code passes through UNTRANSLATED, so API code 5 (single) reads the cascade-5 + slot (secondary/DG-low-E g) for solar+daylight gains. Smaller than the U effect (gains are + second-order) but a real systematic mis-map. Fix = complete `_api_cascade_glazing_type` → + Table-6b, OR feed the transmission-tuple g instead. Verify magnitude first. +2. **Window orientation silently dropped** (solar_gains.py:391 `if orientation is None: continue`) + — an unmapped orientation code loses the whole window's solar gain. HIGH-confidence data-loss. +3. **Tier-2 glazing strict-raise** — now that codes 1-15 are mapped, make `_api_glazing_transmission` + raise `UnmappedApiCode` on a present-but-unmapped (>15) code (zero current regression). +4. Tier-3 age-band swallows (low impact). MVHR (mech_vent=4) deferred. 21.0.0 builder missing the + 8/8b/8c ventilation + (now) glazing edits — extend if a 21.0.0 cert surfaces. +5. Per-cert: cert 0370-2933 still +15 after glazing (7 single windows but the over-rate is + non-window — separate fabric/heating cause). The 100 unsupported-schema certs (big ticket). + ## THE 100 unsupported_schema CERTS (deferred — bigger ticket) SAP-Schema-19.1.0 (and other pre-21). The user is planning a separate big piece: map old schemas → new + **predict missing fields from similar-looking properties** (needs an EPC-prediction