§3 close (LINE_31/33/36/37 exact for both non-RR Elmhurst worksheets) is
now landed across slices 344a9c9d..cf244762. HANDOVER_S3_CLOSE.md was
written as a mid-stream working brief; with §3 done it now creates doc
rot, so it's removed in favour of SPEC_COVERAGE.md as the single source
of truth.
SPEC_COVERAGE.md updates:
- §3 marked Full (non-RR); RR sub-area deferral noted
- §4 carries the ordered slice plan for the worksheet-driven rewrite
(xlsx rows 207–304, line refs (42)..(65))
- Hierarchy callout: the canonical SAP10.2 algorithm lives in the
repo-root xlsx, not in any handover doc
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.8 KiB
SAP 10.2 / RdSAP 10 Coverage Map
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).
The canonical SAP10.2 algorithm lives in 2026-05-19-17-18 RdSap10Worksheet.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.
Sections §§1–13 (the SAP worksheet)
| § | xlsx rows | Topic | Module | Status | Notes / gaps |
|---|---|---|---|---|---|
| 1 | 1–120 (approx) | Dimensions | worksheet/dimensions.py |
Full | Porches, conservatories, RIR deferred per ADR-0009 |
| 2 | 121–206 (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 | 121–207 | 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 | 207–304 | 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 |
| 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 | |
| 8 | Off-period temperature reduction | inline in mean_internal_temperature.py |
Full | Table 9b implemented | |
| 9 | Space heating | worksheet/space_heating.py |
Partial | Single main system only — no Table 11 secondary heating allocation (10% fraction on most boilers — likely big MAE) | |
| 10 | Cooling | — | Not implemented | Rare in UK dwellings; defer | |
| 11 | FEE | — | Not implemented | Only for new-build; not required for ratings | |
| 12 | Total energy + fuel costs | calculator.py |
Partial | Per-end-use cost split ✓; meter_type tariff routing ✓ (S-B15); PV cost credit ✓ (S-B19); standing charges not included (Table 12 note (a) says rating omits standing charge for std electricity tariff) | |
| 13 | SAP rating | worksheet/rating.py |
Full | Equations 7-9 verified against SAP 10.2 §13 | |
| 14 | CO2 + primary energy | calculator.py SapResult.co2_kg_per_yr |
Partial | Single CO2 factor on main fuel; no per-end-use CO2 mixing; no primary energy calculation | |
| 15 | Building regs | n/a | n/a | Not relevant to ratings |
Appendices
| Appendix | Topic | Status | Notes |
|---|---|---|---|
| A | Main + secondary heating identification | Not implemented | First main only; Table 11 secondary fraction missing — high-value gap |
| B | Gas/oil boilers + boiler interlock | Partial | Via Table 4b in domain.ml.sap_efficiencies.seasonal_efficiency |
| C | Community heating | Not implemented | Heat network certs handled by Table 4a codes 301-304 (efficiency only) |
| D | PCDB | Stubbed | Per ADR-0009 grill: NoOpPcdbLookup returning None; Session C bundles a CSV PCDB extract |
| E | Heat pumps | Partial | Category fallback to 2.30 for cat=4; no MCS installation factor (×1.39 GSHP); no flow temp adjustment |
| F | Electric CPSU | Not implemented | Rare |
| G | FGHRS / WWHRS / PV-diverter | Not implemented | Rare |
| H | Solar water heating | Partial | Boolean has_solar_water_heating reduces HW by 250 kWh; no actual collector calc |
| J | Hot water demand | Partial | See §4 row above |
| K | Thermal bridging | Partial | Using global y per age band (per ADR-0009 grill: per-junction Table R2 deferred) |
| L | Lighting | Full | Existing-dwelling fallback ✓ |
| M | PV / wind / hydro generation | Partial | PV ✓ (S-B19); wind / hydro / micro-CHP not implemented |
| N | Micro-CHP | Not implemented | Rare |
| P | Electric storage heaters detail | Partial | Identified via codes 401-409; Table 12a high-rate fractions not exact (we use 100% off-peak per cert-calibration heuristic) |
| Q | Special features | Not implemented | One-off energy-use additions; rare |
| R | Reference dwelling | Not implemented | Only needed for compliance, not ratings |
| S | RdSAP procedures | Separate PDF (114pp) | Cert→inputs mapper in domain.sap.rdsap.cert_to_inputs ports key rules; many sections of RdSAP 10 not yet read |
| T | Improvement measures | Not relevant | Recommendation engine, not rating |
| U | Climate data | Full | Tables U1/U2/U3 + solar declination + Table U5 k1-k9 |
Prioritised gap list (by likely MAE impact)
- Table 11 Secondary heating allocation — most boiler-main certs allocate 10% of space heating to a secondary system (often a less-efficient room heater on a different fuel). We model 0%. Likely +1-2 SAP-point bias on affected certs.
- Wind-shelter factor on infiltration (§2 worksheet lines 19-21) — multiplies infiltration by
1 - 0.075 × sheltered_sides. We have no shelter input; assume 2 sheltered sides default. Net effect on infiltration ACH probably ~10%. - Table 12a high-rate fraction for off-peak dwellings — we currently bill 100% of E7 space heating at the low rate. Real spec says e.g. heat pumps on 7h tariff at 80% high-rate. Affects ~5% of certs.
- Cylinder-loss factor cascade — currently uses simplified buckets in
domain.ml.demand._STORAGE_LOSS_FACTOR. Spec has more precise interpolation rules from cylinder volume + insulation thickness. - Standing charges in cost — Table 12 note (a) gives the rule for when standing charges are included (energy use vs rating). May affect bias.
- Per-junction thermal bridging (Table R2) — only relevant when assessor lodged junction-count data, otherwise global y is the spec answer for RdSAP-driven assessments.
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 207–304)
Line refs to implement in order (one TDD slice each):
| 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 | 238–263 |
| (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 | — |