docs: §5 close — SPEC_COVERAGE flip from "Full" stub to actual full

The pre-§5-rebuild SPEC_COVERAGE row optimistically marked §5 as Full
when only 4 of 8 worksheet lines were implemented and the lighting path
used the L5b/L8c fallback (≈22 W/month bias for typical cert lodgings).

Updates the §5 row with the actual coverage post-rebuild:
worksheet-driven (66)..(73), Table 5 Column A throughout, Table 5a
9-row dispatch with heating-season mask, Appendix L L1-L12 lighting
including RdSAP §12-1 per-lamp-type defaults + Table 6d Z_L light
access factor, and orchestrator wired into cert_to_inputs + calculator.

Adds a §5 slice progress table mirroring §4's format, with the
12-slice commit chain and the remaining work (rooflight Z_L=1.0,
cert-driven fan/PIV/HIU dispatch, frame/glazing string parsing, Column
B reduced-gain forms for new-build).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-05-20 19:15:43 +00:00
parent bf6a7e04b3
commit 2d4fa24de9

View file

@ -2,7 +2,7 @@
Tracks which sections of the SAP 10.2 specification are implemented in `packages/domain/src/domain/sap/`. Per ADR-0009 the calculator is built from the spec, not reverse-engineered from cert data. This doc is the worksheet-driven roadmap for what remains.
Updated 2026-05-20 after §3 close (slices `344a9c9d``cf244762`).
Updated 2026-05-20 after §5 rebuild (slices `3ec56216``bf6a7e04`).
The canonical SAP10.2 algorithm lives in [`2026-05-19-17-18 RdSap10Worksheet.xlsx`](../../2026-05-19-17-18%20RdSap10Worksheet.xlsx) at the repo root — each line ref `(1)..(486)` maps to a cell. The worksheet sub-modules under `packages/domain/src/domain/sap/worksheet/` implement those line refs directly; Elmhurst worksheets validate end-to-end via `tests/_elmhurst_worksheet_*.py`.
@ -14,7 +14,7 @@ The canonical SAP10.2 algorithm lives in [`2026-05-19-17-18 RdSap10Worksheet.xls
| 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 | `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 |
| 5 | Internal gains + Appendix L | `worksheet/internal_gains.py` | **Full** | Worksheet-driven (66)..(73), Table 5 Column A, Table 5a 9-row dispatch + heating-season mask, Appendix L L1-L12 with RdSAP §12-1 bulb defaults + Table 6d Z_L (light access factor). Wired into `calculator.py` via `cert_to_inputs`. Six Elmhurst fixtures conform end-to-end to ≤0.6% lighting / ≤0.2 W (73). |
| 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 |
| 8 | Off-period temperature reduction | inline in `mean_internal_temperature.py` | Full | Table 9b implemented |
@ -92,3 +92,28 @@ Status now: 100-cert MAE 4.49, 300-cert MAE 5.45, bias near zero (±0.2). Worksh
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).
## §5 — slice progress (xlsx rows 305332)
| Line ref | Description | Status | Commit |
|---|---|---|---|
| (66)m | Metabolic = 60 × N (Table 5 Col A) | ✅ | `3ec56216` |
| (71)m | Losses = -40 × N | ✅ | `021f43ba` |
| (69)m | Cooking = 35 + 7 × N | ✅ | `984a5b18` |
| (72)m | Water heating bridge (65)m × 1000/(24 × n_m) | ✅ | `a4d6321f` |
| (68)m | Appliances (L13/L14/L16a) | ✅ | `0bc9eac3` |
| (67)m | Lighting (L1-L12 with Z_L from Table 6d) | ✅ | `50fd940a` |
| (70)m | Pumps + fans (Table 5a 9-row dispatch) | ✅ | `f77229e4` |
| (73)m | Total internal gains + InternalGainsResult | ✅ | `53aba133` |
| — | `internal_gains_from_cert` orchestrator | ✅ | `f81e744b` |
| — | 6-fixture ALL_FIXTURES conformance | ✅ | `99e5c2cd` |
| — | `cert_to_inputs` wiring + calculator.py wiring | ✅ | `bf6a7e04` |
**Six Elmhurst fixtures conform end-to-end on §5 to ≤0.2 W on (73)** with the only meaningful residual on (67) (~0.2 W lighting bias from rooflight Z_L=1.0 being approximated as AVERAGE Z_L=0.83 — Table 6d note 2).
### Remaining §5 work
1. **Rooflight Z_L=1.0** per Table 6d note 2 (currently a single AVERAGE Z_L applies to all windows including rooflights).
2. **Table 5a fan / PIV / HIU branches** are implemented as leaf functions but not yet derived from cert inputs in `internal_gains_from_cert`. Pump dispatch is wired; non-pump rows always emit 0 W. MVHR / MEV correctly produces zero gain.
3. **Per-window `frame_material` / `glazing_type` strings** — current orchestrator uses cert numeric codes; needs a robust mapping for site-notes-sourced certs.
4. **Column B reduced-gain forms** (L12a / L16) for new-build DPER/TPER calculations — deferred until we onboard a new-build cert.