Re-map old-storage HHRSH overrides onto the high-heat-retention archetype 🟥

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-01 14:33:24 +00:00
parent 598aac1556
commit 04484edc67
2 changed files with 82 additions and 0 deletions

View file

@ -0,0 +1,12 @@
"""One-time re-classification of HHRSH overrides funnelled into old storage.
Placeholder decision function stubbed; filled in GREEN.
"""
from __future__ import annotations
from collections.abc import Iterable
def hhrsh_storage_corrections(stored: Iterable[tuple[str, str]]) -> dict[str, str]:
raise NotImplementedError

View file

@ -0,0 +1,70 @@
"""The HHRSH reclassify maps the "old storage" dumping ground onto the high-heat-
retention archetype, leaves other storage subtypes alone, and is idempotent
(#1376 / ADR-0044)."""
from __future__ import annotations
from domain.epc.property_overlays.main_heating_system_overlay import (
main_heating_overlay_for,
)
from domain.epc.property_overrides.main_heating_guard import main_heating_guard
from domain.epc.property_overrides.main_heating_system_type import (
MainHeatingSystemType,
)
from scripts.reclassify_hhrsh_storage import hhrsh_storage_corrections
def test_hhrsh_rows_are_remapped_off_old_storage() -> None:
# Arrange — HHRSH funnelled into old storage (the bug), plus a genuinely-old
# storage row and a gas row that must be left untouched.
stored = [
(
"electric storage systems: high heat retention storage heaters",
"Electric storage heaters, old",
),
(
"electric storage systems: old (large volume) storage heaters",
"Electric storage heaters, old",
),
("gas boiler", "Gas boiler, regular"),
]
# Act
corrections = hhrsh_storage_corrections(stored)
# Assert — only the HHRSH row moves, to its own archetype.
assert corrections == {
"electric storage systems: high heat retention storage heaters": (
"Electric storage heaters, high heat retention"
)
}
def test_every_guard_target_round_trips_to_a_resolvable_archetype() -> None:
# The HHRSH archetype the guard emits must decode to a real SAP heating code —
# a guard/overlay drift can't silently write an unmodellable value (ADR-0044).
member = main_heating_guard(
"Electric Storage Systems: High heat retention storage heaters"
)
assert member is not None
assert member in MainHeatingSystemType
simulation = main_heating_overlay_for(member.value, 0)
assert simulation is not None
assert simulation.heating is not None
assert simulation.heating.sap_main_heating_code is not None
def test_already_corrected_rows_need_no_change() -> None:
# Act / Assert — idempotent.
assert (
hhrsh_storage_corrections(
[
(
"electric storage systems: high heat retention storage heaters",
"Electric storage heaters, high heat retention",
)
]
)
== {}
)