mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
docs: handover post S0380.174..176
Three slices landed: §4 storage+primary loss for community heating
(.174), §14.1 heating_controls_sap extraction (.175), Table 4b combi
sub-row dispatch (.176). Cohort moves from 36 EXACT + 5 pinned to 34
EXACT + 7 pinned — net 2 new full-EXACT closures (oil 3 + oil 4) +
2 reshape (CH1/CH3 SAP/cost EXACT, CO2/PE pinned on the (372)
electrical-distribution Elmhurst-factor mystery).
933 pass + 0 fail at HEAD 326066ee. Pyright net-zero.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
ff80fb4b5c
commit
a862111795
1 changed files with 277 additions and 0 deletions
277
domain/sap10_calculator/docs/HANDOVER_POST_S0380_176.md
Normal file
277
domain/sap10_calculator/docs/HANDOVER_POST_S0380_176.md
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
# Handover — post Slices S0380.174..176
|
||||
|
||||
Branch: `feature/per-cert-mapper-validation`. **HEAD `326066ee`**.
|
||||
Predecessor: [`HANDOVER_POST_S0380_173.md`](HANDOVER_POST_S0380_173.md).
|
||||
|
||||
## TL;DR
|
||||
|
||||
Three slices landed on the heating-systems corpus:
|
||||
- **`.174`** closed §4 (62)m HW for all 5 community-heating variants;
|
||||
CH1 HW EXACT.
|
||||
- **`.175`** wired §14.1 Community Heating "Heating Controls SAP" into
|
||||
the mapper; CH1 + CH3 SAP / cost EXACT.
|
||||
- **`.176`** added Table 4b combi sub-row fall-through to the (61)m
|
||||
default gate; **oil 3 + oil 4 FULLY EXACT on all four metrics**.
|
||||
|
||||
**41 variants total → 34 EXACT + 7 pinned** (was 36 + 5 pre-`.174`).
|
||||
Pinned count drops from 9 (in `.173` handover) to 7 because oil 3 +
|
||||
oil 4 fully closed; CH1 + CH3 reshape from "SAP/cost-pinned" to
|
||||
"SAP/cost EXACT + CO2/PE pinned" pending the (372) electrical-
|
||||
distribution Elmhurst factor mystery.
|
||||
|
||||
| Slice | HEAD | Scope |
|
||||
|---|---|---|
|
||||
| S0380.174 | `4876140a` | **§4 storage + primary loss for community heating.** SAP 10.2 §4 line 1482 "Heat networks": primary circuit loss for insulated pipework + cylinderstat applies. Table 2b note b verbatim system-type list ("boiler / warm air / heat pump") OMITS community heating — ×0.9 multiplier doesn't apply. Three changes: new `_HEAT_NETWORK_PIPEWORK_INSULATION_FRACTION = 1.0`, new branch in `_primary_loss_applies` (heat-network main + WHC ∈ {901, 902, 914} → True), new `_table_2b_note_b_multiplier_applies` predicate gating ×0.9 by system type. CH1 HW useful (62)m closes 2339.24 → 2658.01 EXACT vs ws; HW fuel kWh closes 3391.90 → 3854.12 EXACT; (65)m heat gains 793.51 → 1221.62 EXACT. Cost/SAP signs flipped — exposed pre-existing §7 MIT +0.46 K over-count. |
|
||||
| S0380.175 | `eda07d12` | **§14.1 Community Heating heating_controls_sap extraction.** All 5 CH variants lodge "Heating Controls SAP: 2306" in §14.1 (bare 4-digit form), not in §14.0 "Main Heating Controls Sap" (which is empty for CH certs). Pre-slice mapper read only §14.0 → `main_heating_control=''` → cascade defaulted to `control_type=2` (off-hours (7, 8)). Code 2306 (Table 4e Group 3) → control_type=3 (off-hours (9, 8)), which closes the +0.46 K MIT (92)m residual that `.174` surfaced. Two changes: `_elmhurst_sap_control_code` accepts bare integer form, `_map_elmhurst_sap_heating` falls through to `mh.community_heating.heating_controls_sap` when §14.0 is empty. CH1 + CH3 ΔSAP_c -1.0572 → +0.0000 EXACT; Δcost +£24.36 → -£0.00 EXACT. |
|
||||
| S0380.176 | `326066ee` | **Table 4b combi sub-row dispatch for (61)m default.** SAP 10.2 §4 line 7702 + Table 4b row names: codes 128/129/130 are explicit combi sub-rows ("Combi oil boiler, ..."). Pre-slice `_table_3a_combi_loss_default_applies` gated only on `main_heating_category ∈ {1, 2, 3, 6}`; Elmhurst mapper leaves the category None on Table 4b liquid-fuel boilers so the cascade fell through to (61)m=0. Added `_TABLE_4B_COMBI_OR_CPSU_CODES` fall-through (set already exists in symmetric `_primary_loss_applies` Table 4b branch — see `.146`). **oil 3 + oil 4 ALL FOUR METRICS EXACT** (ΔSAP +2.5863/+2.5603 → ±0.0000, Δcost -£62/-£57 → ±0.00, ΔPE -967/-885 → ±0.00). Cohort 9 → 7 pinned. |
|
||||
|
||||
Extended handover suite at HEAD: **933 pass + 1 skipped, 0 fail.**
|
||||
Pyright net-zero on all affected files.
|
||||
|
||||
## Current residual state at HEAD `326066ee`
|
||||
|
||||
### Cascade-OK tier (41 variants — all populated corpus folders)
|
||||
|
||||
**34 variants EXACT** on all four metrics (|ΔSAP| < 1e-3, |Δcost| <
|
||||
£0.01, |ΔCO2| < 0.1 kg, |ΔPE| < 0.1 kWh):
|
||||
|
||||
```
|
||||
ashp, gshp,
|
||||
electric 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14,
|
||||
oil 1, oil 2, oil 3, oil 4, oil 5, oil pcdb 1, oil pcdb 2, oil pcdb 3,
|
||||
pcdb 1, pcdb 3,
|
||||
solid fuel 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
|
||||
```
|
||||
|
||||
**7 variants pinned**:
|
||||
|
||||
| Variant | SAP code | ΔSAP_c | Δcost | ΔCO2 | ΔPE | Closure driver |
|
||||
|---|---:|---:|---:|---:|---:|---|
|
||||
| CH6 (CHP/Coal) | 302 | −7.49 | +£172.68 | −2939.67 | +7481.57 | DLF=1.0 P960 quirk + CHP credit |
|
||||
| oil 6 (B30K) | 126 | +3.05 | −£69.79 | −240.66 | −1112.66 | -5pp interlock penalty on non-combi |
|
||||
| no system | 699 | +1.18 | −£27.15 | −49.83 | −562.44 | §A.2.2 portable-electric defaults |
|
||||
| CH4 (CHP/Oil) | 302 | +0.53 | −£12.16 | −4401.85 | +111.58 | SAP 302 CHP credit (CO2) |
|
||||
| CH2 (CHP/Gas) | 302 | +0.53 | −£12.16 | −1435.09 | +1123.01 | SAP 302 CHP credit (CO2 + PE) |
|
||||
| CH3 (HP/Elec) | 304 | +0.0000 | −£0.00 | −98.92 | −457.54 | (372) electrical-distribution CO2/PE + (367) HP scaling |
|
||||
| CH1 (Boilers/Gas) | 301 | +0.0000 | −£0.00 | −23.60 | −208.23 | (372) electrical-distribution CO2/PE Elmhurst factor |
|
||||
|
||||
### Blocked tier (0 variants)
|
||||
|
||||
**Empty** (since `.170`). `_BLOCKED_BY_MISSING_MAIN_FUEL_TYPE` tuple
|
||||
in `test_heating_systems_corpus.py` remains empty; the parametrised
|
||||
raise-test is `pytest.mark.skipif`'d.
|
||||
|
||||
## Open fronts ranked by leverage
|
||||
|
||||
### 1. SAP 302 CHP CO2/PE credit cascade (3 variants — CH2, CH4, CH6)
|
||||
|
||||
Highest cohort leverage: closes ~−8 SAP-equivalent across CH6 + the
|
||||
big CO2 / PE residuals on CH2 / CH4 simultaneously. Spec block 13b
|
||||
PE (PDF p.153) + 12b CO2:
|
||||
|
||||
```
|
||||
Space heating from CHP (307a) × 100 ÷ (362) = ... (363)
|
||||
less credit emissions −(307a)×(361) ÷ (362) = ... (364)
|
||||
Water heated by CHP (310a) × 100 ÷ (362) = ... (365)
|
||||
less credit emissions −(310a)×(361) ÷ (362) = ... (366)
|
||||
Heat from heat source 2 [(307b)+(310b)] × 100 ÷
|
||||
(467b) = ... (468)
|
||||
```
|
||||
|
||||
RdSAP 10 §C defaults: CHP overall eff 75%, heat-to-power ratio 2.0 →
|
||||
heat_eff 50% + electric_eff 25%; boiler eff 80%. Verified against
|
||||
CH2/CH4/CH6 worksheet (461)/(462) = 25% / 50% exactly.
|
||||
|
||||
**Per-line walk caveat (unresolved).** The Elmhurst worksheet (463)
|
||||
energy column = spec_formula × 0.8523 uniformly across non-CHP
|
||||
heat-network rows. The 0.8523 multiplier appears in CH1 (467) too.
|
||||
Mechanism unidentified; not RdSAP 10 / SAP 10.2 spec-derived. Walk
|
||||
the worksheet per-line before forming hypotheses.
|
||||
|
||||
Likely 2-3 slices: (a) CHP credit + boiler-side eff for SH; (b)
|
||||
mirror for HW path; (c) the 0.8523 multiplier if load-bearing. The
|
||||
`.172` scaling helper already keys on
|
||||
`_HEAT_NETWORK_HEAT_SOURCE_EFFICIENCY` — add 302 there with weighted
|
||||
overall eff once the split formula is in place. The `.173` predicate
|
||||
`_is_community_heating_hw_from_main` also gates on table membership
|
||||
and will pick up SAP 302 automatically.
|
||||
|
||||
### 2. oil 6 (B30K) −5pp interlock cascade (1 variant, ΔSAP +3.05)
|
||||
|
||||
Per-line walk in this session: cascade Eq D1 outputs (winter, summer) =
|
||||
(80, 68) → annual eff ~73% at Jan; ws (217)m Jan = 73.07. Cascade gives
|
||||
HW kWh 3823.38 vs ws 4099.59. Back-solving the worksheet: applying -5pp
|
||||
interlock penalty to BOTH winter and summer ((75, 63)) reproduces ws
|
||||
(217)m Jan = 73.07 EXACTLY.
|
||||
|
||||
Cascade `eq_d1_interlock_penalty_pp` is gated on `no_interlock` =
|
||||
"cylinder thermostat absent". For oil 6 the cert lodges
|
||||
`cylinder_thermostat = 'Y'` so cascade sets penalty=0. But the
|
||||
worksheet applies -5pp anyway — likely a different gate for non-PCDB
|
||||
Table 4b regular boilers vs PCDB Table 105 boilers.
|
||||
|
||||
Probable 1-slice fix: extend the interlock-penalty gate to fire for
|
||||
Table 4b non-combi boiler codes (124-127) when... [need spec citation
|
||||
on the exact rule — investigate SAP 10.2 §9.4.11 interlock conditions
|
||||
for Elmhurst's interpretation]. ΔSAP_c +3.05 → ±0.0000 expected;
|
||||
closes 4 metrics on a single variant.
|
||||
|
||||
### 3. "no system" §A.2.2 portable-electric defaults (1 variant, ΔSAP +1.18)
|
||||
|
||||
Carried over from `.169`. Cascade thinks dwelling more efficient than
|
||||
worksheet. Probable §A.2.2 portable-electric defaults gap
|
||||
(responsiveness / control / Table 11). Probably 1 slice.
|
||||
|
||||
### 4. CH1 / CH3 (372)/(472) electrical-distribution CO2/PE (deferred)
|
||||
|
||||
Worksheet (372) CO2 factor = 0.1994 (block 11a, rating cascade) and
|
||||
0.2114 (block 11b, demand cascade). PE factor = 1.7591 / 2.1872.
|
||||
These don't match any Table 12 / 12d / 12e weighting I could derive
|
||||
from the SH (307) or (307)+(310) heating-demand monthly profile.
|
||||
|
||||
(313) annual = 0.01 × (307) only — confirmed across all 5 CH variants
|
||||
(NOT 0.01 × ((307)+(310)) as spec text says). Once a factor source is
|
||||
identified, cascade should add an electricity-for-heat-distribution
|
||||
contribution to CO2/PE for heat-network mains.
|
||||
|
||||
Deferred this session. Either reverse-engineer the Elmhurst formula
|
||||
from a wider set of variants or find BRE documentation on the (372)
|
||||
factor convention.
|
||||
|
||||
### 5. CH6 DLF=1.0 lodging in P960 (architectural — pinned forever)
|
||||
|
||||
P960 input lodges `Distribution Loss: Two adjoining dwellings sharing
|
||||
a single heating system` + `Distribution Loss Value: 0.0` → ws (306)
|
||||
= 1.0000. Summary lodges nothing distinguishing CH6 from CH4. Per
|
||||
spec §C3.1 the manual-DLF override is legal but the Summary doesn't
|
||||
carry it. Two paths: (a) extend extractor to surface §17 Additional
|
||||
Information when Elmhurst eventually lodges it; (b) accept as pinned.
|
||||
Recommendation: **(b) — pin and document**.
|
||||
|
||||
## Critical discipline reinforced this session
|
||||
|
||||
**Per-line walk worksheet → spec → fix.** All three slices landed via
|
||||
per-line worksheet dumps confirming the spec rule before
|
||||
implementation:
|
||||
- `.174` probed ws (56)/(57)/(59) and back-solved p=1.0 + TF=0.6 from
|
||||
the spec literal.
|
||||
- `.175` traced the cascade's MIT divergence to control_type=2 vs
|
||||
expected 3, then back-solved from worksheet (89) util_rest = 0.9898
|
||||
+ (90) T_rest = 16.11 confirming off-hours (9, 8).
|
||||
- `.176` ran the cascade `_apply_water_efficiency` trace to find
|
||||
`annual=1935.37` (= (45)) being passed when ws uses (62) = 2535.37
|
||||
(= (45) + (46) + (61)) — exposing the missing combi_loss.
|
||||
|
||||
**Spec-floor skepticism cuts BOTH ways.** `.174`'s spec-correct fix
|
||||
EXPOSED the §7 MIT bug that pre-slice offsetting bugs had masked. The
|
||||
chain `.174` → `.175` followed [[feedback-software-no-special-handling]]:
|
||||
apply spec-correct fix uniformly; the surfaced residual is the next
|
||||
slice's target, not a regression.
|
||||
|
||||
**Pin diagnoses before forming hypotheses.** The (372) Elmhurst factor
|
||||
0.1994 doesn't match any Table 12 derivation. Rather than guess,
|
||||
session pivoted to the next-tractable front (oil 3/4 combi loss) which
|
||||
closed cleanly. The (372) deferred entry documents what's known and
|
||||
what's tried.
|
||||
|
||||
**Don't conflate `main_heating_category` and `sap_main_heating_code`.**
|
||||
Two `.176` slices ago, similar Elmhurst mapper artifact: the FAME oil
|
||||
boilers lodge `sap_main_heating_code=128/129` but the mapper leaves
|
||||
`main_heating_category=None`. Cascade dispatch helpers that gate on
|
||||
either field must check BOTH. The `_TABLE_4B_COMBI_OR_CPSU_CODES` set
|
||||
already existed for the symmetric `_primary_loss_applies` branch
|
||||
(per `.146`); adding the same fall-through to
|
||||
`_table_3a_combi_loss_default_applies` was a 4-line change with
|
||||
exact closure on 8 metrics (oil 3 + oil 4 × SAP/cost/CO2/PE).
|
||||
|
||||
## 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.
|
||||
9. Commit with spec citation + `Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>`
|
||||
10. Update `project-heating-systems-corpus` + `MEMORY.md` index
|
||||
|
||||
## Test baseline at HEAD `326066ee`
|
||||
|
||||
```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: **933 pass + 1 skipped, 0 fail.**
|
||||
|
||||
## Memories to load (in order)
|
||||
|
||||
```
|
||||
project-heating-systems-corpus # HEAD 326066ee
|
||||
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..176** — 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.
|
||||
- **Don't form a spec hypothesis without per-line data.** The (372)
|
||||
Elmhurst factor 0.1994 is unexplained; don't bake guesses into the
|
||||
cascade. Reverse-engineer with more variants first, or find BRE
|
||||
documentation.
|
||||
- **Don't conflate `main_heating_category` and `sap_main_heating_code`
|
||||
in cascade gates.** The Elmhurst mapper leaves `category=None` on
|
||||
Table 4b liquid-fuel boilers; gates must check both fields.
|
||||
|
||||
## Master doc
|
||||
|
||||
The canonical architecture + API + validation doc lives at
|
||||
[`domain/sap10_calculator/docs/SAP_CALCULATOR.md`](SAP_CALCULATOR.md)
|
||||
(§8.1 + §8.2 documented). If the (372) Elmhurst-factor mystery
|
||||
resolves and the formula turns out to be an Elmhurst-vs-spec
|
||||
divergence, add §8.3.
|
||||
|
||||
## Good luck.
|
||||
Loading…
Add table
Reference in a new issue