docs: flag deferred HP-on-E7 Table 12a + Table 4f pumps_fans cascade gap

Cert 000565 reveals a coupling between two SAP 10.2 cascade gaps
that prevents an isolated fix to either:

1. `_space_heating_fuel_cost_gbp_per_kwh` applies the E7 low-rate
   override to any electric main on a Dual meter. Per Table 12a,
   heat pumps on E7 use a ~33% high / 67% low split (cert 000565
   empirically) — NOT 100% low. The current binary all-low/all-high
   biases space-heating cost £-1.1k / £+1.3k respectively.

2. `_PUMPS_FANS_KWH_BY_MAIN_CATEGORY[4] = 0` for HPs (Table 4f says
   the circulation pump is in the COP). But certs with MEV / flue
   fans / solar HW pumps have those components added on top — cert
   000565's worksheet pin = 127.5 MEV + 45 flue + 80 solar = 252.5
   kWh, none of which the cascade currently sums.

Probed a fix that derives `main_heating_category=4` from
`sap_main_heating_code in {211-227, 521-527}` (the Table 4a HP
rows) and exempts category=4 from the off-peak override. The
mapper change is architecturally correct but coupling to (1) +
(2) leaves residuals worse at HEAD than at the prior commit — so
both edits are reverted and the spec rationale is folded into
TODO docstrings on the two helpers:

- `_elmhurst_main_heating_category` (mapper) — flags the deferred
  HP SAP code route + the two cascade prerequisites
- `_space_heating_fuel_cost_gbp_per_kwh` (cascade) — flags the
  Table 12a high/low split as a future cascade slice

Cohort regression check: 192 pass + 10 expected 000565 fails —
identical baseline to S0380.59. Docs-only, pyright net-zero.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-05-28 23:08:37 +00:00
parent 98384999be
commit 1ce1a6974b
2 changed files with 17 additions and 2 deletions

View file

@ -3835,7 +3835,16 @@ def _elmhurst_main_heating_category(
membership is the authoritative signal. A PCDB-referenced boiler on
mains/LPG gas is category 2 (gas-fired boilers). Other system types
fall through to None so the cascade applies its default pumps_fans
130 kWh/yr until extended."""
130 kWh/yr until extended.
TODO: route Table 4a HP SAP codes (211-227, 521-527) to
category=4 when no PCDB Table 362 record is lodged. Currently
deferred because the correct dispatch needs (a) Table 12a
high/low rate split for HP-on-E7 cost cascade and (b) Table 4f
MEV / flue-fan / solar HW pump components for pumps_fans
without both, naive category=4 dispatch overshoots cost by
£1.3k and undershoots pumps_fans by 252 kWh on cert 000565.
"""
if pcdb_index is not None and heat_pump_record(pcdb_index) is not None:
return _ELMHURST_HEATING_CATEGORY_HEAT_PUMP
if pcdb_index is not None and mh.fuel_type in _ELMHURST_GAS_BOILER_FUEL_TYPES:

View file

@ -757,7 +757,13 @@ def _space_heating_fuel_cost_gbp_per_kwh(
"""Space heating bills at the main fuel's rate. When the dwelling is
on an off-peak tariff (meter_type != standard) AND the main fuel is
electricity, bill at the off-peak rate instead. Trusts the cert's
meter_type rather than inferring tariff from heating code."""
meter_type rather than inferring tariff from heating code.
TODO: SAP 10.2 Table 12a applies a per-system high/low rate split
rather than the binary all-low / all-high implemented here. For
HP carriers on E7 the split is ~33% high / 67% low (cert 000565
empirically implies that split); single-rate biases the cost
£±1k vs the worksheet. Table 12a needs its own cascade slice."""
if _is_electric_main(main) and _is_off_peak_meter(meter_type, fuel_is_electric=True):
return prices.e7_low_rate_p_per_kwh * _PENCE_TO_GBP
return _fuel_cost_gbp_per_kwh(main, prices)