A Reducing-CO2 scenario maximises carbon reduction, not SAP 🟥

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-09 12:13:06 +00:00
parent 66748ba26d
commit aac35327f7

View file

@ -0,0 +1,59 @@
"""The ModellingOrchestrator aligns the Optimiser's objective with the
Scenario's goal (ADR-0062): Reducing CO2 emissions maximises the carbon
reduction the budget buys, Energy Savings maximises the annual bill saving,
and Increasing EPC keeps its SAP target semantics. End-to-end through
``run_modelling`` (no database) with the real calculator, against the
uninsulated solid-brick 001431 dwelling where the SAP-optimal and
carbon-optimal packages diverge at a £16,000 budget.
"""
from __future__ import annotations
from datatypes.epc.domain.epc_property_data import EpcPropertyData
from domain.modelling.measure_type import MeasureType
from domain.modelling.plan import Plan
from domain.modelling.scenario import Scenario
from harness.console import run_modelling
from tests.domain.modelling._elmhurst_recommendation import (
parse_recommendation_summary,
)
def _solid_brick_dwelling() -> EpcPropertyData:
return parse_recommendation_summary("solid_brick_ewi_001431_before.pdf")
def _scenario(goal: str, *, budget: float) -> Scenario:
return Scenario(
id=999, goal=goal, goal_value="", budget=budget, is_default=True
)
def test_reducing_co2_scenario_buys_carbon_not_sap() -> None:
# Arrange — at £16,000 the SAP objective buys the wall + floor + £3,200
# gas boiler package (~2,069 kg CO2/yr, SAP 72.9). The carbon objective
# swaps the boiler for electric storage heaters (~1,098 kg/yr) — a lower
# SAP, but ~970 kg/yr less carbon on the low-carbon grid.
epc = _solid_brick_dwelling()
# Act — the same dwelling and budget under each goal.
sap_led: Plan = run_modelling(
epc,
scenario=_scenario("Valuation Improvement", budget=16000.0),
print_table=False,
)
carbon_led: Plan = run_modelling(
epc,
scenario=_scenario("Reducing CO2 emissions", budget=16000.0),
print_table=False,
)
# Assert — the goal changes the outcome in the goal's favour: the carbon
# plan cuts materially more CO2 than the SAP plan buys with the same
# money, and the gas boiler that wins on SAP-per-£ is rejected.
assert (
carbon_led.post_retrofit.co2_kg_per_yr
< sap_led.post_retrofit.co2_kg_per_yr - 500.0
)
selected = {measure.measure_type for measure in carbon_led.measures}
assert MeasureType.GAS_BOILER_UPGRADE not in selected