From 7e08e7af71f9022e9dfb632cbfbeebede4915ba3 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Tue, 2 Jun 2026 10:25:24 +0000 Subject: [PATCH] docs: handover post S0380.164..169 Co-Authored-By: Claude Opus 4.7 --- .../docs/HANDOVER_POST_S0380_169.md | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 domain/sap10_calculator/docs/HANDOVER_POST_S0380_169.md diff --git a/domain/sap10_calculator/docs/HANDOVER_POST_S0380_169.md b/domain/sap10_calculator/docs/HANDOVER_POST_S0380_169.md new file mode 100644 index 00000000..e0ca099a --- /dev/null +++ b/domain/sap10_calculator/docs/HANDOVER_POST_S0380_169.md @@ -0,0 +1,193 @@ +# Handover — post Slices S0380.164..169 + +Branch: `feature/per-cert-mapper-validation`. **HEAD `9ed003a5`**. +Predecessor: [`HANDOVER_POST_S0380_164.md`](HANDOVER_POST_S0380_164.md). + +## TL;DR + +Six slices landed in two phases: + +**Phase 1 — cascade closure** (.164 + .165): closed the LAST two open +variants in the cascade-OK tier. `solid fuel 2` ΔCO2/ΔPE −93/-1027 → +±0.0000 (Elmhurst-mirror §12.4.4 summer-immersion double-count, new +§8.2 row). `pcdb 1` Δ−0.011 SAP → +0.0000 (§9.4.11 boiler-interlock +-5pp applied AFTER Eq D1 instead of before). The 41-variant heating- +systems corpus now has its 27-variant **cascade-OK tier fully EXACT** +on every metric (Σ|ΔSAP_c| ≈ 0.0001 ≈ floating-point noise). + +**Phase 2 — mapper unblocks** (.166–.169): 11 of 16 blocked variants +unblocked via 4 mapper-extension slices. 7 EXACT on first try +(pcdb 3, electric 11/12/13/14, oil 2, oil 5); 4 land with cascade-side +residuals pinned as forcing functions (oil 3/4/6, no system). + +| Slice | HEAD | Scope | Cascade-OK tier | +|---|---|---|---| +| S0380.164 | `302db131` | **§8.2 Elmhurst-mirror summer-immersion CO2/PE double-count.** §12.4.4 back-boiler HW blend adds `S_fuel × Table 12 annual electric` term on top of Table 12d/e monthly cascade for dual-rate tariffs. Closures: `solid fuel 2` ΔCO2/ΔPE → ±0.0000. Single-cert evidence flagged in new §8.2 row. | 25/25 EXACT | +| S0380.165 | `3de52bcb` | **§9.4.11 boiler-interlock -5pp applied AFTER Eq D1, not before.** Reciprocal Eq D1 weighting is non-linear in η; worksheet (217)m for pcdb 1 matches post-Eq-D1 form to 1e-4. New `interlock_penalty_pp` kwarg on `_apply_water_efficiency`. Closures: `pcdb 1` Δ−0.011 SAP / +£0.24 / +1.33 CO2 / +5.70 PE → ±0.0000. | 27/27 EXACT | +| S0380.166 | `589a8631` | **Bulk LPG mapper unblock.** `"Bulk LPG": 27` in `_ELMHURST_MAIN_FUEL_TO_SAP10`. Pcdb 3 EXACT first try. | 28/28 EXACT | +| S0380.167 | `7901dda4` | **Electric storage 11-14 unblock.** WEA / REA / OEA → 30. Electric 11/12/13/14 all EXACT first try. | 32/32 EXACT | +| S0380.168 | `58a95472` | **Bio-liquid oil 2-6 unblock + Table 32 FAME 5.44 → 7.64 (deferred .131 TODO).** BFD/BXE/BXF/BZC/B3C + 4 water labels. oil 2 (HVO) + oil 5 (Bioethanol) EXACT; oil 3/4 (FAME) closed 85 % of cost gap; oil 6 (B30K) carries cascade residual. | 34 EXACT + 3 pinned | +| S0380.169 | `9ed003a5` | **"No system" unblock per §A.2.2.** `"NON": 30`. Cascade lands with small residual pinned. | 34 EXACT + 4 pinned | + +Extended handover suite at HEAD: **916 pass, 0 fail.** Pyright net-zero +(43 → 43). + +## Current residual state at HEAD `9ed003a5` + +### Cascade-OK tier (38 variants, up from 25) + +**34 variants EXACT (|Δ| < 1e-3) on all 4 metrics.** 4 variants +carry pinned non-zero residuals (forcing functions): + +| Variant | ΔSAP_c | Δcost | ΔCO2 | ΔPE | Notes | +|---|---:|---:|---:|---:|---| +| oil 3 | +2.59 | −£62 | −14.58 | −967 | FAME cascade HW kWh diff | +| oil 4 | +2.56 | −£57 | −13.35 | −885 | FAME cascade HW kWh diff | +| oil 6 | +3.05 | −£70 | −240.66 | −1113 | B30K SH/HW kWh gap | +| no system | +1.18 | −£27 | −49.83 | −562 | §A.2.2 portable-electric defaults | + +All other 34 variants ±0.0000 on every metric. + +### Blocked tier (5 variants — community heating) + +Unchanged. `community heating 1/2/3/4/6`. **Deepest remaining tier:** +needs extractor field extraction + new community-fuel-type dispatch +in the mapper + cascade integration for heat-network paths (Table 12c +distribution loss, Table 12 heat-network codes 41/43/48/51/53/54). + +## Open fronts ranked by leverage + +### 1. **Community heating unblock — 5 variants** (next-session work) + +The deepest remaining work. The Elmhurst Summary §14.1 lodges: + + Heating Type Space and Water Heating + Community Heat Source Boilers / Combined Heat and Power / Heat pump + Community Fuel Type Mains Gas / Electricity / Mineral oil / Coal / ... + +Variant breakdown: + + community heating 1 — COM + 301 + Boilers + Mains Gas → code 51 + community heating 2 — COM + 302 + CHP + Mains Gas → code 48 + community heating 3 — COM + 304 + Heat pump + Electricity → code 41 + community heating 4 — COM + 302 + CHP + Mineral oil → code 48 (or 53 if not CHP) + community heating 6 — COM + 302 + CHP + Coal → code 48 (or 54 if not CHP) + +The work spans three layers: + +1. **Extractor**: extract Community Heat Source + Community Fuel Type + strings into a new `CommunityHeating` dataclass on `ElmhurstSiteNotes`. +2. **Mapper**: `_resolve_community_heating_fuel_code(heat_source, fuel)` + dispatch helper that maps the (heat_source, fuel) pair to the + correct Table 12 heat-network code. +3. **Cascade**: ensure the heat-network path (Table 12c DLF age-band, + PCDB Table 322 records if lodged, Table 12 note (k) DHW-only + half-standing) handles all 5 sub-variants correctly. + +Likely 2-3 slices total — start with the extractor + mapper, then +probe each variant's residual and close cascade gaps as they surface. + +### 2. **oil 3 / oil 4 (FAME) cascade HW kWh gap** + +Cascade HW kWh ~900 less than worksheet for oil 3/4 (FAME boilers). +Probably SAP 10.2 Table 4b code 128/129 has a non-standard summer +efficiency or Eq D1 path that the cascade isn't applying. Per-line +worksheet walk: cascade `_apply_water_efficiency` output vs (219)m +row. + +### 3. **oil 6 (B30K) cascade SH + HW kWh gap** + +Δcost −£70 on identical prices means kWh differs. Likely a different +Table 4b code-126 path. Closes ~£70 / 240 CO2 / 1113 PE. + +### 4. **no system §A.2.2 cascade defaults** + +ΔSAP +1.18 — cascade thinks dwelling is more efficient than worksheet. +Probable spec gap: §A.2.2 portable-electric defaults +(responsiveness / control-type / Table 11 secondary fraction). Per- +line walk on (210)m / (240) cost factor needed. + +## Standard slice workflow (unchanged) + +1. Read spec page + identify rule (or Elmhurst worksheet pattern) +2. Probe one variant; verify diagnosis via monkey-patch / direct walk +3. Write failing AAA test (literal `# Arrange / # Act / # Assert`) +4. Implement helper / dispatch entry / mapper extension +5. Re-pin affected variants (DO NOT widen tolerance) +6. Run extended handover suite (command below) +7. Pyright net-zero check (`git stash` → pyright → `git stash pop` → pyright) +8. If mirroring Elmhurst against spec literal: add a row to + `SAP_CALCULATOR.md §8 "Elmhurst-mirrored spec divergences"`. The + ≥2-cert rule applies unless the new divergence shares its shape + with an already-documented row (S0380.164 added §8.2 under this + exception with a single-cert flag). +9. Commit with spec citation + `Co-Authored-By: Claude Opus 4.7 ` +10. Update `project-heating-systems-corpus` + `MEMORY.md` index + +## Test baseline at HEAD `9ed003a5` + +```bash +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: **916 pass, 0 fail.** + +## Memories to load (in order) + +``` +project-heating-systems-corpus # HEAD 9ed003a5 +feedback-sap-10-2-only-never-10-3 +feedback-software-no-special-handling +feedback-spec-floor-skepticism +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-golden-residuals-near-zero +feedback-one-e-minus-4-across-the-board +feedback-bigger-slices-for-uniform-work +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** — re-pin smaller or find the spec gap. +- **Don't add empirical gates** to keep cohort pins stable. +- **Don't re-investigate Slices .91..169** — all settled. +- **Don't add new helpers to `domain/sap10_ml/`** — on deprecation path. +- **Don't treat ΔSAP=0.07 as "closed"** — target is <1e-4 vs worksheet. + +## Master doc + +The canonical architecture + API + validation doc lives at +[`domain/sap10_calculator/docs/SAP_CALCULATOR.md`](SAP_CALCULATOR.md) +(7 sections + §8 with .1 and .2 entries). S0380.164 added §8.2 for +the §12.4.4 summer-immersion double-count. + +## Good luck.