test(corpus): ratchet SAP MAE 0.83->0.82 and PE 4.0->3.7 floors after stone-mechanism correction

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) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-20 13:34:31 +00:00
parent 381ecfda4c
commit 104e3725b8

View file

@ -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]]: