Model/domain
Khalim Conn-Kowlessar faf116bd70 Slice S0380.30: extend g_L + g⊥ Table 6b to RdSAP 21 codes 8-15 — closes API path cohort residual cluster
Per the RdSAP 21 schema in [datatypes/epc/domain/epc_codes.csv][1], the
`glazing_type` enum extends to 15 codes; the legacy SAP 10.2 Table 6b
cascade lookups in `internal_gains.py:106` and `solar_gains.py:178`
only knew codes 1-7. Every API-path cert in the cohort lodges
`glazing_type` via the RdSAP 21 numbering, and triple-glazed
lodgements surface as **code 14** ("triple glazing, installed 2022+").

Pre-slice the cascade fell through to the 0.80 / 0.76 double-glazed
defaults for codes 8-15:

  Internal gains g_L (Table 6b):
    code 14 → default 0.80 (DG)        vs spec 0.70 (TG)
    → daylight factor over-bonused → lighting kWh under-counted

  Solar gains g⊥ (Table 6b):
    code 14 → default 0.76 (DG)        vs spec 0.68 (TG)
    → solar gains over-counted

For cert 0350-2968-2650-2796-5255 (semi-detached, 9 triple-glazed
windows lodged as code 14), this drove:
  lighting_kwh_per_yr: cascade 221.79 vs Summary-path 228.44
    (-6.65 kWh/yr — daylight bonus too generous → lighting too low)
  space_heating_kwh_per_yr: cascade 7000.21 vs Summary-path 6996.94
    (+3.28 kWh/yr — extra solar gains lower HP demand)
  net ECF: -0.0022 vs Summary-path → SAP +0.031

Same mechanism on the other 5 cohort-1 ASHP API certs.

Fix: extend both lookup tables with the RdSAP 21 additions per the
schema CSV semantics:

  | code | description (RdSAP 21)          | g_L  | g⊥   |
  |------|----------------------------------|------|------|
  |  8   | triple glazing, known data      | 0.70 | 0.68 |
  |  9   | triple glazing, 2002-2022       | 0.70 | 0.68 |
  | 10   | triple glazing, pre-2002         | 0.70 | 0.68 |
  | 11   | secondary glazing, normal-E      | 0.80 | 0.76 |
  | 12   | secondary glazing, low-E         | 0.80 | 0.76 |
  | 13   | double glazing, 2022+            | 0.80 | 0.76 |
  | 14   | triple glazing, 2022+            | 0.70 | 0.68 |
  | 15   | single glazing, known data       | 0.90 | 0.85 |

Solar gains also adds code 7 (double known data) for
`_G_PERPENDICULAR_BY_GLAZING_TYPE` to align with the existing
`_G_LIGHT_BY_GLAZING_CODE` code-7 entry (which already mapped to
0.80 = double).

Outcome — Cohort-1 ASHP cohort API path:
  cert 0380:  +0.025  →  +1e-6     (close to exact)
  cert 0350:  +0.031  →  +2.2e-5   (close to exact)
  cert 2225:  +0.029  →  -4.8e-5   (close to exact)
  cert 2636:  +0.015  →  -0.015    (sign flip; cantilever-specific
                                    residual surfaces; same |Δ| as Summary)
  cert 3800:  +0.023  →  -2e-5     (close to exact)
  cert 9285:  +0.029  →  -3.4e-5   (close to exact)

5 of 6 API path certs now sit at <1e-4 vs worksheet. Cert 2636
matches its Summary-path residual (-0.015) — the cantilever fixture
has its own non-glazing residual to be diagnosed separately.

Cohort-2 Summary path unchanged (33 exact + 5 ≤0.07) — the cohort-2
certs lodge glazing codes 1-7 (RdSAP 17 numbering still surfaces in
Elmhurst Summary PDF lookups), so codes 8-15 only affect the
RdSAP-21-schema API path.

Golden API fixture pins updated to reflect the tightened cascade-vs-API
alignment (7 certs: 0380, 0350, 2225, 2636, 3800, 9285, 9418). SAP
integer residuals unchanged (all sit at +0).

Pyright net-zero on touched files (22 → 22).

Tests: 710 → **711** pass (+1 new: cert 0350 fixture-shape test for
glazing_type=14 routing to g⊥=0.68 with `total_solar_gains_monthly_w[0]
≈ 67.00 W` (vs pre-slice 74.88 W at the DG default), proving code 14
hits the triple-glazed Table 6b row.) 10 expected fails unchanged.

[1]: datatypes/epc/domain/epc_codes.csv (RdSAP-Schema-21.0.1).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 12:01:34 +00:00
..
addresses get rid of comments 2026-05-20 13:21:11 +00:00
sap10_calculator Slice S0380.30: extend g_L + g⊥ Table 6b to RdSAP 21 codes 8-15 — closes API path cohort residual cluster 2026-05-28 12:01:34 +00:00
sap10_ml Slice S0380.26: RdSAP10 §5.8 dry-lining adjustment on alt walls — closes cert 7700 -0.44 → +5e-5 2026-05-28 10:56:11 +00:00
tasks added postcode splitter rewrite to ddd 2026-05-19 16:35:09 +00:00
postcode.py get rid of comments 2026-05-20 13:21:11 +00:00