Flag works bought for no real SAP gain 🟥

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-21 15:53:59 +00:00
parent 8c2c19495c
commit 08d2b874d5
2 changed files with 73 additions and 0 deletions

View file

@ -187,6 +187,11 @@ def _already_meets_goal_with_works(a: PropertyAudit) -> Optional[str]:
return f"already {a.effective_band} >= goal {a.scenario_goal_band} but cost_of_works £{a.cost_of_works:.0f}"
@check("costed-plan-without-real-gain", Severity.HIGH)
def _costed_plan_without_real_gain(a: PropertyAudit) -> Optional[str]:
raise NotImplementedError
@check("plan-stops-short-of-goal", Severity.HIGH)
def _plan_stops_short_of_goal(a: PropertyAudit) -> Optional[str]:
"""The default plan ends BELOW the scenario's goal band on a scenario that is

View file

@ -10,6 +10,7 @@ from scripts.audit.anomalies import (
PropertyAudit,
Severity,
_already_meets_goal_with_works, # pyright: ignore[reportPrivateUsage]
_costed_plan_without_real_gain, # pyright: ignore[reportPrivateUsage]
_effective_lodged_divergence, # pyright: ignore[reportPrivateUsage]
_implausible_lodged_score, # pyright: ignore[reportPrivateUsage]
_plan_stops_short_of_goal, # pyright: ignore[reportPrivateUsage]
@ -213,3 +214,70 @@ class TestAlreadyMeetsGoalWithWorks:
# Assert
assert registered["already-meets-goal-with-works"] is Severity.HIGH
class TestCostedPlanWithoutRealGain:
"""Money spent for no meaningful SAP movement (#1652 / #1655).
The coverage hole the #1652 diagnosis found: `plan-score-below-baseline`
only fires on a *drop* beyond 0.5 and `zero-works-post-differs` only on £0
plans, so a costed plan landing flat against the effective baseline was
caught by neither including the 112 homes whose modelled post-retrofit SAP
sat ~0.2 *below* their effective baseline.
"""
def test_fires_when_works_are_bought_for_no_real_gain(self) -> None:
# Arrange — £6,240 of works moving the dwelling 0.2 SAP.
audit = _make_audit(
effective_sap=63.0, post_sap=63.2, cost_of_works=6240.0
)
# Act
result = _costed_plan_without_real_gain(audit)
# Assert
assert result is not None
assert "6240" in result or "6,240" in result
def test_fires_when_the_post_score_lands_below_the_baseline(self) -> None:
# Arrange — the likely-downgrade case: paid works, post *below* baseline.
audit = _make_audit(
effective_sap=63.0, post_sap=62.8, cost_of_works=1029.0
)
# Act
result = _costed_plan_without_real_gain(audit)
# Assert
assert result is not None
def test_silent_when_the_works_deliver_a_real_uplift(self) -> None:
# Arrange — £6,240 buying 9 SAP points: what a retrofit should look like.
audit = _make_audit(
effective_sap=63.0, post_sap=72.0, cost_of_works=6240.0
)
# Act
result = _costed_plan_without_real_gain(audit)
# Assert
assert result is None
def test_silent_on_a_zero_cost_plan(self) -> None:
# Arrange — no money spent, so there is nothing to justify; a £0 plan
# that moves nothing is the correct outcome for an already-compliant
# dwelling, and is covered by its own check.
audit = _make_audit(effective_sap=63.0, post_sap=63.0, cost_of_works=0.0)
# Act
result = _costed_plan_without_real_gain(audit)
# Assert
assert result is None
def test_is_registered_at_high_severity(self) -> None:
# Act
registered = {name: severity for name, severity, _ in _REGISTRY}
# Assert
assert registered["costed-plan-without-real-gain"] is Severity.HIGH