Model/tests/orchestration
Khalim Conn-Kowlessar 31c74ab500 feat(modelling): gas-boiler-upgrade-with-cylinder option in the heating rec
Add the first boiler-upgrade option to the single "Heating & Hot Water"
Recommendation (ADR-0024 expansion): a dwelling whose existing wet boiler heats
a hot-water cylinder is offered a new gas condensing boiler, with the cylinder
jacketed when under-insulated and given a thermostat when absent. One competing
Option (the Optimiser picks <=1), folded into one composite Plan line.

The end-state is read from the Elmhurst before/after re-lodgements (cert 001431,
gas boiler upgrade - with cylinder), which REVISE ADR-0024:

- Target is always a gas condensing boiler, not fuel-preserving: every after
  lodges fuel 26. Gas->gas always; a non-gas wet boiler ->gas only with a
  mains-gas connection; electric boilers are left alone (electrification is the
  upgrade path). Eligibility = wet-boiler SAP code (Table 4a/4b 101-141 /
  151-161 / 191-196) + not an electric boiler + mains gas present.
- End-state is a Table 4b SAP code, not a PCDB index: code 102 (regular boiler
  + cylinder). The calculator derives the condensing seasonal efficiency from
  the code, so no efficiency input exists or is needed.
- A modern condensing boiler has a fanned flue: the after flips
  `fan_flue_present` False->True on every cert (SAP 10.2 Table 4f flue-fan +
  the Table 4b condensing-efficiency basis). Added as a new HeatingOverlay
  field, routed to main_heating_details[0].
- Cylinder thermostat is always added when absent (user-locked); the jacket is
  the 80 mm `cylinder_insulation_type=2` end-state, applied only when the
  cylinder is below 80 mm (never downgrading a better one). Both are conditional
  per-dwelling components, not a frozen overlay.

Cascade-pinned delta-0 (SAP/CO2/PE) against the relodged after via
`_assert_overlay_reproduces_after`. NB the absolute SAP on this dwelling is
subject to a separate Summary-path mapper roof-fidelity gap (we read the roof
better-insulated than Elmhurst, scoring ~75 vs the printed 56); the gap is
identical on before+after (the boiler measure never touches the roof) so it
cancels and the pin still proves the exact heating field-delta. Tracked on the
calculator branch.

Wires the new `gas_boiler_upgrade` MeasureType through contingencies (0.26),
the offline sample catalogue, the catalogue-coverage list, and the ARA
first-run integration seed (the option fires on any mains-gas boiler+cylinder
dwelling).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 16:16:46 +00:00
..
__init__.py added postcode splitter rewrite to ddd 2026-05-19 16:35:09 +00:00
fakes.py Merge origin/main into feature/bill-derivation (calculator + mapper fixes) 2026-06-08 13:12:21 +00:00
test_ara_first_run_pipeline.py feat(modelling): ModellingOrchestrator persists a Plan end-to-end (#1157) 2026-06-03 12:08:32 +00:00
test_ara_first_run_pipeline_integration.py feat(modelling): gas-boiler-upgrade-with-cylinder option in the heating rec 2026-06-09 16:16:46 +00:00
test_bulk_upload_finaliser_orchestrator.py fix 2026-06-05 17:24:17 +00:00
test_first_run_without_database.py feat(modelling): run_one console entrypoint for DB-less inspection 2026-06-04 08:14:14 +00:00
test_ingestion_orchestrator.py feat(ingestion): cache the spatial reference per UPRN 2026-06-04 17:24:03 +00:00
test_landlord_description_overrides_orchestrator.py moved classifier data transformation to an easy one 2026-06-01 14:53:34 +00:00
test_modelling_solar_threading.py feat(modelling): considered_measures allowlist on the orchestrator 2026-06-08 20:32:11 +00:00
test_postcode_splitter_orchestrator.py updated rdsap option; seperated s3 location in infrastrucutre; added open ai api 2026-05-22 14:00:33 +00:00
test_property_baseline_orchestrator.py feat(baseline): CalculatorRebaseliner — calculator goes load-bearing (ADR-0013 amend) 2026-06-04 15:40:26 +00:00
test_task_orchestrator.py tests framework completed 2026-05-20 14:00:19 +00:00