Model/backend/documents_parser
Khalim Conn-Kowlessar c17330b319 Slice S0380.173: Community heating HW path routes through main fuel
Closes CH1 (boilers) + CH3 (HP) HW CO2 / PE residuals by routing
the HW cost / CO2 / PE factor lookups through the heat-network main
when WHC ∈ {901, 902, 914} ("HW from main heating system"). Pre-
slice the cascade honoured Elmhurst Summary §15.0's
`water_heating_fuel_type = "Mains gas"` placeholder on community-
heated certs, mis-routing HW through Table 12 code 1 (mains gas,
3.48 p/kWh / 0.21 CO2 / 1.13 PE) instead of the heat-network code
(4.24 p/kWh + Table 12 code 41 / 51 / 53 / 54 with Table 4a heat-
source-eff scaling per S0380.172).

Per SAP 10.2 §C1 + RdSAP 10 §C (PDF p.49 + p.58) the HW heat
delivered by a heat-network main is supplied through the same
network as SH: spec block 10b (342a)/(342b) computes HW cost as
`(310a) × CHP_price + (310b) × boiler_price`, mirroring SH's
(340a)/(340b) split. Block 12b (365)/(366) and 13a (465)/(466)
likewise apply the heat-source-eff division on HW.

Three layers wired:

1. New `_is_community_heating_hw_from_main(epc)` predicate. Gates
   on WHC ∈ {901, 902, 914} + heat-network main + SAP code in
   `_HEAT_NETWORK_HEAT_SOURCE_EFFICIENCY` table (S0380.172 — only
   301 boilers + 304 HP). SAP 302 (CHP+boilers) is excluded
   because the 35%/65% split needs the displaced-electricity
   credit cascade per spec block 13b (464)/(466) on BOTH SH and HW
   paths — both converge in a single follow-up slice.

2. `_hot_water_fuel_cost_gbp_per_kwh` gains a keyword-only
   `inherit_main_for_community_heating: bool = False` parameter.
   When True, returns `_fuel_cost_gbp_per_kwh(main, prices)` —
   same helper that already applies the S0380.171 CHP blend +
   heat-network rate. The orchestrator passes
   `inherit_main_for_community_heating=_is_community_heating_hw_
   from_main(epc)` at the cost-rate construction site.

3. `_hot_water_co2_factor_kg_per_kwh` and `_hot_water_primary_
   factor` get top-level branches: when the predicate fires, return
   `Table_12_factor × _heat_network_heat_source_efficiency_scaling
   (main)` — same scaled-factor return as the SH path in S0380.172.

Closures (heating-systems corpus block 11b):

  CH1 (Boilers/Gas) ΔPE   −967 → −9    (essentially closed)
  CH1               ΔCO2 −126 → +52    (shifted across worksheet)
  CH3 (HP/Elec)     ΔPE  +1749 → −387  (~78% closure)
  CH3               ΔCO2 +473 → −86    (~82% closure)

Cost / SAP signs flip on CH1 / CH3 (was −£14 / +0.59 SAP, now
+£12 / −0.53 SAP) — HW cost now matches the worksheet's (342) line
exactly, exposing a +£12 lighting / standing overage that was
previously masked by the HW under-charge. Per [[feedback-software-
no-special-handling]] the pre-slice near-zero on CH1 / CH3 cost was
an offsetting-bugs artifact; the spec-correct fix surfaces the real
lighting / standing gap as the next forcing function.

CH2 / CH4 / CH6 (SAP 302) unchanged from S0380.171 / S0380.172 pins
— gated out per the heat-source-eff-table membership check.

Test baseline at HEAD: 926 pass + 1 skipped (was 926 + 1 at
predecessor 36d4bf87). Pyright net-zero on affected files
(cert_to_inputs.py, test_heating_systems_corpus.py): 32 → 32.

Per [[feedback-spec-citation-in-commits]] the rule cites SAP 10.2
§C1 verbatim ("heat from CHP + back-up boilers, via a heat main")
and RdSAP 10 §C defaults (PDF p.58).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 15:40:26 +00:00
..
handler address JTK review comments 2026-04-20 15:11:17 +00:00
tests Slice S0380.173: Community heating HW path routes through main fuel 2026-06-04 15:40:26 +00:00
__init__.py Map to RdSapSiteNotes from site notes JSON 🟥 2026-04-16 13:54:03 +00:00
db_writer.py include updating epc_property_data to pashub to ara workflow 2026-04-29 09:55:14 +00:00
elmhurst_extractor.py Slice S0380.170: Community heating mapper unblock (Table 12 dispatch) 2026-06-04 15:40:25 +00:00
extractor.py Handle wall thickness "Unmeasurable" 🟩 2026-04-30 16:41:16 +00:00
local_runner.py update local runner to work for elmhurst 2026-04-24 14:01:36 +00:00
parser.py load ecmk site notes to db 2026-04-29 11:20:47 +00:00
pdf.py update local runner to work for elmhurst 2026-04-24 14:01:36 +00:00