mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
docs: handover for closing golden cert 0240 to 1e-4
Records why case 6 (worksheet-validated dual-oil archetype) did not close 0240's residual: 0240 is API-only with an INTEGER-rounded register target (PE 122, CO2 6.0), so 0 residual at 1e-4 is not well-posed without a worksheet. 0240's unvalidated path vs case 6 is the condensing-combi (code 130) + no-cylinder HW (Table 3a keep-hot 600 kWh) — case 6 used a regular boiler + cylinder. Recommends generating an exact-0240 worksheet (or a 'case 7' = case 6 with the combi swapped in) to get a 1e-4 target. Notes the lodged RHI water_heating 2842.82 already matches the cascade HW output exactly (HW demand is right; any residual is in efficiency). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
7344f600e6
commit
d4817ccdc7
1 changed files with 129 additions and 0 deletions
129
domain/sap10_calculator/docs/HANDOVER_0240_CLOSURE.md
Normal file
129
domain/sap10_calculator/docs/HANDOVER_0240_CLOSURE.md
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
# Handover — closing golden cert 0240-0200-5706-2365-8010 to 1e-4
|
||||
|
||||
Point-in-time note. Start from [`AGENT_GUIDE.md`](AGENT_GUIDE.md) for methodology,
|
||||
accuracy bar, and pipeline. This records the state of cert **0240** and the
|
||||
concrete path to driving its residual to zero.
|
||||
|
||||
- **Branch:** `feature/per-cert-mapper-validation`
|
||||
- **HEAD:** `7344f600` (S0380.207). Confirm with `git rev-parse HEAD`.
|
||||
- **Baseline:** `2372 passed, 1 skipped, 0 failed` (AGENT_GUIDE §4 suite command).
|
||||
|
||||
---
|
||||
|
||||
## What the last session shipped (S0380.201–207)
|
||||
|
||||
Closed **simulated case 6** (`001431_case6`) to 1e-4 on the full SapResult and
|
||||
promoted it to an e2e fixture. It is the worksheet-backed proxy for 0240's
|
||||
**dual-oil, different-parts** archetype (Main 1 rads/2106 + Main 2 UFH/2110,
|
||||
51/49, 6 "Roof of Room" rooflights, no boiler interlock). Slices:
|
||||
|
||||
| slice | spec | what |
|
||||
|---|---|---|
|
||||
| S0380.201 | Table 4f note c) | 2nd-main circulation pump → (231) |
|
||||
| S0380.202 | Table 5a note a) | 2nd-main pump **gain** → (70) |
|
||||
| S0380.203 | RdSAP §3.7 | "Roof of Room" rooflights deduct from the §3.10.1 RR residual → (30) |
|
||||
| S0380.204 | extractor/mapper | capture Main 2's §14.1 emitter + control |
|
||||
| S0380.205 | SAP 10.2 **p.186** | two-systems-different-parts MIT: weighted R + elsewhere two-control blend → (87)/(90)/(98c) |
|
||||
| S0380.206 | Appendix D Eq D1 | Q_space = DHW boiler's own (204) share, not (202) → (219) |
|
||||
| S0380.207 | test | promote case 6 to a full e2e fixture |
|
||||
|
||||
**0240 was re-pinned at each step** (it shares the archetype) and its residual
|
||||
improved on PE/CO2 but its SAP integer dropped 73→72. The boiler-interlock −5pp
|
||||
the *previous* handover called the priority was already implemented — see
|
||||
[[project_case6_interlock_already_done]].
|
||||
|
||||
---
|
||||
|
||||
## The 0240 problem — and why case 6 did NOT close it
|
||||
|
||||
### ⚠️ Critical: 0240 is API-only and its register target is INTEGER-rounded
|
||||
|
||||
0240 has **no worksheet**. The golden test pins the cascade against the lodged
|
||||
EPC register:
|
||||
- `energy_consumption_current = 122` — **an integer** (1 kWh/m² resolution).
|
||||
- `co2_emissions_current = 6.0` — **1 d.p.** (tonnes).
|
||||
- `current_energy_efficiency = None` — the SAP isn't even in the JSON
|
||||
(`actual_sap=73` in the test was carried from the original lodgement).
|
||||
|
||||
**You cannot drive 0240 to "0 residual" at 1e-4 against these.** The register
|
||||
rounds PE to the nearest whole kWh/m², so any cascade value in `[121.5, 122.5)`
|
||||
*is* 122, and the true (unrounded) Elmhurst value could sit anywhere in that band
|
||||
— or itself carry residual vs the rounded lodgement. Matching a rounded integer
|
||||
to 1e-4 is not a well-posed target. **The only 1e-4 ground truth is a worksheet**
|
||||
(the per-line `(1)..(286)` Elmhurst output), which is exactly why case 5/6 were
|
||||
generated.
|
||||
|
||||
Current 0240 cascade vs lodged: **PE 123.8687 vs 122 (resid +1.8687)**, **CO2
|
||||
6.0907 vs 6.0 (+0.0907)**, SAP cont 72.39 (integer 72 vs lodged 73, resid −1).
|
||||
|
||||
### Why case 6 didn't close 0240
|
||||
|
||||
Case 6 validated the dual-main **structure** (MIT p.186, pumps, rooflights,
|
||||
Eq-D1 fraction). But 0240 differs in cert-specific features case 6 does **not**
|
||||
exercise:
|
||||
|
||||
| feature | case 6 (worksheet-validated) | **0240** (unvalidated) |
|
||||
|---|---|---|
|
||||
| SAP code | 127 regular oil boiler | **130 condensing oil combi** (Table 4b 82/73) |
|
||||
| DHW path | regular boiler **+ 110 L cylinder** → primary/storage loss | **combi, NO cylinder** → Table 3a keep-hot **600 kWh** (`combi_loss`), primary_loss 0 |
|
||||
| TFA | (case-6 dwelling) | **201.53 m²** (different fabric/dimensions) |
|
||||
| PV | none | **none** (the golden note's "+ PV" is STALE — `solar_water_heating=N`, no PV field) |
|
||||
|
||||
So 0240's *remaining* residual lives in the parts case 6 never touched —
|
||||
**the condensing-combi (130) + no-cylinder HW path** and the cert's own fabric.
|
||||
The combi Eq-D1 / Table 3a keep-hot path has never been pinned against a
|
||||
worksheet in the dual-main context.
|
||||
|
||||
### Partial ground truth already in the 0240 JSON
|
||||
|
||||
The lodged `renewable_heat_incentive` block gives two deemed-demand figures:
|
||||
- `water_heating = 2842.82` — **exactly equals** the cascade's §4 HW output
|
||||
`(64)` (2842.82). So the **HW demand is right**; any HW residual is in the
|
||||
*efficiency* (Eq D1 combi blend), not the demand.
|
||||
- `space_heating_existing_dwelling = 13254.52` vs cascade `(98c)` 12760.9 —
|
||||
differ ~494 kWh (~3.7%). RHI uses its own deemed methodology so this is **not**
|
||||
a clean 1e-4 check, but it's a hint the space-heat demand or the combi figures
|
||||
are worth scrutinising.
|
||||
|
||||
---
|
||||
|
||||
## What to do next — generate the right example
|
||||
|
||||
To close 0240 properly you need a **worksheet** that exercises its
|
||||
combi-HW path. Two options, best first:
|
||||
|
||||
1. **Exact 0240 replica worksheet (gold standard).** Re-enter 0240's lodged data
|
||||
into Elmhurst and export the worksheet PDF. Then build a mapper-driven fixture
|
||||
(mirror `_elmhurst_worksheet_001431_case6.py`) and pin every line `(1)..(286)`
|
||||
at 1e-4. The first diverging line localises the residual exactly. This is the
|
||||
only way to get a true 1e-4 target for 0240.
|
||||
|
||||
2. **"Case 7" — case 6 with 0240's combi swapped in.** If generating an exact
|
||||
0240 replica is hard, generate a `001431` variant that changes case 6's
|
||||
heating to **0240's**:
|
||||
- **Condensing oil combi, SAP code 130** (not 127 regular boiler).
|
||||
- **NO hot water cylinder** — combi instantaneous DHW → WHC 901, Table 3a/3b
|
||||
combi keep-hot loss, no primary/storage loss.
|
||||
- Keep the validated dual-main rads(2106)+UFH(2110) 51/49 + RR rooflights.
|
||||
This pins the **combi Eq-D1 + Table 3 keep-hot** path (the biggest unvalidated
|
||||
piece) against a worksheet. Whatever it reveals applies directly to 0240.
|
||||
|
||||
**The single most important differentiator to change vs case 6: regular
|
||||
boiler + cylinder → condensing combi (130) with no cylinder.** That is the one
|
||||
HW path 0240 uses that has never seen a worksheet in this archetype.
|
||||
|
||||
### Reframing the goal
|
||||
If a worksheet is genuinely unavailable, "0 residual vs the lodged register" is
|
||||
not achievable at 1e-4 (integer rounding). The realistic target then is the
|
||||
**±0.5 SAP fallback** (AGENT_GUIDE §1) — and 0240's continuous SAP 72.39 vs
|
||||
lodged 73 is ~0.6 off, just outside it. Closing that last 0.6 still requires
|
||||
knowing the true (worksheet) value, so the worksheet is the unblocker either way.
|
||||
|
||||
---
|
||||
|
||||
## Pointers
|
||||
- Golden pin + full slice history: `tests/domain/sap10_calculator/rdsap/test_golden_fixtures.py` (cert `0240-0200-5706-2365-8010`, line ~83).
|
||||
- Case-6 fixture to mirror: `tests/domain/sap10_calculator/worksheet/_elmhurst_worksheet_001431_case6.py` + its e2e pins in `test_e2e_elmhurst_sap_score.py::_FIXTURE_PINS["001431_case6"]`.
|
||||
- Memories: [[project_case6_mit_two_system_rootcause]] (the p.186 MIT, now CLOSED), [[project_case6_interlock_already_done]], [[feedback-worksheet-not-api-reference]] (API matches the worksheet, not the lodged register), [[feedback-software-no-special-handling]].
|
||||
- Repro 0240: `EpcPropertyDataMapper.from_api_response(json.load(...0240.json))` → `cert_to_inputs` / `cert_to_demand_inputs` → `calculate_sap_from_inputs`. The §2.4 section helpers are UNFAITHFUL (skip the interlock penalty + two-system MIT params) — diagnose against the real `cert_to_inputs` cascade.
|
||||
- Process: one slice = one commit, spec citation (page+line), `Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>`. SAP 10.2 only. No tolerance widening. mapper.py + cert_to_inputs.py each carry 32 pre-existing pyright errors (baseline-compare with `git stash`).
|
||||
Loading…
Add table
Reference in a new issue