From 98aa0127a78074f4375483b77617a98fe74f5559 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 14 Jul 2026 17:40:50 +0000 Subject: [PATCH] =?UTF-8?q?Keep=20swallowing=20the=20control=20gap's=20bou?= =?UTF-8?q?ndary=20form=20in=20the=20accuracy=20harness=20=F0=9F=9F=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The control gap surfaces as UnmappedSapCode on main and as UnmappedPasHubLabel once the #1557 control mapper lands (unmapped community-heating control), so the harness must swallow both; only the closed fuel-specific MissingMainFuelType is dropped as a fuel-drop tripwire. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../tests/test_pashub_sap_accuracy.py | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/backend/documents_parser/tests/test_pashub_sap_accuracy.py b/backend/documents_parser/tests/test_pashub_sap_accuracy.py index 191e87930..c6a4a4e0e 100644 --- a/backend/documents_parser/tests/test_pashub_sap_accuracy.py +++ b/backend/documents_parser/tests/test_pashub_sap_accuracy.py @@ -21,11 +21,11 @@ a **hybrid** gate: calculable `EpcPropertyData`. Any *unexpected* exception is a hard fail (a real extractor/mapper bug on that property). The one *known* remaining gap — the pashub mapper not coding a main-heating `main_heating_control` label to a - SAP code (`UnmappedSapCode`) — is `xfail`ed dynamically, so these flip to - passing automatically once that mapper fix lands. The main-fuel-code gap + SAP code — is `xfail`ed dynamically (see `_KNOWN_GAPS` for its two forms), so + these flip to passing once that mapper fix lands. The main-fuel-code gap (`Bulk LPG`, and the `Fuel:`-form Mains Gas the extractor was dropping) was - closed in #1558, so those exceptions are *no longer* swallowed — a fixture - that regresses to a fuel gap now hard-fails. + closed in #1558, so `MissingMainFuelType` is *no longer* swallowed — a + fixture that regresses to a dropped fuel now hard-fails. * `test_pashub_sap_accuracy_aggregate` — over the fixtures that compute: fraction within 0.5 SAP of `pre_sap`, and MAE. Ratcheting floor/ceiling @@ -45,17 +45,20 @@ from typing import Optional import pytest from backend.documents_parser.parser import parse_site_notes_pdf +from datatypes.epc.domain.mapper import UnmappedPasHubLabel from domain.sap10_calculator.calculator import Sap10Calculator from domain.sap10_calculator.exceptions import UnmappedSapCode # Known in-progress pashub main-heating string→SAP-code mapper gaps, fixed -# field-by-field. The remaining gap is a raw `main_heating_control` label the -# calculator can't code (`UnmappedSapCode`) — it xfails until that mapper fix -# lands. The main-fuel-code gaps are closed: mains-gas code landed in #1554, and -# #1558 coded "Bulk LPG" and captured the `Fuel:`-form Mains Gas the extractor -# was dropping. Their exceptions (`UnmappedPasHubLabel`, `MissingMainFuelType`) -# are deliberately *not* here, so a fuel regression hard-fails instead of hiding. -_KNOWN_GAPS: tuple[type[Exception], ...] = (UnmappedSapCode,) +# field-by-field. The remaining gap is the `main_heating_control` label, which +# surfaces in one of two forms: `UnmappedSapCode` (raw label reaches the +# calculator) or, once the control mapper (#1557) lands, `UnmappedPasHubLabel` +# (strict-raised at the boundary for a control label not yet mapped — e.g. the +# cohort's community-heating charging control). Both xfail until that fix lands. +# The main-fuel-code gaps are closed (mains-gas code #1554; "Bulk LPG" + the +# `Fuel:`-form Mains Gas the extractor was dropping #1558), so `MissingMainFuelType` +# is deliberately *not* here — a fuel-drop regression hard-fails instead of hiding. +_KNOWN_GAPS: tuple[type[Exception], ...] = (UnmappedSapCode, UnmappedPasHubLabel) _FIXTURES_DIR = Path(__file__).parent / "fixtures" / "pashub_accuracy" _MANIFEST_PATH = _FIXTURES_DIR / "manifest.json"