Reclassify electric-underfloor overrides via the generalized main-heating reclassify 🟩

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-01 16:51:22 +00:00
parent 9d106d9d6d
commit f50ee5f957
2 changed files with 42 additions and 2 deletions

View file

@ -1,11 +1,13 @@
"""One-time re-classification of main-heating overrides funnelled into a garbage
drawer for want of a correct archetype (#1376).
Covers both dumping grounds the ``main_heating_guard`` now rescues:
Covers the dumping grounds the ``main_heating_guard`` now rescues:
- **HHRSH** (ADR-0044): "High heat retention storage heaters" "Electric storage
heaters, old" (SAP 401), the worst old type — 111 rows.
- **Gas CPSU** (ADR-0045): solid-fuel room heaters (open fire / + back boiler /
closed + boiler) and electric "NA"-type boilers "Gas CPSU" (120, mains gas).
- **Electric underfloor** (ADR-0046): concrete slab (421) / integrated (422) /
screed (424) dumped into Direct-acting (191) / old storage (401).
The live classifier now applies ``main_heating_guard`` deterministically (so new
intakes are correct); this fixes the rows written before it. The **same guard**

View file

@ -65,12 +65,50 @@ def test_garbage_drawer_rows_are_remapped_to_faithful_archetypes() -> None:
}
def test_electric_underfloor_rows_are_remapped_off_direct_acting_and_old_storage() -> None:
# Underfloor dumped into Direct-acting (191) / old storage (401) → its own codes
# (ADR-0046). Description-determined, so the guard-based reclassify handles it.
stored = [
(
"electric underfloor heating: in concrete slab (off-peak only)",
"Direct-acting electric",
),
(
"electric underfloor heating: integrated (storage+direct-acting) (off peak)",
"Electric storage heaters, old",
),
(
"electric underfloor heating: in screed above insulation (standard or off peak)",
"Direct-acting electric",
),
]
# Act
corrections = main_heating_corrections(stored)
# Assert
assert corrections == {
"electric underfloor heating: in concrete slab (off-peak only)": (
"Electric underfloor, in concrete slab (off-peak)"
),
"electric underfloor heating: integrated (storage+direct-acting) (off peak)": (
"Electric underfloor, integrated storage and direct-acting"
),
"electric underfloor heating: in screed above insulation (standard or off peak)": (
"Electric underfloor, in screed above insulation"
),
}
def test_every_guard_target_round_trips_to_a_resolvable_archetype() -> None:
# Every archetype the guard emits for the rescued descriptions must decode to a
# real SAP heating code — a guard/overlay drift can't silently write an
# unmodellable value (ADR-0044, ADR-0045).
# unmodellable value (ADR-0044, ADR-0045, ADR-0046).
descriptions = [
"Electric Storage Systems: High heat retention storage heaters",
"Electric Underfloor Heating: In concrete slab (off-peak only)",
"Electric Underfloor Heating: Integrated (storage+direct-acting) (off peak)",
"Electric Underfloor Heating: In screed above insulation (standard or off peak)",
"Solid fuel room heaters: Open fire in grate",
"Solid fuel room heaters: Open fire with back boiler (no radiators)",
"Solid fuel room heaters: Closed room heater with boiler (no radiators)",