diff --git a/scripts/audit/anomalies.py b/scripts/audit/anomalies.py index c856a5d17..762fc30a5 100644 --- a/scripts/audit/anomalies.py +++ b/scripts/audit/anomalies.py @@ -189,6 +189,11 @@ def _effective_lodged_divergence(a: PropertyAudit) -> Optional[str]: return f"effective {a.effective_sap:.0f} vs lodged {a.lodged_sap:.0f} (Δ{gap:+.0f}, reason={a.rebaseline_reason})" +@check("implausible-lodged-score", Severity.LOW) +def _implausible_lodged_score(a: PropertyAudit) -> Optional[str]: + raise NotImplementedError + + @check("impossible-sap-over-100", Severity.HIGH) def _impossible_sap_over_100(a: PropertyAudit) -> Optional[str]: """A SAP score above 100 is impossible (SAP caps at 100) — a calculator / diff --git a/tests/scripts/test_audit_anomalies.py b/tests/scripts/test_audit_anomalies.py index b6acf3fde..69cd25080 100644 --- a/tests/scripts/test_audit_anomalies.py +++ b/tests/scripts/test_audit_anomalies.py @@ -5,6 +5,7 @@ import pytest from scripts.audit.anomalies import ( PropertyAudit, _effective_lodged_divergence, + _implausible_lodged_score, ) @@ -46,3 +47,28 @@ class TestEffectiveLodgedDivergence: # Assert assert result is None + + def test_fires_when_lodged_sap_at_or_above_floor_with_large_gap(self) -> None: + # Arrange — lodged=20 (band G, plausible), effective=65 (band D), gap +45 + audit = _make_audit(lodged_sap=20.0, effective_sap=65.0) + + # Act + result = _effective_lodged_divergence(audit) + + # Assert + assert result is not None + assert "65" in result + assert "20" in result + + +class TestImplausibleLodgedScore: + def test_fires_when_lodged_sap_below_floor_and_gap_large(self) -> None: + # Arrange — Class C exemplar: lodged=1, effective=76 (gap +75) + audit = _make_audit(lodged_sap=1.0, effective_sap=76.0) + + # Act + result = _implausible_lodged_score(audit) + + # Assert + assert result is not None + assert "1" in result