Phase-2 candidates are valued against the post-fabric dwelling 🟩

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-09 11:40:34 +00:00
parent 705c86d5e6
commit 7f4d313932

View file

@ -272,7 +272,7 @@ def optimise_package_fabric_first(
None if budget is None else budget - _package_cost(fabric_package.selected)
)
top_up: OptimisedPackage = optimise_package(
groups=remaining_groups,
groups=_rescored_groups(remaining_groups, post_fabric_scorer, baseline_epc),
scorer=post_fabric_scorer,
baseline_epc=baseline_epc,
budget=leftover_budget,
@ -293,6 +293,31 @@ def _is_fabric_group(group: list[ScoredOption]) -> bool:
)
def _rescored_groups(
groups: list[list[ScoredOption]],
scorer: Scorer,
baseline_epc: EpcPropertyData,
) -> list[list[ScoredOption]]:
"""The groups with every Option's role-1 warm-start signal re-scored
through ``scorer`` for phase 2, its independent gain on the post-fabric
dwelling rather than the raw baseline, so options whose worth changes once
the envelope is treated (a boiler on an insulated home) are re-ranked."""
start_sap: float = scorer.score(baseline_epc, []).sap_continuous
return [
[
ScoredOption(
option=scored.option,
sap_gain=scorer.score(
baseline_epc, [scored.option.overlay]
).sap_continuous
- start_sap,
)
for scored in group
]
for group in groups
]
class _PrefixedScorer:
"""A Scorer view of the dwelling with a committed package already applied:
every score call sees the ``prefix`` overlays before the candidate's own.