Some SAP-Schema-17.x/18.0.0 certs lodge sap_openings width/height in MILLIMETRES mixed with metre rows in the same array (e.g. a 2025x2100 mm window beside a 3.06x1 m one). The 17.1 mapper read them all as metres → a 4.25M m2 window → HTC in the millions → SAP clamped to 1. Fix (TDD, datatypes/epc/domain/mapper.py): _sanitise_opening_dimension_m treats any dimension > 50 m as mm and divides by 1000; _sap_opening_area_m2 applies it to areas. Wired into the window, roof-window, and door-area-weighting paths. The 3 broken certs (uprn_10093117227 / 10090317693 / 10091636031) now score 90 / 81 / 79 instead of 1. 3 RED->GREEN slices + refactor; new test class TestFromSapSchema17_1OpeningUnitSanitisation + sap_17_1_mm_openings.json fixture; 0 new pyright errors; no regressions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.3 KiB
Autonomous corpus run — findings for review (2026-06-16)
Triaged the full remaining worklist (~95 UPRNs): capture → map → engine SAP, flagging |eng−lodged| ≥ 8. Most certs map within ±4 of lodged.
✅ Schema coverage ADDED this run (low-risk, tested, committed)
- SAP-18.0.0 → full-SAP shape, dispatched to
from_sap_schema_17_1(no normalisation). Maps fine (e.g. 10094601287 → 80/lodged 84). - SAP-16.0 → same reduced-field 16.x path; only omitted
tenure, now defaulted in_normalize_sap_schema_16_x. Maps (100020933894 → 61/lodged 56). - (16.2/16.3/17.0 were added earlier in the session.)
⛔ Genuinely SPARSE 16.x certs (insufficient data — cannot score)
Missing 18 required fields incl. core fabric (glazed_area, window, door_count, habitable_room_count, multiple_glazing_type). Fail loud at from_dict (correct):
- uprn_10090844948 (16.3), uprn_10014314798 (16.2), uprn_10014314853 (16.3), uprn_10014314830 (16.2). These are minimal "reduced-data" lodgements.
🐞 BUGS FOUND (diagnosed; NOT fixed — for your review)
1. Opening dimensions in millimetres read as metres — MAPPER bug (SEVERE) ✅ FIXED
FIXED (TDD, _sanitise_opening_dimension_m + _sap_opening_area_m2): any opening
dimension > 50 m is mm → ÷1000. Applied to windows, roof windows, and the door
area-weighting. The 3 broken certs now score 90 / 81 / 79 (were all 1). 3 RED→GREEN
slices + refactor; fixture sap_17_1_mm_openings.json; 0 new pyright errors.
Original report below.
Full-SAP certs whose sap_building_parts[].sap_openings[] lodge width/height in
mm (mixed with metre rows in the same array) → the 17.1 mapper treats all as
metres → multi-million-m² windows → HTC in the millions → SAP clamps to 1.
- uprn_10093117227 (eng 1 / lodged 80): opening "Side Elevation" 2025×2100 (mm)
- uprn_10090317693 (eng 1 / lodged 88): 940×2100, 700×1500 (mm)
- uprn_10091636031 (eng 1 / lodged 85)
- Fix idea: sanitise
sap_openingsdims in_sap_17_1_windows/doors — any dimension > ~50 m is impossible → it's mm, ÷1000. Cleanly separates the mm rows (1000/2025/2100) from the m rows (3.06/3.6/1). Safe, high-value (3+ certs broken).
2. Heat-pump fuel code 39 mis-priced as gas — CALCULATOR bug
- uprn_10093114053 (eng 93 / lodged 79, +14): PCDB heat pump COP 3.33, fuel 39.
- Code 39 absent from
table_12.UNIT_PRICE_P_PER_KWH→ gas default 3.64p; CO2 factor correctly electricity (0.136). Inconsistent across price vs Table-12a. - Affects ALL database heat-pump certs (fuel 39). See memory
heat-pump-fuel-39-mispriced. Needs SAP-domain confirmation of the correct electricity tariff (standard 30 vs heat-pump) → not an autonomous fix.
⚠ MODERATE eng-vs-lodged gaps (not catastrophic — sample, for review)
Direction is mostly engine UNDER lodged on full-SAP (17.0/17.1) certs:
- −15: uprn_100090108846 (RdSAP-20, off-peak fuel 29), uprn_100061086424 (RdSAP-17.0)
- −12: uprn_10090343767 (17.0) · −9: uprn_10090341811, 10093386427 · +9: uprn_10090342180
- A spread of −6…−8 on 17.0/17.1. Likely a mix of the full-SAP→RdSAP residual and possibly more heat-pump-fuel cases. Worth a focused pass after the 2 bugs above.
NOT diagnosed individually
The ~70 within-±4 certs are not listed; they look healthy.