From 104e3725b8631dd43b464189eb3438f84ddb0c0d Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Sat, 20 Jun 2026 13:34:31 +0000 Subject: [PATCH] test(corpus): ratchet SAP MAE 0.83->0.82 and PE 4.0->3.7 floors after stone-mechanism correction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The corrected stone branch (age-E-only cap, §3.5 Table-3 unknown-thickness default, Scotland band-J override) improved the corpus gauge to SAP MAE 0.819 and PE MAE 3.6 kWh/m2/yr. Lock the gains in and record the corrected mechanism in the provenance log; within-0.5 (71.6%) and CO2 (0.08) unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../epc_client/test_sap_accuracy_corpus.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py index 2f454359..079f4e01 100644 --- a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py +++ b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py @@ -163,6 +163,20 @@ _CORPUS = Path( # Took within-0.5 70.3% -> 71.6% (MAE 0.833 -> 0.822); fixed the 2 stone-U # unit tests; worksheet-validated (Elmhurst age-B sandstone 400 mm → 1.90). # +# STONE MECHANISM CORRECTED (RdSAP 10 Tables 6-7 footnote a + §3.5 Table 3): +# the commit above (034d4b7c) got the right numbers for two cases but the +# wrong mechanism — it dropped the 1.7 cap for ALL age bands and gated on +# `wall_insulation_type is not None`. Per Tables 6-10: bands A-D = uncapped +# §5.6 formula, band E = min(formula, 1.7) (Scotland sandstone 1.5); the cap +# is age-E ONLY. The insulation-state gate is not a spec rule (it sent +# age-A-D "insulation Unknown" stone to the flat 1.7 table). Unknown +# thickness now feeds the §3.5 Table-3 default thickness (stone A-D 500 mm, +# E 450; Scotland +200/+100) into the formula — Elmhurst defaults an England +# age-B granite as-built unknown-thickness wall to 500 mm → 1.87 (sandstone +# 1.68), NOT a flat 1.7. Also added the missing Scotland band-J 0.30 override +# (Table 7) for all 7 as-built wall types. MAE 0.822 -> 0.819, PE 3.7 -> 3.6; +# within-0.5 and CO2 unchanged. Unit-pinned in test_rdsap_uvalues. +# # SAP RATING FLOOR (SAP 10.2 §13 / RdSAP 10 §13): the rating is floored at 1 # ("if the result is less than 1, the rating is 1"). `calculate_sap_from_inputs` # now applies that floor to the CONTINUOUS score too (was integer-only), so a @@ -170,9 +184,9 @@ _CORPUS = Path( # (cert 422000111926, lodged at the floor of 1, was computing -11.3): within-0.5 # 70.2% -> 70.3%, MAE 0.845 -> 0.833. _MIN_WITHIN_HALF_SAP = 0.71 -_MAX_SAP_MAE = 0.83 +_MAX_SAP_MAE = 0.82 _MAX_CO2_MAE_TONNES = 0.09 # t CO2 / yr vs co2_emissions_current -_MAX_PE_PER_M2_MAE = 4.0 # kWh / m2 / yr vs energy_consumption_current +_MAX_PE_PER_M2_MAE = 3.7 # kWh / m2 / yr vs energy_consumption_current def _load_corpus() -> list[dict[str, Any]]: