mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
docs(adr): secondary heating removal — ADR-0028 + CONTEXT term
Records the four load-bearing design decisions from the grill-with-docs session: standalone co-selectable rec; eligibility = lodged-only (no effectiveness gate, electric-storage §A.2.2 no-op is the Optimiser's call); dedicated clearing SecondaryHeatingOverlay; flat per-dwelling cost (a lodged secondary is fixed per RdSAP, so a real decommission job, not room-scaled). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
0d1ec2228d
commit
f9a89a8e11
2 changed files with 37 additions and 0 deletions
|
|
@ -274,6 +274,10 @@ _Avoid_: "low energy lighting" as the upgrade target (we go to **LED**); treatin
|
|||
The rule fixing which **Measure Options** the single **Heating & Hot Water** Recommendation offers (ADR-0024, expanded). The competing Options are **mutually-exclusive** (the Optimiser picks at most one) and fall in two families: **whole-system replacements** — `high_heat_retention_storage_heaters`, `air_source_heat_pump` — which change main heating + **controls + fuel + meter + the implied hot water** at once (never a separate HW measure; the legacy heating-vs-HW split double-counted); and, for a dwelling keeping a serviceable wet boiler, **partial upgrades** — `gas_boiler_upgrade` (a like-for-like condensing **gas** boiler: gas→gas, or non-gas→gas only where mains gas is present; combi or regular-plus-cylinder, shaped by the dwelling) and the **system tune-up** (keep the boiler; install better **controls** + fix the **cylinder**), the tune-up offered at two competing control levels: `system_tune_up` (standard, SAP code 2106) and `system_tune_up_zoned` (time-and-temperature zone control, 2110 — more SAP uplift, more cost). Each Option is a **fixed, real, contractor-installable end-state** (ASHP via a fixed PCDB heat-pump index; HHR storage via `sap_main_heating_code=409`; the gas boiler via Table 4b code 102/104; controls via 2106/2110), not a derived ideal; **Product** stays cost-only, but a partial/bundle cost is **composed per dwelling** from the components the overlay installs (ADR-0025/0027), not a flat scalar. Eligibility encodes **only physical/planning installability** — the **Optimiser owns the economics**, so it must not re-gate on cost proxies: **ASHP** → houses/bungalows that are not **listed**/**heritage** and not already a heat pump (flats excluded — individual siting needs a survey; a **conservation area** still gets the offer, unlike glazing); **HHR storage** → off-gas or currently-electric dwellings, not community-heated or already HHR; **boiler upgrade / tune-up** → an existing (non-electric) wet boiler, the gas end-state gated on a mains-gas connection, a partial control upgrade offered only when it genuinely improves the existing control (never a downgrade or no-op). Floor area, fabric, fuel, and built form are **not** gates (the legacy ASHP built-form / 120 m² rule is dropped — no authoritative basis). A free Optimiser candidate, not a forced **Measure Dependency**.
|
||||
_Avoid_: separate "heating" and "hot water" recommendations (HW folds into each Option); gating ASHP on floor area / built form / fabric (eligibility is physical/planning only — the Optimiser decides cost-effectiveness); treating the whole-system replacements and the partial boiler/tune-up upgrades as **separate** Recommendations (they are mutually-exclusive Options within the one heating rec — separate recs would let the Optimiser co-select and double-charge); a standalone hot-water-only or controls-only Recommendation (controls + cylinder fold into the boiler/tune-up Option)
|
||||
|
||||
**Secondary Heating Removal**:
|
||||
The rule fixing the single Measure the **Secondary Heating Removal** Recommendation offers — strip the dwelling's lodged secondary heating system so the main system serves 100% of space heating (ADR-0028). A **standalone, co-selectable** Recommendation, **not** an Option in the Heating & Hot Water rec: removing a secondary heater is independent of (and combinable with) a tune-up or boiler upgrade, so it must not be made mutually-exclusive with them. Eligibility is purely physical — offered **iff a secondary is lodged** (`secondary_heating_type` is set); since RdSAP only records a secondary when a **fixed** emitter is present (portable plug-in heaters are ignored), a lodged secondary is by definition a fixed unit worth removing. There is **no effectiveness gate**: on an electric-storage main, RdSAP §A.2.2 *forces a default secondary back*, so removal yields zero SAP change — the **Optimiser** de-selects those (it owns the economics), eligibility does not pre-filter them. The change is a dedicated **Simulation Overlay** (`SecondaryHeatingOverlay`) that *clears* the secondary fields — the one overlay that sets a value to absent rather than to a target state. Priced at a **flat per-dwelling decommission cost** (one electrician visit to disconnect a fixed/hard-wired heater + localised making-good), not scaled by room count (the EPC carries no heater count).
|
||||
_Avoid_: making it an Option inside the Heating & Hot Water rec (it is independent, not mutually-exclusive); gating out electric-storage dwellings where removal is a no-op (that is the Optimiser's call, not eligibility's); pricing by room count (the legacy room proxy — the EPC lodges one secondary system with no count); "secondary heating" as the Measure name (name the action: **Secondary Heating Removal**)
|
||||
|
||||
### Valuation
|
||||
|
||||
**Property Valuation**:
|
||||
|
|
|
|||
33
docs/adr/0028-secondary-heating-removal.md
Normal file
33
docs/adr/0028-secondary-heating-removal.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Secondary Heating Removal — standalone recommendation, eligibility, overlay, costing
|
||||
|
||||
We model "removal of secondary heating" — stripping a dwelling's lodged secondary heating system so the main system serves 100% of space heating — as a **standalone, co-selectable Recommendation** (`MeasureType.SECONDARY_HEATING_REMOVAL`), built API-inputs-first. This records the four load-bearing, non-obvious choices made designing it.
|
||||
|
||||
## Status
|
||||
|
||||
Accepted.
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. Standalone Recommendation, not an Option in the Heating & Hot Water rec
|
||||
|
||||
The heating expansion (ADR-0024) consolidated heating into one rec whose Options are **mutually-exclusive** (the Optimiser picks ≤1) because they are whole-system replacements you would never combine. Secondary-heating removal is different in kind: it is independent of, and freely combinable with, a tune-up or a boiler upgrade (you can remove a panel heater *and* upgrade the controls). Making it an Option would falsely force mutual exclusivity with the partial heating upgrades. As a standalone rec it composes additively like loft/cavity/glazing.
|
||||
|
||||
The redundancy risk with a whole-system bundle is self-resolving: an ASHP is calculator-category 4 → secondary fraction is already 0.00, so removal adds **zero marginal SAP** on top of it, and a SAP-maximising Optimiser never pays for a zero-gain measure. The two overlays touch disjoint fields, so there is no double-*SAP*-counting either.
|
||||
|
||||
### 2. Eligibility is physical only — offer iff a secondary is lodged; no effectiveness gate
|
||||
|
||||
Offered **iff `sap_heating.secondary_heating_type is not None`** (a surveyor-lodged secondary exists to remove). Per ADR-0024's principle — *eligibility encodes only physical/planning installability; the Optimiser owns the economics* — we deliberately do **not** gate out the cases where removal cannot move SAP.
|
||||
|
||||
The surprising case: on an **electric-storage main** (SAP codes 401–407/409/421), RdSAP §A.2.2 **forces a default secondary (693, portable electric) back** even after the lodged one is removed, so removal is a guaranteed zero-SAP no-op. That is an *effectiveness* fact, not an installability one — so eligibility still offers it, and the Optimiser de-selects it (zero gain, real cost). This is why our only example cert (001431, main 402) shows F35→F35 unchanged, matching Elmhurst exactly.
|
||||
|
||||
### 3. A dedicated `SecondaryHeatingOverlay` that *clears* fields
|
||||
|
||||
Every other Simulation Overlay obeys "a `None` field means leave the baseline unchanged" and writes **target states**. Removal is the opposite — it must set `secondary_heating_type` and `secondary_fuel_type` *to* `None`, which that convention structurally cannot express. Rather than wart the absolute-target-state `HeatingOverlay` with a remove-flag, removal gets its own minimal overlay surface (`SecondaryHeatingOverlay`, with an explicit `remove` flag) + `EpcSimulation` slot + `_fold_secondary_heating`, mirroring the one-overlay-per-measure-family pattern. It is the one overlay that sets a value to *absent*.
|
||||
|
||||
### 4. Flat per-dwelling decommission cost, not room-scaled
|
||||
|
||||
Legacy `recommendations/SecondaryHeating.py` scaled cost by a room count (`habitable − heated`). We price a **flat per-dwelling scalar (~£250, contingency 0.25)** instead. Two reasons: (a) the EPC lodges a *single* secondary system with **no heater count**, so the legacy room proxy is unfounded; (b) because RdSAP only records a secondary when a **fixed** emitter is present (portable plug-in heaters are ignored), a lodged secondary is by definition a fixed unit — its removal is a real but roughly-fixed job (one electrician visit to disconnect/isolate a hard-wired panel/convector/radiant heater + a blanking plate + localised making-good of the wall). The contingency absorbs the unknown count / hard-wire status / repaint extent. No composite `Products` machinery and no `rates.json` entry — a future data-only upgrade if a real per-unit rate sheet arrives.
|
||||
|
||||
## Validation
|
||||
|
||||
The before/after example (cert 001431, main 402) is a forced-secondary delta-0 case, and shares the boiler-fixtures' Summary-path roof-fidelity gap, so the cascade pin asserts the **field-delta** (`score(before + remove-overlay) == score(before)` at delta 0), proving the overlay clears the fields and the calculator correctly re-forces the §A.2.2 default. A **synthetic unit test** recasts 001431's main to a non-forced gas-boiler code and asserts removal yields a *positive* SAP delta (Table 11 fraction → 0), exercising the value path without a second real cert.
|
||||
Loading…
Add table
Reference in a new issue