Model/domain
Khalim Conn-Kowlessar efcd37e2d2 Slice S0380.61: wire RdSAP §12 dispatch + Table 12a high-rate fractions into cost scalars
Builds on S0380.60. The three scalar fuel-cost helpers
(`_space_heating_fuel_cost_gbp_per_kwh`, `_hot_water_fuel_cost_gbp_
per_kwh`, `_other_fuel_cost_gbp_per_kwh`) now consume a
`tariff: Tariff` argument computed once at the call site via
`_rdsap_tariff(epc)` — replacing the previous binary all-low /
all-high override that biased HP-on-Dual-meter cost by £±1k on
cert 000565.

Three pieces wired:
1. `_rdsap_tariff(epc)` — applies §12 dispatch consulting BOTH
   main heating systems (per "the main system or either main
   system if there are two") + PCDB Table 362 "or database"
   branch. Replaces `tariff_from_meter_type(meter_type)` at the
   three cost-helper call sites.
2. `_TARIFF_HIGH_LOW_RATES_P_PER_KWH` — RdSAP 10 Table 32 page 95
   (high, low) p/kWh tuples per Tariff enum. Codes 31/32 (E7),
   33/34 (E10), 38/40 (E18), 35 (24-hour single rate).
3. `_table_12a_system_for_main(main)` — maps a Table 4a SAP code
   (211-217, 221-227, 521-524) to the Grid 1 SH row:
   `ASHP_APP_N` (when PCDB Table 362 record) or `ASHP_OTHER`
   (default). Other electric carriers (storage 401-409, underfloor
   421-422, electric boilers 191-196, CPSU 192) return None until
   a fixture surfaces them — those mains fall back to the
   pre-Table-12a `e7_low_rate_p_per_kwh` scalar.

Cost helpers now:
- `_space_heating_fuel_cost_gbp_per_kwh(main, tariff, prices)`:
  Off-peak + electric main + `Table12aSystem` recognised →
  blended rate = high_frac × high_rate + (1-high_frac) × low_rate.
  STANDARD or unknown Table12aSystem → preserve legacy fallback.
- `_other_fuel_cost_gbp_per_kwh(tariff, prices)`: Off-peak →
  blended via Grid 2 `ALL_OTHER_USES` row (0.90 high on 7-hour,
  0.80 high on 10-hour).
- `_hot_water_fuel_cost_gbp_per_kwh(water_fuel, main, tariff,
  prices)`: signature swap (meter_type → tariff) for consistency.
  Behavioural change deferred (HW Grid 1 WH-row split is its own
  slice).

Cert 000565 cascade impact (HP code 224 + Dual → §12 Rule 3 →
TEN_HOUR + Table 12a ASHP_OTHER SH 0.60 high, ALL_OTHER_USES 0.80
high):
- space_heating tariff: 0.094 → 0.11808 ✓ matches worksheet
- other_fuel tariff:     0.165 → 0.13244 ✓ matches worksheet
- hot_water tariff:      gas 0.0364 (Table 12 mains gas) — vs
  worksheet 0.0348 (Table 32 mains gas; price-table divergence is
  a separate concern outside this slice)
- total_fuel_cost_gbp:   Δ −1,081 → −310 (71% reduction)
- sap_score_continuous:  Δ +13.81 → +3.61

Cohort regression check: 427 pass + 10 expected 000565 fails.
Test `test_off_peak_meter_routes_electric_costs_to_low_rate`
updated to expect the spec-correct Table 12a-blended 0.14311
(was 0.1649 under the pre-S0380.61 "empirical" override).

Spec source: SAP 10.2 Table 12a Grid 1 (SH) + Grid 2 (other uses)
page 191. RdSAP 10 §12 page 62 dispatch (verified Slice S0380.60).
RdSAP 10 Table 32 page 95 prices.

Pyright net-zero on both touched files (34 / 11; baseline 34 / 11).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 16:28:47 +00:00
..
addresses standardist Address 2026-05-22 10:13:32 +00:00
data_transformation moved classifier data transformation to an easy one 2026-06-01 14:53:34 +00:00
epc pr review, move domain and orhcestration 2026-06-01 14:00:31 +00:00
sap10_calculator Slice S0380.61: wire RdSAP §12 dispatch + Table 12a high-rate fractions into cost scalars 2026-06-01 16:28:47 +00:00
sap10_ml Slice S0380.26: RdSAP10 §5.8 dry-lining adjustment on alt walls — closes cert 7700 -0.44 → +5e-5 2026-06-01 16:28:46 +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