Model/domain/sap10_calculator/docs/HANDOVER_POST_S0380_189.md
Khalim Conn-Kowlessar e63d046b9d docs: handover post S0380.189 — TMP/Table 22 + the two open follow-ups
Point-in-time note for the next agent: what S0380.185-189 shipped (worksheet
PE/CO2 pins, the two D_PV electricity-vs-gain fixes, and the thermal-mass-
parameter Table 22 fix), the per-line diagnosis template, the two worksheet-
block / gains-vs-solar traps, and the ranked open slices (Summary-path fuel
derivation first, then pin the simulated 001431 case, then cert 6035).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 22:05:41 +00:00

6.4 KiB
Raw Permalink Blame History

Handover — post S0380.189 (thermal mass parameter / Table 22)

Point-in-time note. Start from AGENT_GUIDE.md for the methodology, accuracy bar, and pipeline — this doc only records what this session did and what is open.

  • Branch: feature/per-cert-mapper-validation
  • HEAD: e03f08cd (S0380.189)
  • Baseline: 2290 passed, 1 skipped, 0 failed (the skip is the gitignored xlsx load_cells test). Verify with the §4 suite command.

What this session shipped (S0380.185189)

Slice What Spec
.185 Recorded the CH6 "pin-forever" proof — distribution-loss is an Elmhurst Summary-export gap, not a mapper miss (controlled adjoining-dwellings pair byte-identical in inputs).
.186 Added test_golden_cert_pe_co2_matches_worksheet — pins calc PE/CO2 for the 47 worksheet-backed certs against the dr87 (286)/(272) at full precision (not lodged register values). Appendix U
.187 Appendix M1 §3a D_PV,m was missing electric secondary space heating (215)m — under-credited PV on gas-main+electric-secondary+PV certs. SAP 10.2 App M1 §3a
.188 D_PV,m used the Appendix L L12 lighting GAIN (= E_L×0.85) instead of the L10 lighting ELECTRICITY (232). Closed the whole PV cohort to 1e-4. Same gain-vs-electricity class as the S0380.73 cooking fix. SAP 10.2 App L L10/L12, M1 §3a
.189 Thermal mass parameter was hardcoded 250 at all 5 §7/§8 call sites. Now _thermal_mass_parameter_kj_per_m2_k(epc) per Table 22. RdSAP 10 §5.16 Table 22 (p.48)

After .186.188 all 47 worksheet-backed certs match calc≡worksheet at <1e-4 on PE and CO2 (the convergence target). See [project-golden-coverage-state memory] for the per-slice detail.


The S0380.189 diagnosis (template for the open work)

Driven entirely by the per-line walk (AGENT_GUIDE §3) against a user-simulated worksheet for a 6035-archetype property:

  • Fixture: sap worksheets/golden fixture debugging/simulated case 1/Summary_001431 (1).pdf (input) + P960-0001-001431 - ….pdf (worksheet ground truth). A gas-combi mid-terrace, TFA 128, solid brick with internal insulation, no PV/secondary/cylinder. (The P960-… prefix is just the Elmhurst account id; cert is 001431.) These PDFs are untracked — the user holds them locally.
  • Decompose: PE +8.78 / SAP 1.76 / CO2 +0.21, entirely space-heating demand (+838 kWh). Fabric (2637), internal gains (73), climate (96)m, HTC (39) all EXACT → localised to §7 MIT (92) +0.71 °C.
  • Root cause: TMP hardcoded 250; cert is masonry with internal insulation → RdSAP 10 §5.16 Table 22 = 100. Wrong TMP → time constant τ=Cm/(3.6·H) ≈40 h not 16 h → §7 temperature reduction too small → MIT too high → space heating over-stated.
  • Fix + blast radius: only golden cert 6035 re-pinned (SAP 6→2, PE +46.42→+19.16, CO2 +1.07→+0.42). All other fixtures are masonry-no-internal → TMP unchanged.

Two diagnostic traps that cost false starts (read before debugging §7/§8)

  1. The worksheet has TWO blocks per dwelling. The first is the SAP-rating block (UK-average climate, region 0); the second, under "CALCULATION OF EPC COSTS, EMISSIONS AND PRIMARY ENERGY", is the postcode block. The demand cascade (cert_to_demand_inputs) matches the POSTCODE block. Comparing calc HTC/MIT to the UK-avg block shows phantom gaps (e.g. HTC "10.8"); against the postcode block HTC is exact.
  2. (84) Total gains = internal (73) + solar (83). The calc's internal_gains_annual_avg_w is (73) only — don't diff it against (84) (a phantom "248 W" gap that is just solar).

Use the §2.4 section helpers (mean_internal_temperature_section_from_cert, space_heating_section_from_cert, internal_gains_section_from_cert, local_climate_for_cert) for the per-line walk.


OPEN — next slices (ranked)

1. Summary-path main_fuel_type derivation from the SAP code ← do first

The Elmhurst Summary PDF has no main-heating fuel field — only the SAP code (14.0 Main Heating1 → Main Heating SAP Code 104). So from_elmhurst_site_notes leaves main_fuel_type='', and cert_to_inputs raises MissingMainFuelType (cert_to_inputs.py _main_fuel_code). This blocks the Summary path for every gas-combi cert, including the simulated case (I injected main_fuel_type=26 to run the diagnosis).

Fix: derive the fuel in the mapper (or _main_fuel_code) from sap_main_heating_code via SAP 10.2 Table 4b (104 = condensing combi mains gas), mirroring the existing strict-raise → derive pattern. Cite the table. This is the higher-leverage win — it unblocks the whole site-notes gas-combi population, not one cert.

2. Pin the simulated 001431 case end-to-end (after #1)

Once #1 lands, the Summary path runs natively. Add it as a site-notes fixture and pin every line ref at 1e-4. NB: with .189 + injected fuel, PE and CO2 close to 1e-4 but SAP showed +0.0007 vs a hand-computed target (100 13.95×ECF from the 4-dp (257)=1.6047). That is almost certainly ECF rounding in the target, not a real gap — but verify against the worksheet's own continuous SAP before declaring it closed (don't trust my hand value).

3. Cert 6035 remaining +19 PE

6035 is API/lodged-only (no worksheet) so it can't be pinned past the lodged register. The user can reproduce 6035 exactly in Elmhurst to get a worksheet — offer to format the golden JSON (tests/domain/sap10_calculator/rdsap/fixtures/golden/6035-7729-2309-0879-2296.json) as Elmhurst inputs. With a worksheet, walk the remaining +19 the same way.

Carry-over (lower priority)

  • transform.py:973 treats wall_construction in (5,6) as timber-frame for the ventilation structural-ACH split, but Table 22 / rdsap_uvalues classify 6 = system built (masonry), only 5/7/8 are timber/cob/park. Possible latent ventilation-ACH bug — verify before touching.

Process notes

  • One slice = one commit, spec citation in the message, Co-Authored-By: Claude Opus 4.8 trailer. AAA tests, abs(x-y) <= tol (not pytest.approx).
  • The golden worksheet PE/CO2 pins (.186) re-pin smaller as gaps close — never widen. The lodged-residual pins (test_golden_cert_residual_matches_pin) carry the API-vs-register residual and move when the calc improves.