Model/docs/sap-spec/SPEC_COVERAGE.md
Khalim Conn-Kowlessar d90827446a docs: sweep stale handover, mark §3 Full, scaffold §4 slice plan
§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>
2026-05-20 15:18:46 +00:00

7.8 KiB
Raw Blame History

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 344a9c9dcf244762).

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 §§113 (the SAP worksheet)

§ xlsx rows Topic Module Status Notes / gaps
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
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)

  1. 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.
  2. 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%.
  3. 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.
  4. 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.
  5. Standing charges in cost — Table 12 note (a) gives the rule for when standing charges are included (energy use vs rating). May affect bias.
  6. 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 207304)

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 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