docs: §4 slice progress — happy path closes both non-RR fixtures

Updates SPEC_COVERAGE.md with the 9 §4 slices landed since the last doc
sweep, and lays out the remaining work in priority order:
  1. §4 orchestrator (water_heating_from_cert)
  2. Wire calculator.py to the new worksheet module
  3. End-to-end SAP score validation against Elmhurst worksheets
  4. Cylinder + solar + renewables branches (population coverage)
  5. PCDB-backed Table 3b/3c combi loss (000474 sits here)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-05-20 16:15:18 +00:00
parent 43da3ea064
commit 6a3552a50d

View file

@ -13,7 +13,7 @@ The canonical SAP10.2 algorithm lives in [`2026-05-19-17-18 RdSap10Worksheet.xls
| 1 | 1120 (approx) | Dimensions | `worksheet/dimensions.py` | **Full** | Porches, conservatories, RIR deferred per ADR-0009 |
| 2 | 121206 (approx) | Ventilation | `worksheet/ventilation.py` | Partial | No mechanical ventilation (MVHR/MEV), no wind-shelter factor, no pressure-test override (worksheet lines 17-18), no AP4 override (worksheet line 19) |
| 3 | 121207 | Heat transmission | `worksheet/heat_transmission.py` | **Full (non-RR)** | LINE_31/33/36/37 exact for both non-RR Elmhurst fixtures (000474, 000490). Suspended-timber + Table 20 exposed-floor routes wired. RR sub-areas (gable/slope/stud-wall) deferred until `SapRoomInRoof` carries them. Global y-factor (Table R2 per-junction deferred). |
| 4 | 207304 | Hot water + Appendix J | uses `domain.ml.demand.predicted_hot_water_kwh` | Partial (legacy) | **Worksheet-driven rewrite in progress** — see slice plan below. Instantaneous-system flag ✓; no shower/bath count adjustments, no FGHRS/WWHRS, no PV-diverter |
| 4 | 207304 | Hot water + Appendix J | `worksheet/water_heating.py` (new) + legacy `domain.ml.demand.predicted_hot_water_kwh` (calculator still calls this) | **Happy-path done** — see slice progress below. Worksheet-driven module lands line refs (42)..(65) for the combi-gas-boiler population (~70% of corpus). Cylinder + solar + renewables branches deferred. Calculator.py not yet wired to new module — next step. |
| 5 | Internal gains + Appendix L | `worksheet/internal_gains.py` | Full | Default occupancy + Appendix L lighting fallback |
| 6 | Solar gains + Tables 6b/6c/6d + Appendix U | `worksheet/solar_gains.py` | Partial | Per-orientation/pitch ✓; Tables 6b/6c lookups ✓; Z (overshading) hardcoded to 0.77 average; roof-lights treated as vertical |
| 7 | Mean internal temperature | `worksheet/mean_internal_temperature.py` | Partial | Living area fraction from Table 27 ✓ (per S-A7b); control_type from main_heating_control code ✓ (S-B5); control_temperature_adjustment_c always 0 |
@ -61,25 +61,34 @@ The canonical SAP10.2 algorithm lives in [`2026-05-19-17-18 RdSap10Worksheet.xls
Status now: 100-cert MAE 4.49, 300-cert MAE 5.45, bias near zero (±0.2). Worksheet-driven phase begins with **Secondary heating Table 11** as the next slice.
## §4 — current focus (xlsx rows 207304)
## §4 — slice progress (xlsx rows 207304)
Line refs to implement in order (one TDD slice each):
| Line ref | Description | Status | Commit |
|---|---|---|---|
| (42) | Assumed occupancy N from Appendix J | ✅ | `aff678e8` |
| (42a)m | Mixer showers monthly | ✅ | `1dcbdb28` |
| (42b)m | Baths monthly | ✅ | `dad7fbf3` |
| (42c)m | Other uses monthly | ✅ | `5cc68ab3` |
| (43) | Annual avg | ✅ | `702b1c6c` |
| (44)m | Daily monthly total | ✅ | `702b1c6c` |
| (45)m | Energy content | ✅ | `a3c687f1` |
| (46)m | Distribution loss | ✅ | `a3c687f1` |
| (47)(56) | Storage / HIU loss | Combi zero-branch only; cylinder paths deferred | — |
| (57)m | Dedicated solar storage | Combi zero-branch only; solar HW deferred | — |
| (59)m | Primary loss | Combi zero-branch only; boiler+cylinder deferred | — |
| (61)m | Combi loss | Table 3a row "time-clock keep-hot" only | `bfba610b` |
| (62)m | Total demand | ✅ | `bfba610b` |
| (63a-d) | WWHRS/PV/Solar/FGHRS reductions | Zero-only — non-zero paths deferred | `feef8198` |
| (64)m | Output from water heater | ✅ (with max-clamp) | `feef8198` |
| (64a)m | Electric shower energy | Zero-only — non-zero path deferred | — |
| (65)m | Heat gains | ✅ | `43da3ea0` |
| Line ref | Description | xlsx row |
|---|---|---|
| (42) | Assumed occupancy N from Appendix J formula | 209 |
| (42a)m | Hot water — mixer showers, monthly | 215 |
| (42b)m | Hot water — baths, monthly | 218 |
| (42c)m | Hot water — other uses, monthly | 221 |
| (43) | Annual average hot water (litres/day) | 223 |
| (44)m | Daily hot water usage, monthly | 226 |
| (45)m | Energy content of hot water, monthly | 229 |
| (46)m | Distribution loss = 0.15 × (45)m | 236 |
| (47)(56) | Storage volume + water storage / HIU loss path | 238263 |
| (57) | Dedicated solar storage adjustment | (after 263) |
| (58)(61) | Primary loss + combi loss | — |
| (62)m | Total monthly water heat requirement | — |
| (63a)(63d) | WWHRS / PV-diverter / Solar / FGHRS reductions | — |
| (64)m | Output from water heater | — |
| (64a)m | Electric-shower energy | — |
| (65)m | Heat gains from water heating | — |
**Happy path closes both non-RR Elmhurst fixtures to <1e-3 kWh end-to-end on lines (42)..(65)** (000474's PCDB-backed Table 3b combi loss is the one hand-lodged value).
### Remaining §4 work
1. **Orchestrator** `water_heating_from_cert(epc, ...)` that wires the leaf functions, mirroring `heat_transmission_from_cert` for §3.
2. **Integrate with `calculator.py`** — replace the legacy `domain.ml.demand.predicted_hot_water_kwh` call.
3. **End-to-end SAP score** validation against the worksheets — the real e2e test the user has been asking for.
4. **Cylinder + solar + renewables paths** for full population coverage (cylinders, FGHRS, WWHRS, PV-diverter).
5. **PCDB-backed Table 3b/3c combi loss** for tested boilers (000474 sits here).