mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
docs: handover post S0380.195 — 6035 OPEN, API-mapper roof/RR over-count lead
Retracts the premature "6035 = lodged divergence" claim (S0380.195 commit msg + fixture docstring). The golden residual SAP -2 / PE +19.16 / CO2 +0.42t is REAL and exceeds the fallback bar. Section-level diff of 6035 (API) vs sim case 4 (site-notes, pins @1e-4) localised it to a cross-mapper parity break: roof W/K 78.33 (site-notes) vs 130.73 (API), a +52 over-count from the API RR scalar path + roof_construction=4. Next agent starts there. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
4a21717de6
commit
af477678c2
1 changed files with 147 additions and 0 deletions
147
domain/sap10_calculator/docs/HANDOVER_POST_S0380_195.md
Normal file
147
domain/sap10_calculator/docs/HANDOVER_POST_S0380_195.md
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
# Handover — post S0380.195 (gas-combi site-notes + RR/floor bugs; 6035 OPEN)
|
||||
|
||||
Point-in-time note. Start from [`AGENT_GUIDE.md`](AGENT_GUIDE.md) for methodology,
|
||||
accuracy bar, and pipeline — this records *what this session did* and *what is open*.
|
||||
|
||||
- **Branch:** `feature/per-cert-mapper-validation`
|
||||
- **HEAD:** `4a21717d` (S0380.195)
|
||||
- **Baseline:** `2341 passed, 1 skipped, 0 failed`. Verify with the §4 suite command.
|
||||
|
||||
---
|
||||
|
||||
## What this session shipped (S0380.190–195 + 1 extractor fix)
|
||||
|
||||
| Slice | What | Spec |
|
||||
|---|---|---|
|
||||
| **.190** | Gas-combi site-notes `main_fuel_type` derivation. Newer Elmhurst export lodges §14.0 Fuel Type EMPTY + SAP code 104 → `MissingMainFuelType` blocked ALL gas-combi Summary certs. Derive carrier from §15.0 Water Heating Fuel Type for Table 4b gas-boiler codes 101–119 (NOT "104→mains gas" — Table 4b gas codes span mains gas/LPG/biogas; §15.0 disambiguates). `_elmhurst_gas_boiler_main_fuel`. | SAP 10.2 Table 4b p.168 |
|
||||
| extractor fix | Windows-table header remnant ("value value Proofed Shutters") leaked into the FIRST window's `glazing_type` (layout `before_start=0` reaches the wrapped header). Trim prefix to the glazing-start word. | — |
|
||||
| **.191** | Promoted sim case 1 (single-part gas combi) to e2e harness `001431`, 11 pins @1e-4. Resolved the handover's "+0.0007 SAP" as a display-rounded-ECF target artifact. | — |
|
||||
| **.192** | **Simplified room-in-roof bug.** A Simplified RR (assessment "Simplified") lodges PLACEHOLDER slope/ceiling L×H (40 m ceiling height, 32 m slope). Spec derives one timber-framed remaining area `A_RR = 12.5√(A_floor/1.5) − Σgables`. The cascade already computes this (`has_roof_lodgement` gate in heat_transmission.py) but `_map_elmhurst_rir_surface` emitted the placeholder slope/ceiling → 1024+160 m² roof → **7.5× heat-loss explosion (SAP −14.6)**. Fix: drop roof-going surfaces for Simplified. API path (6035) already correct via scalar gable fields. | RdSAP 10 §3.9.1 p.21 |
|
||||
| **.193** | **Suspended-floor (12) sealed rule.** Rule (a) "floor U<0.5 → sealed 0.1" applies only when a U-value is SUPPLIED; an as-built/default U falls to (b)→unsealed 0.2. Cascade fed the computed default U into (a) → wrongly sealed → ~450 kWh space-heat understatement. Fix: gate (a) on `floor_u_value_known`. | RdSAP 10 §5 p.29 |
|
||||
| **.194** | Sim case 3 (8 windows, symmetric HLP) → e2e `001431_rr8`, 11 pins @1e-4. | — |
|
||||
| **.195** | Sim case 4 (6035 floor geometry: Main ground HLP 15.99 + first 8.32) → e2e `001431_6035`, 11 pins @1e-4. | — |
|
||||
|
||||
Net: 4 new Elmhurst-only e2e fixtures (cases 1–4 of cert 001431), all @1e-4. The
|
||||
worksheet Summaries are mirrored into `backend/documents_parser/tests/fixtures/`
|
||||
(`Summary_001431_gas_combi.pdf`, `_rr_ext`, `_rr8w`, `_6035`); source Summary +
|
||||
P960 worksheet tracked under `sap worksheets/golden fixture debugging/simulated
|
||||
case {1..4}/`.
|
||||
|
||||
**The .195 commit message and the `_elmhurst_worksheet_001431_6035.py` docstring
|
||||
claim 6035's +19 PE is "lodged divergence." THAT CLAIM IS RETRACTED — see below.**
|
||||
|
||||
---
|
||||
|
||||
## OPEN (the priority) — golden cert 6035 residual is REAL, not divergence
|
||||
|
||||
`tests/.../test_golden_fixtures.py` pins cert `6035-7729-2309-0879-2296`:
|
||||
`actual_sap=70, expected_sap_resid=-2, expected_pe_resid=+19.16,
|
||||
expected_co2_resid=+0.42 t`. **All three exceed the ±0.5 SAP / small-CO2 fallback
|
||||
bar.** A −2 SAP is not rounding. 6035 was lodged **2025-11-11** under
|
||||
RdSAP-Schema-21.0.1 / SAP 10.2 (software `5.02r0328`) — the SAME methodology we
|
||||
target, so it is NOT a version artifact.
|
||||
|
||||
### What we know
|
||||
- **The cascade reproduces Elmhurst's WORKSHEET engine** for this archetype: sim
|
||||
cases 1–4 (Main+Ext+RR+suspended-floor+gas-combi-104) all pin @1e-4 on all 11
|
||||
Block-1 line refs.
|
||||
- **Case 4 ≈ 6035.** Identical: 2 BPs, age A, solid-brick walls (Main ins, Ext
|
||||
as-built), RR floor 29.75, floor areas, **Main floors HLP 15.99/8.32**, doors,
|
||||
heating (104/control 2106), 8 windows by **area + BP + 7/8 orientations**.
|
||||
Remaining input diffs case4-vs-6035:
|
||||
1. the **3.82 m² window**: North in case 4, **South** in 6035 (only window diff);
|
||||
2. **lighting bulbs**: case 4 cascade lighting 262 vs 6035's **364** (6035 lodges
|
||||
9 low-energy + 2 incandescent; case 4's Summary lighting parsed as None);
|
||||
3. **meter type** "Dual" (case4) vs API **2** (6035);
|
||||
4. 6035 lodges `cylinder_size=1` (case 4 none) — appears immaterial (HW matches).
|
||||
- **Controlled test:** flipping case 4's 3.82 window N→S raises SAP only **+0.25**
|
||||
(68.19→68.44). Nowhere near +2. So orientation does NOT explain the gap.
|
||||
- **The energy/demand model looks ~right per-end-use.** Cascade DEMAND
|
||||
(postcode) costs ≈ 6035's lodged costs: heating £1278 vs lodged £1285, HW £225
|
||||
vs £217, lighting £103 vs £103. So the −2 SAP lives in the **RATING block**
|
||||
(UK-avg): cascade rating cost 948.59 → ECF 2.31 → SAP 67.81; register implies
|
||||
cost ~£886 / ECF 2.15 / SAP 70. **Plus the CO2 (+0.42 t) is unexplained.**
|
||||
- Neither bug fixed this session touches 6035 (its RR uses the API scalar-field
|
||||
path, already correct; its floor U=0.63 ≥ 0.5 was already "unsealed").
|
||||
|
||||
### The contradiction to resolve
|
||||
Elmhurst-worksheet-for-case4-inputs = **68**, 6035-register = **70**, same
|
||||
methodology, inputs nearly identical, and the known diffs explain only ~+0.25.
|
||||
Either (a) 6035's register was produced from inputs materially different from the
|
||||
golden JSON in a rating-relevant way we can't see, or (b) there's a real cascade
|
||||
bug only 6035's exact combination triggers (the simulated cases didn't hit it).
|
||||
|
||||
### ★ BREAKTHROUGH LEAD (end of session) — API-mapper roof/RR over-count
|
||||
The user's hypothesis ("something missing from the API mapper") is CONFIRMED.
|
||||
Diffing **6035 (API path) vs case 4 (site-notes path)** at the SECTION level
|
||||
(`heat_transmission_section_from_cert`) — with near-identical fabric — exposes a
|
||||
cross-mapper parity break that should not exist:
|
||||
|
||||
| §3 line | case4 (site-notes) | 6035 (API) | Δ |
|
||||
|---|---|---|---|
|
||||
| **roof W/K** | **78.33** | **130.73** | **+52.39** |
|
||||
| party W/K | 36.86 | 0.00 | −36.86 |
|
||||
| (33) fabric heat loss | 290.72 | 304.66 | +13.94 |
|
||||
| (31) total ext area | 231.02 | 242.74 | +11.72 |
|
||||
| walls / floor / windows / doors | — | — | ≈0 |
|
||||
|
||||
**The roof +52 W/K is the prime suspect for the whole 6035 residual** (52 W/K of
|
||||
spurious heat loss ≈ the −2 SAP / +19 PE / +0.42 t CO2). Root cause is the RR/roof
|
||||
representation feeding two DIFFERENT cascade paths:
|
||||
- **case 4 (site-notes):** `sap_room_in_roof.detailed_surfaces=[gable_wall_external,
|
||||
gable_wall]`, scalar gable lengths = None, `roof_construction=None` → cascade's
|
||||
Detailed-loop residual path (`12.5√(A_floor/1.5) − Σwalls`) → roof 78.33. ✓
|
||||
(pins to case-4 worksheet @1e-4).
|
||||
- **6035 (API):** `detailed_surfaces=None`, scalar `gable_1/2_length_m=4.65`,
|
||||
**`roof_construction=4`** → cascade's SCALAR RR path (heat_transmission.py
|
||||
~363-460 + ~853-875) AND a separate `roof_construction=4` main-roof element →
|
||||
roof 130.73. Likely DOUBLE-COUNTS the main roof over the full footprint with the
|
||||
RR, or the scalar A_RR path over-states the area.
|
||||
|
||||
Hand-check: for 6035 the correct roof ≈ RR remaining (12.5√(29.75/1.5) − 2×11.39
|
||||
= 32.88 × 2.30 = 75.6) + main-loft residual (41.73−29.75=11.98 × 0.14 = 1.68) +
|
||||
ext roof (7.21 × 0.14 = 1.01) ≈ **78.3** (matches case 4). The API path's 130.73 is
|
||||
~52 too high.
|
||||
|
||||
**START HERE:** instrument the API RR/roof path for 6035. Compare
|
||||
`_api_build_room_in_roof` (mapper.py ~2713) output + `roof_construction=4`
|
||||
handling vs the site-notes detailed_surfaces path. Find where the extra ~52 W/K
|
||||
roof comes from (main-roof-area double count with RR, or scalar A_RR over-state).
|
||||
Fix so the API path matches the site-notes path (cross-mapper parity), then re-pin
|
||||
6035's golden residual (should collapse toward 0). The party=0 (party_wall_
|
||||
construction=3) is secondary — verify 3=solid U=0 is correct first.
|
||||
|
||||
This is a CALCULATOR/MAPPER bug, not lodged divergence — the byte-exact-worksheet
|
||||
plan below is now a fallback only.
|
||||
|
||||
### Fallback — byte-exact 6035 worksheet ("simulated case 5")
|
||||
Ask the user to generate case 5 = case 4 with EVERY remaining input matched to
|
||||
6035: **3.82 m² window → South**, **lighting = 9 low-energy + 2 incandescent**,
|
||||
**meter type matched**, **cylinder matched**. Then:
|
||||
- If the worksheet SAP = **70** → real cascade bug. Diff cascade vs worksheet
|
||||
line-by-line (start §6 solar gains (74)–(83) for the south window, §8 lighting
|
||||
(232)/Appendix L, then §10a/§12 rating cost/ECF and §12/§13 CO2).
|
||||
- If the worksheet SAP = **68** → the register's 70 is the anomaly (lodged from
|
||||
different inputs); 6035 becomes a documented register-vs-worksheet divergence.
|
||||
|
||||
Parallel angle worth a look NOW (no new worksheet needed): the **lighting energy**
|
||||
(cascade 364 for 9 LE + 2 inc, TFA 128) — verify against SAP 10.2 Appendix L; and
|
||||
the **CO2 (+0.42 t)** decomposition by carrier (the demand-cost match suggests the
|
||||
energy is right, so a CO2-FACTOR or rating-block issue is implicated).
|
||||
|
||||
---
|
||||
|
||||
## Carry-over (lower priority, from the prior handover)
|
||||
- `transform.py:973` treats `wall_construction in (5,6)` as timber-frame for the
|
||||
ventilation structural-ACH split, but 6 = system-built (masonry); only 5/7/8 are
|
||||
timber/cob/park. Possible latent ventilation-ACH bug — verify before touching.
|
||||
- Summary-path `main_fuel_type` for non-gas/non-104 boilers (only 101–119 + the
|
||||
existing liquid/solid/electric/community branches are covered).
|
||||
|
||||
## 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 4 sim-case e2e fixtures pin Block 1 (UK-avg rating) via
|
||||
`Sap10Calculator().calculate(epc)` — NOT the postcode demand block.
|
||||
- Window ORIENTATION does NOT change the SAP rating much (+0.25 for 3.82 m²) — do
|
||||
not over-attribute the 6035 gap to it.
|
||||
Loading…
Add table
Reference in a new issue