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:57:25 +00:00
parent 08d2b874d5
commit 31be36cca5

View file

@ -26,6 +26,11 @@ be justified against the real distribution, not guessed.
Read-only: this script never writes to the DB.
"""
# Every check is reached through `_REGISTRY` via the `@check` decorator, never by
# name, so pyright sees each one as an unused function. That is the design, not a
# defect — suppress it for the module rather than tagging a dozen definitions.
# pyright: reportUnusedFunction=false
from __future__ import annotations
import argparse
@ -42,6 +47,11 @@ from scripts.e2e_common import build_engine, load_env
# A..G, A best — index is the rank (lower = better) for band comparisons.
_BANDS = "ABCDEFG"
# The smallest SAP movement that counts as a real improvement. The effective
# baseline is a rounded integer, so anything at or under half a point is within
# the rounding the published band already absorbs — invisible on a certificate.
_MIN_REAL_SAP_GAIN = 0.5
def _band_rank(band: Optional[str]) -> Optional[int]:
if band is None or band not in _BANDS:
@ -189,7 +199,34 @@ def _already_meets_goal_with_works(a: PropertyAudit) -> Optional[str]:
@check("costed-plan-without-real-gain", Severity.HIGH)
def _costed_plan_without_real_gain(a: PropertyAudit) -> Optional[str]:
raise NotImplementedError
"""Money was spent but the modelled post-retrofit SAP barely moves off the
effective baseline works that buy no real improvement.
Provenance: #1652 / #1655. This closes a coverage hole rather than adding a
new opinion: `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 baseline was caught by neither. It is what the 112
"no real improvement" homes in portfolio 796 looked like priced plans whose
post-retrofit SAP sat ~0.2 *below* the effective baseline and what the
band-boundary defect (#1654) produced at scale: 630 homes each sold ~1 SAP
point of works toward a band they had already reached.
The 0.5 threshold is the same "within rounding is not a real move" line the
published banding uses: the effective baseline is a rounded integer, so a
sub-half-point shift is not a change anyone can see on a certificate. Spend
that buys less than that is not a retrofit."""
if a.effective_sap is None or a.post_sap is None:
return None
cost = a.cost_of_works or 0.0
if cost <= 0.0:
return None
gain = a.post_sap - a.effective_sap
if gain > _MIN_REAL_SAP_GAIN:
return None
return (
f"£{cost:.0f} of works for {gain:+.1f} SAP "
f"(effective {a.effective_sap:.1f} → post {a.post_sap:.1f})"
)
@check("plan-stops-short-of-goal", Severity.HIGH)
@ -555,11 +592,14 @@ def _load(
rollups = {
m["property_id"]: (m["solar_sap"], m["solar_bill"], m["n_measures"])
for m in (
row._mapping for row in conn.execute(_ROLLUP_QUERY, params)
# `Row._mapping` is public API in SQLAlchemy 2.0; only the
# stub marks it protected.
row._mapping # pyright: ignore[reportPrivateUsage]
for row in conn.execute(_ROLLUP_QUERY, params)
)
}
for r in conn.execute(_QUERY, params):
m = r._mapping
m = r._mapping # pyright: ignore[reportPrivateUsage]
solar_sap, solar_bill, n_measures = rollups.get(m["id"], (None, None, 0))
out.append(
PropertyAudit(