mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Slice 37's per-cert pin refactor pinned PE residuals against `result.primary_energy_kwh_per_m2` from the rating cascade (UK-avg climate). But per SAP10.2 Appendix U + the codebase's own SAP_CALCULATOR.md docs, the EPC's published `energy_consumption_current` is a postcode-climate value — same as CO2. The CO2 pin was already correct; PE was an oversight. Fix: use the public `calculate_sap_from_inputs` entry point twice — once with `cert_to_inputs` (rating cascade) for SAP, once with `cert_to_demand_inputs` (demand cascade) for PE + CO2. This drops the four section-helper imports and reads everything off SapResult, keeping the test surface minimal. PE residuals shift on every fixture (sometimes toward zero, sometimes away — the rating cascade was masking the real gap): cert old PE new PE Δ 0240-0200-5706-2365-8010 +0.74 +5.58 worse — known RR gap 0300-2747-7640-2526-2135 +17.34 +4.45 tighter 0390-2254-6420-2126-5561 (LN12) -3.14 +0.18 tighter ← bread-and-butter cert now within 0.2 kWh/m² 0390-2954-3640-2196-4175 -27.64 -26.68 ~same 2130-1033-4050-5007-8395 (DE22) -61.25 -65.89 worse — PV PE-offset now correctly accounted 6035-7729-2309-0879-2296 +34.62 +45.05 worse — known wall-insulation + RR gap 7536-3827-0600-0600-0276 -27.45 -17.98 tighter 8135-1728-8500-0511-3296 -14.37 -9.50 tighter The "worse" certs (0240, 6035, DE22) were never close — the rating cascade had been coincidentally masking the real PE gap on the certs with documented mapper gaps. Demand cascade now exposes the real residual for each; the documented gaps' fixes will close them. LN12 (bread-and-butter, gas combi, no PV) now reads: SAP resid +0 (exact match) PE resid +0.18 (within 0.2 kWh/m² of lodged 241) CO2 resid +0.04 (within 0.05 t/yr of lodged 3.5) First cert in the cohort within target ±0.5 on SAP and ±1 on PE/CO2. 930/930 Elmhurst cascade unchanged. 14/14 golden cohort + PCDB chain green. Pyright net-zero (2 errors before and after). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| domain | ||
| fetchers | ||
| repos | ||
| utils | ||
| README.md | ||
Shared packages
Workspace packages consumed by services/*. Each package is its own Python distribution with its own pyproject.toml; services import via the workspace dependency mechanism ({ workspace = true }).
| Package | Purpose |
|---|---|
domain/ |
Shared domain types — Property, BaselinePerformance, Plan, Scenario, EpcPropertyData, etc. No persistence, no IO, no business logic. |
repos/ |
Persistence layer — one repo per aggregate. Owns the SQL. Depends on domain. |
fetchers/ |
External API clients (gov EPC, Ofgem, Google Solar, etc.). Depend on domain for response shapes. |
utils/ |
Cross-cutting infra — logging, S3, CloudWatch URL builders, SQS task helpers. |
Adding a new shared package
Only when a real second consumer materialises. Don't pre-shatter (repos-epc, repos-property, ...) — split when a deployment needs to drop a dep, not before.
See ../ara_backend_design.md §11 for the broader monorepo layout and ../CONTEXT.md for the domain glossary that names the types living in domain/.