Guard the glazing classifier so an aggregate mix keeps the cert per-window glazing 🟩

Wires GuardedColumnClassifier(glazing_mix_guard, <llm>) into the glazing column so a
structured percentage mix deterministically resolves to MIXED (no overlay), while
uniform and varied phrasings fall through to the LLM (#1376, ADR-0042).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-01 11:07:45 +00:00
parent f11fc9bc04
commit 1500725d1d

View file

@ -10,6 +10,7 @@ from applications.landlord_description_overrides.landlord_description_overrides_
from domain.epc.property_overrides.built_form_type import BuiltFormType
from domain.epc.property_overrides.construction_age_band import ConstructionAgeBand
from domain.epc.property_overrides.glazing_type import GlazingType
from domain.epc.property_overrides.glazing_mix_guard import glazing_mix_guard
from domain.epc.property_overrides.main_fuel_type import MainFuelType
from domain.epc.property_overrides.main_heating_system_type import MainHeatingSystemType
from domain.epc.property_overrides.property_type import PropertyType
@ -146,8 +147,15 @@ def _build_columns(
"glazing": lambda src: ClassifiableColumn(
name="glazing",
source_column=src,
classifier=ChatGptColumnClassifier(
chat_gpt, GlazingType, GlazingType.UNKNOWN
# An aggregate glazing mix ("40% double, 60% single") can't be applied
# per-window, so the deterministic guard resolves the structured split
# to MIXED (no overlay → keep the cert's per-window glazing) and the LLM
# handles uniform / varied phrasings (#1376, ADR-0042).
classifier=GuardedColumnClassifier(
guard=glazing_mix_guard,
fallback=ChatGptColumnClassifier(
chat_gpt, GlazingType, GlazingType.UNKNOWN
),
),
repo=LandlordOverridesRepository[GlazingType](
session, LandlordGlazingOverrideRow