Model/tests/domain/modelling
Khalim Conn-Kowlessar 49e86344d2 feat(modelling): whole-package re-score + greedy repair (#1160)
Slice 2 of #1160 — the ADR-0016 truth step on top of the warm-start
knapsack. optimise_package(groups, scorer, baseline_epc, budget,
target_sap) -> OptimisedPackage:

  warm-start optimise() (role-1 signal) → re-score the chosen package on
  the real scorer (role-2 truth) → while the true SAP undershoots
  target_sap and budget remains, greedy-add the untreated-group Option
  with the best *marginal* SAP-per-£ (re-scored, not the role-1 signal),
  re-score, repeat until the target is met, nothing positive-marginal is
  affordable, or the budget is spent.

`Scorer` is a structural Protocol (PackageScorer satisfies it) so the
repair loop is tested with a stub scorer — no calculator, runs on ARM.
The key case: role-1 under-counts roof so the warm-start skips it, the
re-score undershoots, and repair adds roof back to hit the target. 3
repair tests + the 6 core tests; pyright strict clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 12:45:05 +00:00
..
fixtures feat(modelling): floor insulation-type overlay field + cascade pins (#1159) 2026-06-03 09:41:54 +00:00
__init__.py feat(modelling): Overlay Applicator folds EpcSimulation onto EpcPropertyData 2026-06-02 22:13:51 +00:00
_elmhurst_recommendation.py test(modelling): Elmhurst before/after cascade pin for cavity wall (#1154) 2026-06-03 09:36:53 +00:00
test_elmhurst_cascade_pins.py feat(modelling): floor insulation-type overlay field + cascade pins (#1159) 2026-06-03 09:41:54 +00:00
test_floor_recommendation.py feat(modelling): floor Recommendation Generator + ground-floor-area geometry 2026-06-03 09:12:29 +00:00
test_optimiser.py feat(modelling): whole-package re-score + greedy repair (#1160) 2026-06-03 12:45:05 +00:00
test_overlay_applicator.py feat(modelling): Overlay Applicator folds EpcSimulation onto EpcPropertyData 2026-06-02 22:13:51 +00:00
test_package_scorer.py feat(modelling): Package Scorer — compose overlays + score on the calculator 2026-06-03 08:41:30 +00:00
test_plan.py feat(modelling): domain Plan + PlanMeasure types (#1157) 2026-06-03 11:40:27 +00:00
test_roof_recommendation.py feat(modelling): loft overlay 270→300 mm + Elmhurst cascade pin (#1158) 2026-06-03 09:39:21 +00:00
test_scoring.py feat(modelling): per-measure scoring — marginal cascade + per-Option signal (#1156) 2026-06-03 08:50:49 +00:00
test_wall_recommendation.py feat(modelling): price the cavity Option from area x Product — closes #1155 2026-06-03 08:35:52 +00:00