A main_fuel override beats a heating archetype's natural-fuel default 🟩

overlays_from now applies main_fuel after main_heating_system (stable sort), so
an explicit landlord fuel wins the natural-fuel default the heating archetype
drags, regardless of override row order. apply_simulations is last-wins.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-30 17:06:56 +00:00
parent 260e3cbd32
commit 6276730cfe

View file

@ -67,9 +67,22 @@ _COMPONENT_OVERLAYS: dict[str, Callable[[str, int], Optional[EpcSimulation]]] =
}
# Components whose overlay must be applied LAST so an explicit value wins a
# default another overlay dragged. `apply_simulations` is last-wins and override
# rows arrive in arbitrary order, so a `main_fuel` override must be applied after
# the `main_heating_system` archetype, whose natural-fuel default it overrides
# (ADR-0041) — e.g. "smokeless coal" must beat a solid-fuel room heater's coal
# default.
_APPLY_LAST: frozenset[str] = frozenset({"main_fuel"})
def overlays_from(overrides: ResolvedPropertyOverrides) -> list[EpcSimulation]:
overlays: list[EpcSimulation] = []
for row in overrides.rows:
# Stable sort: non-`_APPLY_LAST` rows keep their order, `main_fuel` goes last.
ordered_rows = sorted(
overrides.rows, key=lambda row: row.override_component in _APPLY_LAST
)
for row in ordered_rows:
mapper = _COMPONENT_OVERLAYS.get(row.override_component)
if mapper is None:
continue