Model/domain/sap10_calculator/docs/HANDOVER_POST_S0380_143.md
Khalim Conn-Kowlessar 53ceb63624 docs: handover post S0380.141..143 (pcdb 1 closure via §9.4.11 + §4 cylinder gates + RdSAP 10 Table 29 inaccessible-cylinder insulation defaults)
Three slices on top of `8ee877e4` closed cert pcdb 1 from SAP +6.95
to +0.57 (-92% magnitude) via spec-citable fixes in three distinct
cascade areas.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 21:06:11 +00:00

9.2 KiB
Raw Blame History

Handover — post Slices S0380.141..143

Branch: feature/per-cert-mapper-validation. HEAD eda6f449. Predecessor: HANDOVER_POST_S0380_140.md.

TL;DR

Three slices landed on top of 8ee877e4 this session, all concentrated on the §4 / §9.4.11 cascade for PCDB regular oil boilers feeding a cylinder (cert pcdb 1 in the heating-systems corpus). Each slice surfaced 1-2 spec-citable bugs hidden behind silent fallbacks; together they closed pcdb 1 from SAP +6.95 to +0.57 (-92% magnitude).

Slice Commit Scope
S0380.141 6636f1c3 SAP 10.2 §9.4.11 (PDF p.30) "Boiler interlock": -5pp adjustment now applies to BOTH space-heating efficiency and the PCDB Equation D1 monthly water cascade (previously only the water_eff scalar fallback got the adjustment). SH path further gated on pcdb_main is not None so cert 000565 (ASHP Main 1) is unaffected.
S0380.142 7f9074fc SAP 10.2 §4 line 7702 + Table 3 cylinder-presence gates: (a) combi loss = 0 whenever epc.has_hot_water_cylinder is True (combi boilers are by definition instantaneous per Table 3 zero-loss list); (b) _primary_loss_applies returns True when main_heating_index_number resolves to a PCDB Table 322 (gas/oil boiler) record. Golden cert 0390-2954-3640-2196-4175 re-pinned (PE -26.37 → -28.50, CO2 -2.55 → -2.75) because primary-loss gain (~5-10 kWh) < combi-loss removal (-600 kWh).
S0380.143 eda6f449 RdSAP 10 §10.11 Table 29 (PDF p.56) "Hot water cylinder insulation if not accessible" — new _resolve_elmhurst_inaccessible_cylinder_insulation(age_band) helper deriving (insulation_type, thickness_mm) from construction age band when §15.1 lodges "Cylinder Size: No Access". Age G/H → 25 mm foam (code 1); I-M → 38 mm foam (code 1); A-F raises UnmappedElmhurstLabel (loose-jacket SAP10 enum not yet exercised).

Extended handover suite at HEAD: 886 pass, 0 fail.

Current residual state at HEAD eda6f449

Cascade-OK tier (25 variants on pin grid)

Variant ΔSAP_c Δcost ΔPE Notes
ashp +0.24 -£5.57 -12 closed
electric 1 -0.06 +£1.32 +94
electric 2 +0.47 -£10.92 +101 warm-air ASHP
electric 3 +2.55 -£58.65 -1122 open
electric 5 +0.07 -£1.72 -161
electric 6 +1.33 -£30.60 -563 open
electric 7 +1.29 -£29.73 -498 open
electric 8 -0.26 +£5.92 +126
electric 9 -0.12 +£2.72 +91
gshp +1.15 -£26.48 -455
oil 1 +2.66 -£61.24 -1050 open
oil pcdb 1/2 +0.42 -£9.77 -84 closed
oil pcdb 3 +1.16 -£26.72 -271
pcdb 1 +0.57 -£12.55 -109 closed via S0380.141..143 (was +6.95 / -£157.61 / -3135 PE)
solid fuel 2 +2.64 -£60.79 -1211 PE outlier
solid fuel 3 +1.32 -£30.45 -935 PE outlier
solid fuel 4-11 (×8) -0.29..+0.10 small ±170

Blocked tier (16 variants)

Unchanged from previous handover — community heating × 5, electric storage 11/12/13/14, no system, oil 2-6, pcdb 3.

Next-slice candidates ranked by leverage

1. electric 3 / 6 / 7 SAP +1.3..+2.5 (cluster of 3) — open

Surfaced by S0380.139. Cascade _secondary_heating_fraction_for_ category defaults to 0.10 when mapper leaves main_heating_category=None; worksheet for SAP code 401/402 uses 0.15 (Table 11 Cat 7 "electric storage"). Mapper-side fix: derive main_heating_category from SAP code when not lodged. Side issue: code 408 (HHR storage) is in _FORCE_SECONDARY_FOR_MAIN_CODES but spec docstring says forced applies to "401 to 407, 409 and 421" only — 408 excluded.

The previous +2.5 SAP cluster (electric 3, oil 1, solid fuel 2) was diagnosed as HETEROGENEOUS during S0380.140 work. Electric 3's driver is §9 MIT for storage heaters; oil 1's is HW efficiency for non-PCDB Table 4b oil boilers; solid fuel 2's is HW lodging in a different line ref. The shared "+2.5 SAP" magnitude is coincidence, not signal. Per-variant slices still recommended.

2. oil 1 SAP +2.66 / cost -£61 / PE -1050 — open

Table 4b oil boiler (code 127, eff 84%) with cylinder lodged + Boiler Interlock: Yes (per cert). The -5pp interlock fix from S0380.141 does NOT apply (interlock is present). Cascade HW kWh 2785 vs worksheet 3639. Worksheet effective HW efficiency ≈ 65% suggests summer/winter blend the cascade may not be applying for non-PCDB oil boilers per SAP 10.2 Appendix D §D2.1.

3. solid fuel 2 / 3 PE -935..-1211 — open

Both anthracite (codes 158, 160). Same fuel + R as variants that closed. Distinct cause from #1 above. Per-variant probe required.

4. community heating unblocking (5 variants) — sizeable

Extend extractor to capture §14.1 Community Heating block (heat-network codes 41-58). Each cert maps to a Table 32 heat-network code via the lodged heat source type.

5. Electric storage unblocking (variants 11-14) — small

Extend _ELMHURST_MAIN_HEATING_EES_TO_FUEL_CODE for EES codes WEA, REA, OEA.

What's still open on pcdb 1 (~SAP +0.57)

The residual ~+0.57 SAP is primarily a ~1.3% cascade-side undercount on space-heating demand (cascade SH 7900 kWh vs worksheet (98c) 8004 kWh). This is a §8 driver — different MIT or gains calculation between cascade and worksheet. Falls within "spec-cascade floor" noise; not chasable without a clearer probe target.

Standard slice workflow

  1. Read spec page + identify rule
  2. Probe one cluster variant; verify diagnosis via monkey-patch
  3. Write failing AAA test (literal # Arrange / # Act / # Assert)
  4. Implement helper / dispatch entry / mapper extension
  5. Re-pin affected variants
  6. Run extended handover suite (command in previous handover)
  7. Pyright net-zero check (git stash → pyright → git stash pop → pyright)
  8. Commit with spec citation + Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
  9. Update project-heating-systems-corpus + MEMORY.md index

Test baseline at HEAD eda6f449

PYTHONPATH=/workspaces/model python -m pytest \
    backend/documents_parser/tests/test_summary_pdf_mapper_chain.py \
    backend/documents_parser/tests/test_heating_systems_corpus.py \
    backend/documents_parser/tests/test_elmhurst_extractor.py \
    backend/documents_parser/tests/test_elmhurst_end_to_end.py \
    domain/sap10_calculator/worksheet/tests/test_e2e_elmhurst_sap_score.py \
    domain/sap10_calculator/worksheet/tests/test_heat_transmission.py \
    domain/sap10_calculator/worksheet/tests/test_internal_gains.py \
    domain/sap10_calculator/worksheet/tests/test_solar_gains.py \
    domain/sap10_calculator/worksheet/tests/test_dimensions.py \
    domain/sap10_calculator/worksheet/tests/test_rating.py \
    domain/sap10_calculator/worksheet/tests/test_ventilation.py \
    domain/sap10_calculator/worksheet/tests/test_appendix_h_solar.py \
    domain/sap10_calculator/worksheet/tests/test_mev.py \
    domain/sap10_calculator/rdsap/tests/test_cert_to_inputs.py \
    domain/sap10_calculator/rdsap/tests/test_golden_fixtures.py \
    domain/sap10_calculator/tests/test_pcdb_table_322_lookup.py \
    domain/sap10_calculator/tests/test_pcdb_table_329_lookup.py \
    domain/sap10_calculator/tests/test_table_12a.py \
    --no-cov -q

Expected: 886 pass, 0 fail.

Memories to load (in order)

project-heating-systems-corpus    # HEAD eda6f449
feedback-sap-10-2-only-never-10-3 # CRITICAL — never reference SAP 10.3
feedback-worksheet-not-api-reference
feedback-spec-citation-in-commits
feedback-verify-handover-claims
feedback-zero-error-strict
feedback-commit-per-slice
feedback-aaa-test-convention
feedback-e2e-validation-philosophy
feedback-abs-diff-over-pytest-approx
feedback-spec-floor-skepticism
feedback-golden-residuals-near-zero
feedback-one-e-minus-4-across-the-board
reference-unmapped-sap-code
reference-unmapped-api-code
project-oil-price-spec-divergence

What NOT to do

  • Don't reference SAP 10.3 — track 10.2 deliberately
  • Don't widen pin tolerances to make pins pass — re-pin smaller or find the spec gap
  • Don't re-investigate Slices .91..143 — all settled
  • Don't add new helpers to domain/sap10_ml/ — on deprecation path

Spec source quick-reference

All under domain/sap10_calculator/docs/specs/:

  • SAP 10.2 full spec: sap-10-2-full-specification-2025-03-14.pdf
    • §4 (p.135-137) — water heating worksheet (45..65), Tables 2/2a/2b
    • §9 (p.155+) — MIT calc, Tables 9/9a/9b
    • §9.4.11 (p.30) — Boiler interlock: -5pp to BOTH SH and DHW
    • Table 3 (p.160) — Primary circuit loss; zero-loss list
    • Table 4a/4b/4c/4d — heating systems + responsiveness + interlock
    • Table 4f (p.174) — pumps + fans
    • Table 11 — secondary heating fraction by category
    • Table 12 (p.191) — SAP rating fuel prices
    • Table 12a (p.191) — high/low-rate fraction by system × tariff
  • RdSAP 10 spec: RdSAP 10 Specification 10-06-2025.pdf
    • §10.11 Table 29 (p.56) — Heating and hot water parameters; inaccessible cylinder defaults
    • §19 Table 32 (p.95) — RdSAP10 fuel prices / CO2 / PE

Good luck.