# Valuation Uplift is percentage-primary The Modelling rebuild needs a financial-uplift output (the increase in a Property's market value from a retrofit). The legacy model (`backend/ml_models/Valuation.py`) is **value-primary**: it starts from a current market value and returns absolute pounds. But that current value — a **Property Valuation** — is sourced from a customer upload (or a ~93-entry hardcoded demo stub) and is **absent for the overwhelming majority of Properties**, including every property in an EPC-only scale corpus. A value-primary model therefore produces nothing for almost all inputs. We model **Valuation Uplift** as **percentage-primary** instead: the uplift is computed purely from the **EPC Band** jump (current → target) and is always returned as a percentage; the absolute £ form (`lower/upper/average_value`, `post_retrofit_value`) is derived **only when a Property Valuation is supplied**, otherwise left `None`. This means every Plan gets an inspectable uplift even with no market value, and it cleanly separates the two concepts the word "valuation" was blurring — the externally-sourced **Property Valuation** (a Baseline attribute) from the plan-conditional **Valuation Uplift** (a Plan output). The domain function lives in `domain/modelling/valuation.py` (Modelling is the consumer that knows the target band; relocatable to a neutral package later, as `domain/billing/` was, if Baseline takes ownership of Property Valuation). ## Consequences - The percentage uplift compounds the legacy's four hardcoded broker tables (MoneySupermarket, Lloyds, Knight Frank, Rightmove), taking min/max/average across the sources that cover the band step. These 2022-era figures are ported verbatim as committed reference data; they are a provenance snapshot, not a live source. - The **2× ROI cap** (uplift ≤ twice the retrofit cost) is a £ comparison, so it can only bite once a Property Valuation supplies the £ form; the bare percentages are uncapped. - The model is a pure function of the before/after **EPC Band** — it does **not** use the continuous SAP score, so it needs no precision work beyond the band the Plan already computes. ## Deferred (not in this phase) - **Property Valuation sourcing** — the upload-CSV ingestion slice, the Property field + persisted column, and the decision to retire or keep the demo `UPRN_VALUE_LOOKUP` stub. Where it persists (Baseline/performance table vs. a separate valuation table) is open. - **Per-measure `property_valuation_increase`** and **`rental_yield_increase`** — the legacy path never populated either; uplift is a plan-level figure for now.