fix(uvalues): add missing Scotland band-J 0.30 wall override for all 7 as-built types (RdSAP 10 Table 7, PDF p.35)

A full code-vs-spec sweep of unknown-thickness as-built U-values across all
seven wall types found exactly one divergence: Scotland age band J. Table 7
(Scotland) gives 0.30 for every uninsulated wall type, but the England base
(Table 6) is 0.35 and the _COUNTRY_KLM_OVERRIDES[SCT] dicts listed H/K/L/M
while omitting J — so a Scotland band-J wall wrongly returned England's 0.35.

Added 'J': 0.30 to all 7 SCT as-built entries (granite, sandstone, solid
brick, cavity, timber frame, system built, cob).

The audit's companion finding — Scotland sandstone age E = 1.5 — needs NO
table override: the §5.6 stone branch intercepts all sandstone bands A-E and
already caps age E at 1.5 for Scotland (e_default in the prior commit), so a
table-E override would be dead code. England base tables and Isle of Man
(= England) are confirmed correct by the same sweep.

Corpus unchanged (England-only corpus has no Scotland band-J certs).
pyright not installed in this container — strict type gate not run locally.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-20 13:29:54 +00:00
parent 54ae05d04b
commit 381ecfda4c
2 changed files with 46 additions and 8 deletions

View file

@ -439,14 +439,16 @@ _CAVITY_FILLED_ENG: Final[list[float]] = [
# entries that differ from the England base.
_COUNTRY_KLM_OVERRIDES: Final[dict[Country, dict[tuple[int, int], dict[str, float]]]] = {
Country.SCT: {
# Scotland Cavity-as-built K-M: 0.25, 0.22, 0.17 (vs ENG 0.30, 0.28, 0.26).
(WALL_CAVITY, 0): {"H": 0.45, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_STONE_GRANITE, 0): {"H": 0.45, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_STONE_SANDSTONE, 0): {"H": 0.45, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_SOLID_BRICK, 0): {"H": 0.45, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_TIMBER_FRAME, 0): {"K": 0.25, "L": 0.22, "M": 0.17},
(WALL_SYSTEM_BUILT, 0): {"H": 0.45, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_COB, 0): {"K": 0.25, "L": 0.22, "M": 0.17},
# Scotland (Table 7, PDF p.35) as-built bands that diverge from the
# England base: H 0.60→0.45 (not timber/cob, which are already 0.40/
# 0.60), J 0.35→0.30 (ALL types), K 0.30→0.25, L 0.28→0.22, M 0.26→0.17.
(WALL_CAVITY, 0): {"H": 0.45, "J": 0.30, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_STONE_GRANITE, 0): {"H": 0.45, "J": 0.30, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_STONE_SANDSTONE, 0): {"H": 0.45, "J": 0.30, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_SOLID_BRICK, 0): {"H": 0.45, "J": 0.30, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_TIMBER_FRAME, 0): {"J": 0.30, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_SYSTEM_BUILT, 0): {"H": 0.45, "J": 0.30, "K": 0.25, "L": 0.22, "M": 0.17},
(WALL_COB, 0): {"J": 0.30, "K": 0.25, "L": 0.22, "M": 0.17},
},
Country.NIR: {
(WALL_CAVITY, 0): {"M": 0.18},

View file

@ -421,6 +421,42 @@ def test_u_wall_scotland_age_band_m_returns_country_specific_table7_value() -> N
assert result == pytest.approx(0.17, abs=0.001)
def test_u_wall_scotland_age_band_j_returns_0_30_not_england_0_35_per_table7() -> None:
# Arrange — RdSAP 10 Table 7 (Scotland, PDF p.35) as-built band J is
# 0.30 for every uninsulated wall type, vs the England base 0.35
# (Table 6). The _COUNTRY_KLM_OVERRIDES[SCT] dicts previously listed
# H/K/L/M but omitted J, so a Scotland band-J cavity wrongly fell
# through to England's 0.35.
# Act
result = u_wall(
country=Country.SCT,
age_band="J",
construction=WALL_CAVITY,
insulation_thickness_mm=0,
)
# Assert
assert result == pytest.approx(0.30, abs=0.001)
def test_u_wall_scotland_age_band_j_timber_frame_returns_0_30_per_table7() -> None:
# Arrange — the J=0.30 override applies to all 7 as-built wall types,
# including timber frame (England base J = 0.35). Guards the type whose
# Scotland override has no H entry (timber H already 0.40 in England).
# Act
result = u_wall(
country=Country.SCT,
age_band="J",
construction=WALL_TIMBER_FRAME,
insulation_thickness_mm=0,
)
# Assert
assert result == pytest.approx(0.30, abs=0.001)
def test_u_wall_timber_frame_as_built_age_band_a_returns_table6_value() -> None:
# Arrange — Timber frame as built, age A, England -> 2.5 W/m^2K.