Model/tests/domain
Khalim Conn-Kowlessar 0ffc25506e Bill a flat's floor to an unheated space as semi-exposed 🟩
RdSAP 10 §3.12 (PDF p.26), the flats/maisonettes floor rules: "There is no heat
loss through the floor if there is another flat below. Otherwise the floor area
of the flat ... is ... a semi-exposed floor if there are unheated premises below
it (e.g. an enclosed garage) ... Semi-exposed (sheltered) floors are treated as
if they were fully exposed." §5.13 (p.48) confirms the U-value identity: Table 20
applies to exposed and semi-exposed alike.

API floor_heat_loss=2 -> floor_type "To unheated space" set no exposure signal,
so on a mid-/top-floor flat the dwelling-level heuristic (has_exposed_floor=False,
assuming a heated dwelling below) went unopposed and the ENTIRE floor was billed
at 0 W/K. 11 properties across portfolios 796+824, mean +4.02 SAP, 10 of 11
over-rating — we judged dwellings more efficient than the accredited assessment
and would withhold retrofit measures they need.

Exemplars: 750018 space heating -53.2% -> -8.1% vs the cert's own RHI figure,
SAP +8.22 -> +1.16; 749898 -43.0% -> +0.9%, SAP +6.29 -> -1.11.

SCOPED TO FLATS ON PURPOSE. §3.12 is the flats/maisonettes section, and the
accredited Elmhurst worksheet disagrees with Table 20 for a house: golden cert
7536-3827-0600-0600-0276 (detached) lodges floor_heat_loss=2 on its Main part and
the worksheet bills it on the BS EN ISO 13370 ground-floor cascade at U 0.97, not
Table 20's 1.20. An unscoped mapper-level fix broke that pin and the
uprn_100050881708 accuracy pin; the scoped fix leaves both untouched.

No regressions: identical failure set and pyright count vs main; the RdSAP-21.0.1
accuracy corpus gauge is unchanged at 78.8% within-0.5 / MAE 0.625 (correctly —
all 7 corpus certs lodging code 2 are houses).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 21:24:25 +00:00
..
abri send AM or PM instead of trying to parse morning or afternoon 2026-07-10 10:45:57 +00:00
addresses standardist Address 2026-05-22 10:13:32 +00:00
billing ASHP sizing targets the Appendix-N efficiency peak (realistic installed pump) 🟩 2026-07-03 11:02:13 +00:00
bulk_document_download Scope latest-per-Document-Type per property, each in its own folder 🟩 2026-07-08 09:15:44 +00:00
data_transformation Let a deterministic guard override the fallback classifier per description 🟥 2026-07-01 09:39:16 +00:00
epc A community override keeps an assessor-observed Group 3 control 🟥 2026-07-03 16:33:40 +00:00
epc_prediction Derive multiple_glazed_proportion for 16.x certs with explicit glazing wording 2026-07-08 11:53:51 +00:00
fuel_rates Expose an off-peak meter's standing charge and full day/night blend range 🟩 2026-06-24 17:14:51 +00:00
magicplan Mapper reads 'Individual Trickle Vent' label variant 🟥 2026-06-30 13:43:48 +00:00
modelling Gate the loft top-up strictly below the 270mm building-regs depth 🟩 2026-07-10 16:07:48 +00:00
property feat: thread physical-state-change signal into rebaselining 🟩 2026-06-26 19:15:11 +00:00
property_baseline ASHP sizing targets the Appendix-N efficiency peak (realistic installed pump) 🟩 2026-07-03 11:02:13 +00:00
sap10_calculator Bill a flat's floor to an unheated space as semi-exposed 🟩 2026-07-21 21:24:25 +00:00
tasks A recorded batch failure carries structured details onto the sub_task outputs 🟥 2026-07-07 11:49:56 +00:00
__init__.py added postcode splitter rewrite to ddd 2026-05-19 16:35:09 +00:00
test_building_geometry.py feat(modelling): floor Recommendation Generator + ground-floor-area geometry 2026-06-03 09:12:29 +00:00
test_postcode.py Add UK-postcode format validity to the Postcode value object 🟩 2026-06-29 15:24:18 +00:00