mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
docs: handover + next-agent prompt post S0380.85..90 (BP main-wall closure + SH-channel discovery + strict-raise series)
Session summary documents covering 6 slices:
- S0380.85 — Curtain Wall §5.18 dispatch (cascade walls 443 → 555.93 W/K)
- S0380.86 — §5.6 thin-wall stone + §5.8 dry-line (555.93 → 602.40,
worksheet 604.07, 0.27% residual)
- S0380.87 — Table 4e GROUP 2 HP control codes — single-line spec
dispatch bug; SH residual +7924 → +1460 (82%), sap_score
23 → 27, largest single-slice movement of session
- S0380.88 — Full Table 4e Groups 0-7 + UnmappedSapCode strict-raise
- S0380.89 — Table 4d responsiveness + screed-UFH bug fix + strict raise
(latent bug found via strict-raise rollout)
- S0380.90 — 6 dispatch sites strict-raise + UnmappedSapCode shared
module + GOV.UK API digit-string meter_type bug fix
HANDOVER_POST_S0380_90.md covers full state, cumulative-closure table,
strict-raise philosophy, and which 6 dispatch sites were closed.
NEXT_AGENT_PROMPT_POST_S0380_90.md briefs the next-slice work:
S0380.91 (RdSAP 10 Table 15 row 3 "Cavity masonry filled" U=0.2 in
u_party_wall — closes ~+1000 kWh of the remaining +1460 SH residual
on cert 000565 Ext1).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
9bfb852483
commit
edb1e6b892
2 changed files with 451 additions and 0 deletions
251
domain/sap10_calculator/docs/HANDOVER_POST_S0380_90.md
Normal file
251
domain/sap10_calculator/docs/HANDOVER_POST_S0380_90.md
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
# Handover — post S0380.85..90 (BP main-wall closure + SH-channel discovery + strict-raise series)
|
||||
|
||||
Branch: `feature/per-cert-mapper-validation`. **HEAD `9bfb8524`**.
|
||||
Predecessor: [`HANDOVER_POST_S0380_84.md`](HANDOVER_POST_S0380_84.md).
|
||||
|
||||
## Slices committed this session (S0380.85..90)
|
||||
|
||||
Six spec-cited slices: two BP main-wall closures (Curtain Wall + thin-
|
||||
wall stone) followed by SH-channel investigation that surfaced the
|
||||
S0380.87 single-line bug (the dominant SH residual driver), then a
|
||||
3-slice strict-raise series that closed the calculator's cascade-
|
||||
dispatch silent-fallback inventory.
|
||||
|
||||
| Slice | Commit | Spec | Cert 000565 outcome |
|
||||
|---|---|---|---|
|
||||
| **S0380.85** | `647c1aad` | RdSAP 10 §5.18 (PDF p.48) — "U= 2.0 W/m²K for pre-2023 curtain walls; for post-2023, U-values as for windows below Table 24" | Cascade walls 443 → 555.93 W/K (+112). BP[2] Ext2 Curtain Wall U: 0.60 → 1.40 per worksheet (29a). |
|
||||
| **S0380.86** | `6c8bbbc9` | RdSAP 10 §5.6 Table 12 (PDF p.40) thin-wall stone formula + §5.8 + Table 14 dry-line | Cascade walls 555.93 → 602.40 W/K (worksheet 604.07; **0.27% residual**). BP[0] alt1 U: 0.32 → 2.34 EXACT vs worksheet. Plus `SapAlternativeWall.wall_thickness_mm` field added (per [[feedback-no-misleading-insulation-type]]). |
|
||||
| **S0380.87** | `c0328f4e` | SAP 10.2 Table 4e GROUP 2 (PDF p.172-173) — HP control code 2207 → control type 3 | **Largest single-slice movement of the session**: sap_score 23 → 27; SH residual +7924 → **+1460 kWh (82% closed)**; sap_score_continuous +4.71 closer. Mechanism: wrong control type → wrong elsewhere off-hours per Table 9 → MIT_elsewhere over by +0.5 °C → over-counted SH. |
|
||||
| **S0380.88** | `1b3bbbf7` | SAP 10.2 Table 4e (PDF p.171-174) all 8 groups | Introduced `UnmappedSapCode(ValueError)` strict-raise. Extended `_CONTROL_TYPE_BY_CODE` to all 40 codes (Groups 0-7). Corpus audit closed 3 silent mis-classifications (codes 2307, 2401, 2603). |
|
||||
| **S0380.89** | `6d02d205` | SAP 10.2 Table 4d (PDF p.170) | **Fixed a latent bug**: `_responsiveness` had `if emitter == 2: return 0.25` — treating screed UFH as concrete-slab UFH. Spec is R=0.75 (3× under-spec). Bug was latent because `_first_main_heating` picks main[0] and all cohort+golden certs lodge radiators (emitter=1) on main[0]. |
|
||||
| **S0380.90** | `9bfb8524` | Bundled 6 dispatch-site closures | `_pv_pitch_deg`, `_pv_overshading_factor`, `tariff_from_meter_type`, `_tariff_high_low_rates_p_per_kwh`, `_heat_network_dlf`, `_secondary_heating_fraction_for_category` all flipped to strict-raise. `UnmappedSapCode` promoted to shared `domain/sap10_calculator/exceptions.py`. **Fixed a second latent bug**: GOV.UK API lodges `meter_type='2'` as digit-string on 125 golden certs — silently fell through to STANDARD via the str-dict miss; now routes via int-cast short-circuit. |
|
||||
|
||||
**Test baseline at HEAD `9bfb8524`:** 574 pass + 9 expected
|
||||
`test_sap_result_pin[000565-*]` fails. Pyright net-zero on every
|
||||
touched file. Cohort + golden + cert 9501 unaffected.
|
||||
|
||||
## Cert 000565 state (HEAD `9bfb8524`)
|
||||
|
||||
| Pin | Cascade | Worksheet | Δ | Cause |
|
||||
|---|---:|---:|---:|---|
|
||||
| **sap_score (int)** | **27** | 29 | **−2** | Remaining +1460 SH residual; closes when party-wall CF U=0.2 + ventilation gap close |
|
||||
| sap_score_continuous | 27.3534 | 28.5087 | −1.16 | Downstream of SH residual |
|
||||
| ecf | 5.5066 | 5.3866 | +0.12 | Downstream |
|
||||
| total_fuel_cost_gbp | 4784.29 | 4680.26 | +104 | Downstream |
|
||||
| co2_kg_per_yr | 6581.12 | 6447.63 | +133 | Downstream |
|
||||
| **space_heating_kwh** | **60468.18** | **59008.35** | **+1460** | Party-wall CF over-count + ventilation +27 W/K |
|
||||
| main_heating_fuel | 35569.52 | 34710.79 | +859 | Follows SH via 1/COP |
|
||||
| **hot_water_kwh** | **3755.03** | **3755.03** | **✓ 0 EXACT** | §4 cascade closed S0380.77..80 |
|
||||
| lighting | 1387.02 | 1384.84 | +2.19 | Sub-spec |
|
||||
| pumps_fans | 255.00 | 252.52 | +2.48 | MEV PCDB record missing |
|
||||
|
||||
### Cumulative closure across this session
|
||||
|
||||
| Pin | post-.84 | .85 | .86 | .87 | .88 | .89 | .90 |
|
||||
|---|---:|---:|---:|---:|---:|---:|---:|
|
||||
| sap_score | 26 | 24 | 23 | **27** | 27 | 27 | 27 |
|
||||
| sap_score_continuous | 26.50 | 23.94 | 22.64 | 27.35 | 27.35 | 27.35 | 27.35 |
|
||||
| space_heating_kwh | +2591 | +6348 | +7924 | **+1460** | +1460 | +1460 | +1460 |
|
||||
| cascade walls W/K | 443 | 555.93 | **602.40** | 602.40 | 602.40 | 602.40 | 602.40 |
|
||||
|
||||
S0380.85+.86 closed the BP main-wall cascade gap (walls 443 → 602
|
||||
W/K, worksheet 604). Per [[feedback-verify-handover-claims]] the
|
||||
predicted SH closure didn't materialise — instead exposed a separate
|
||||
+8 k kWh SH-channel over-count that S0380.87 traced to a single-line
|
||||
spec dispatch bug. S0380.88-90 forecloses that bug pattern across the
|
||||
calculator.
|
||||
|
||||
## Why the BP-wall slices made SH "worse" before S0380.87 fixed it
|
||||
|
||||
Per the diagnosis at the end of S0380.86:
|
||||
|
||||
- Pre-S0380.84: cascade walls 322 (under by 282) + party 153 (over
|
||||
by 88) ≈ cancelled at HTC level. SH residual ~0.
|
||||
- Post-S0380.84: party fixed, walls still under. Cascade HTC under.
|
||||
But SH cascade was OVER worksheet — meaning a separate non-fabric
|
||||
SH-channel over-count was masked by the wall under-count.
|
||||
- Each spec-correct +1 W/K of cascade walls added ~33.5 kWh of cascade
|
||||
SH (consistent ratio across .85/.86/.87). Closing wall under-count
|
||||
exposed the SH-channel over-count fully.
|
||||
- S0380.87 traced it: cert 000565 main_heating_control=2207 (HP zone
|
||||
control) silently mapped to type 2 instead of type 3 → wrong
|
||||
elsewhere off-hours → MIT_elsewhere +0.5 °C → SH +4500 kWh.
|
||||
|
||||
## Strict-raise series (S0380.88..90) — calculator philosophy change
|
||||
|
||||
User mandate ("we keep debugging silent fallbacks") prompted the
|
||||
strict-raise rollout. New module:
|
||||
|
||||
`domain/sap10_calculator/exceptions.py` — `UnmappedSapCode(ValueError)`.
|
||||
|
||||
Mirror of mapper-side `UnmappedApiCode` / `UnmappedElmhurstLabel`.
|
||||
**Principle:** distinguish "lodging absent" (None / 0 / "" — cascade
|
||||
default OK per RdSAP §6.2.3 "assume as-built") from "lodging present
|
||||
but unmapped" (raise so spec-coverage gap surfaces at test time).
|
||||
Strict-raise applies to CODE DISPATCH sites; VALUE defaults (u_wall,
|
||||
u_floor, ...) remain total per cascade-helper docstring.
|
||||
|
||||
Eight dispatch sites flipped:
|
||||
|
||||
1. `_control_type` (S0380.87 → .88)
|
||||
2. `_responsiveness` (S0380.89 — fixed bug)
|
||||
3. `_pv_pitch_deg` (S0380.90)
|
||||
4. `_pv_overshading_factor` (S0380.90)
|
||||
5. `tariff_from_meter_type` (S0380.90 — fixed bug)
|
||||
6. `_tariff_high_low_rates_p_per_kwh` (S0380.90)
|
||||
7. `_heat_network_dlf` (S0380.90)
|
||||
8. `_secondary_heating_fraction_for_category` (S0380.90)
|
||||
|
||||
Both latent bugs (S0380.89 + S0380.90) were exclusively surfaced by
|
||||
the strict-raise rollout — corpus audit caught the dispatch coverage
|
||||
gaps that would otherwise have stayed silent.
|
||||
|
||||
## Open work — prioritised next slices
|
||||
|
||||
### S0380.91 — `u_party_wall` Table 15 row 3 "Cavity masonry filled"
|
||||
|
||||
**Highest-leverage remaining single-cause closure for cert 000565.**
|
||||
|
||||
Per RdSAP 10 §5.10 Table 15 (PDF p.42) "U-values of party walls":
|
||||
|
||||
Party wall type U
|
||||
------------------------------ ----
|
||||
Solid masonry / timber / system 0.0
|
||||
Cavity masonry unfilled 0.5
|
||||
Cavity masonry filled 0.2 ← cert 000565 Ext1 lodges CF
|
||||
Unknown, house 0.25
|
||||
Unknown, flat / maisonette 0.0
|
||||
|
||||
The current `u_party_wall` at
|
||||
[`domain/sap10_ml/rdsap_uvalues.py:1022`](../../sap10_ml/rdsap_uvalues.py)
|
||||
does not have a CF (Cavity masonry filled) branch — both CU (unfilled)
|
||||
and CF (filled) currently route to U=0.5. Spec value for CF is **0.2**.
|
||||
|
||||
Cert 000565 Ext1 lodges `Party Wall Type CF Cavity masonry filled`;
|
||||
the cascade over-counts party_wall by `(0.5 - 0.2) × Ext1_party_area
|
||||
≈ +28 W/K`. At the cascade rate of ~33.5 kWh per W/K, this maps to
|
||||
**~+1000 kWh of the remaining +1460 SH residual**.
|
||||
|
||||
The existing mapper at `datatypes/epc/domain/mapper.py:2196` already
|
||||
maps `"CF"` → SAP10 code 4 (Cavity) — same as CU — and the comment
|
||||
already flags this as a known approximation since S0380.64:
|
||||
|
||||
> CF: 4, # Cavity masonry filled (cert 000565 Ext1) — RdSAP 10
|
||||
> # Table 15 row 3 spec U=0.20. The cascade's `u_party_wall`
|
||||
> # only returns 0.0 / 0.5 / 0.25 for code 4 today, so CF
|
||||
> # rounds up to the conservative cavity-unfilled U=0.5 —
|
||||
> # matches the existing `_API_PARTY_WALL_CONSTRUCTION_TO
|
||||
> # _SAP10[3]` approximation until u_party_wall gains the
|
||||
> # filled-cavity branch (TODO).
|
||||
|
||||
**Slice span:**
|
||||
1. Need a way to distinguish CF from CU in `u_party_wall` — currently
|
||||
the function takes a single `party_wall_construction` int. The
|
||||
Elmhurst mapper collapses both to code 4. Need either:
|
||||
- New `party_wall_insulation_type` parameter (filled / unfilled)
|
||||
- Or a new wall_construction int specifically for CF (e.g. 11)
|
||||
- Or a separate cert-side "party_wall_filled: bool" field
|
||||
|
||||
The cleanest is option 2 (new wall_construction int) since it
|
||||
parallels the existing WALL_CAVITY=4 convention.
|
||||
|
||||
2. Cohort + golden audit for party-wall CF lodgings — only cert 000565
|
||||
Ext1 in the cohort has CF; golden API enum has its own party_wall
|
||||
_construction enum at `_API_PARTY_WALL_CONSTRUCTION_TO_SAP10[3]`
|
||||
which is also CF-aware per the comment (currently rounds to U=0.5).
|
||||
|
||||
**Expected outcome:** cert 000565 SH residual **+1460 → ~+460 kWh**;
|
||||
sap_score 27 → 28 (or 29 depending on continuous SAP rounding).
|
||||
|
||||
### S0380.92+ — remaining smaller residuals
|
||||
|
||||
After S0380.91 the cascade should be within ~+500 kWh SH. Open
|
||||
work-items per [[project-cert-000565-recovery-state]] memory:
|
||||
|
||||
- Ventilation infiltration +27 W/K over worksheet (~+900 kWh SH)
|
||||
— RdSAP 10 §5.15 / SAP 10.2 §3 line refs (24)..(25)
|
||||
- Doors 0 vs worksheet ~21 W/K (cascade missing doors entirely?)
|
||||
- Lighting +2.19 / pumps_fans +2.48 (sub-spec / MEV PCDB gap)
|
||||
|
||||
### Deferred (unchanged from earlier handovers)
|
||||
|
||||
- MEV PCDB Table 4f component for pumps_fans +2.5 (blocked on external
|
||||
data acquisition)
|
||||
- HP SAP code → main_heating_category=4 mapper extension
|
||||
- 12 gas-combi PV certs at +0.5..+1.6 PE (no worksheets)
|
||||
- 5 SAP-residual API-only certs (no worksheets)
|
||||
|
||||
## How to run the baseline
|
||||
|
||||
```bash
|
||||
PYTHONPATH=/workspaces/model python -m pytest \
|
||||
backend/documents_parser/tests/test_summary_pdf_mapper_chain.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_appendix_h_solar.py \
|
||||
domain/sap10_calculator/rdsap/tests/test_cert_to_inputs.py \
|
||||
domain/sap10_calculator/rdsap/tests/test_golden_fixtures.py \
|
||||
--no-cov -q
|
||||
```
|
||||
|
||||
Expected: **574 pass + 9 expected `test_sap_result_pin[000565-*]` fails**.
|
||||
|
||||
The 9 expected fails (verbatim):
|
||||
```
|
||||
sap_score
|
||||
sap_score_continuous
|
||||
ecf
|
||||
total_fuel_cost_gbp
|
||||
co2_kg_per_yr
|
||||
space_heating_kwh_per_yr
|
||||
main_heating_fuel_kwh_per_yr
|
||||
lighting_kwh_per_yr
|
||||
pumps_fans_kwh_per_yr
|
||||
```
|
||||
|
||||
## Files touched this session
|
||||
|
||||
| File | Slices | Change |
|
||||
|---|---|---|
|
||||
| `backend/documents_parser/elmhurst_extractor.py` | .85 | `Curtain Wall Age` extraction in `_wall_details_from_lines` |
|
||||
| `backend/documents_parser/tests/test_summary_pdf_mapper_chain.py` | .85, .86 | 5 new tests (extractor + mapper + cascade pins) |
|
||||
| `datatypes/epc/surveys/elmhurst_site_notes.py:WallDetails` | .85 | `curtain_wall_age: Optional[str] = None` |
|
||||
| `datatypes/epc/domain/epc_property_data.py` | .85, .86 | `SapBuildingPart.curtain_wall_age`; `SapAlternativeWall.wall_thickness_mm` |
|
||||
| `datatypes/epc/domain/mapper.py` | .85, .86 | Plumb new fields through `_map_elmhurst_building_part` + `_map_elmhurst_alternative_wall` (also rename `wall_insulation_thickness` mis-route → `wall_thickness_mm`) |
|
||||
| `domain/sap10_ml/rdsap_uvalues.py` | .85, .86 | `_u_curtain_wall` helper (§5.18); `_u_stone_thin_wall_age_a_to_e` helper (§5.6); `u_wall` dispatch extended with both branches |
|
||||
| `domain/sap10_calculator/worksheet/heat_transmission.py` | .85, .86 | Pass `curtain_wall_age=part.curtain_wall_age` and `wall_thickness_mm=alt_wall.wall_thickness_mm` to `u_wall` |
|
||||
| `domain/sap10_calculator/rdsap/cert_to_inputs.py` | .87..90 | Full Table 4e GROUP 2 dispatch (.87) + full Groups 0-7 + strict raise (.88) + Table 4d screed-UFH bug fix + strict raise (.89) + 5 dispatch helpers strict-raise (.90); `UnmappedSapCode` import from shared module |
|
||||
| `domain/sap10_calculator/exceptions.py` | .90 | **NEW** — `UnmappedSapCode(ValueError)` shared exception class |
|
||||
| `domain/sap10_calculator/tables/table_12a.py` | .90 | `tariff_from_meter_type` strict-raise + digit-string int-cast fix |
|
||||
| `domain/sap10_calculator/rdsap/tests/test_cert_to_inputs.py` | .87..90 | 13 new tests across the strict-raise series |
|
||||
| `domain/sap10_ml/tests/test_rdsap_uvalues.py` | .85, .86 | 8 new tests (Curtain Wall 3-test set + thin-wall stone 5-test set) |
|
||||
|
||||
## Spec source quick-reference
|
||||
|
||||
- **SAP 10.2 full specification**: `domain/sap10_calculator/docs/specs/sap-10-2-full-specification-2025-03-14.pdf`
|
||||
- Table 4d (p.170) — heat emitter responsiveness R
|
||||
- Table 4e (p.171-174) — heating system controls (Groups 0-7)
|
||||
- Table 9 (p.182) — heating periods + temperatures
|
||||
- Table 9b (p.183) — off-period temperature reduction formula
|
||||
- Table 11 (p.188) — secondary-heating fraction by main category
|
||||
- Table 12c (p.193) — heat-network distribution loss factor
|
||||
- Table M1 — PV overshading factor ZPV
|
||||
- **RdSAP 10 specification**: `domain/sap10_calculator/docs/specs/RdSAP 10 Specification 10-06-2025.pdf`
|
||||
- §5.6 Table 12 (p.40) — uninsulated stone wall thin-wall formula
|
||||
- §5.8 + Table 14 (p.40-41) — dry-line + insulation R-value
|
||||
- §5.10 Table 15 (p.42) — party-wall U-values (S0380.91 target)
|
||||
- §5.18 (p.48) — curtain wall U-values
|
||||
- §11.1 — PV pitch enum
|
||||
- **SAP 10.3 at** `domain/sap10_calculator/docs/specs/sap-10-3-full-specification-2026-01-13.pdf`: **DO NOT reference** ([[feedback-sap-10-2-only-never-10-3]])
|
||||
|
||||
## Memory updated this session
|
||||
|
||||
- `project_cert_000565_recovery_state` — slice-by-slice closure table
|
||||
for .85..87 + SH-channel diagnosis
|
||||
- `reference_unmapped_sap_code` — **NEW** memory documenting the
|
||||
strict-raise pattern + which dispatch sites are now closed
|
||||
- `project_sap10_ml_deprecation` — **NEW** memory recording the
|
||||
user-requested folder deprecation (any new cascade helpers should
|
||||
land under `domain/sap10_calculator/` not `domain/sap10_ml/`)
|
||||
- `MEMORY.md` — index refreshed at HEAD `9bfb8524`
|
||||
200
domain/sap10_calculator/docs/NEXT_AGENT_PROMPT_POST_S0380_90.md
Normal file
200
domain/sap10_calculator/docs/NEXT_AGENT_PROMPT_POST_S0380_90.md
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
# Next-agent prompt — post S0380.85..90
|
||||
|
||||
Branch: `feature/per-cert-mapper-validation`.
|
||||
HEAD: `9bfb8524`.
|
||||
|
||||
Read these in order before any tool call:
|
||||
|
||||
1. [`HANDOVER_POST_S0380_90.md`](HANDOVER_POST_S0380_90.md) — full state
|
||||
2. [`HANDOVER_POST_S0380_84.md`](HANDOVER_POST_S0380_84.md) — predecessor (background)
|
||||
|
||||
Also load these memories before starting:
|
||||
|
||||
- `project_cert_000565_recovery_state` — slice history + per-pin state
|
||||
- `reference_unmapped_sap_code` — calculator strict-raise pattern
|
||||
- `project_sap10_ml_deprecation` — `domain/sap10_ml/` is marked for
|
||||
migration; new cascade helpers should land under
|
||||
`domain/sap10_calculator/`
|
||||
- `feedback_sap_10_2_only_never_10_3` — **CRITICAL** — never reference
|
||||
SAP 10.3 spec
|
||||
- `feedback_spec_citation_in_commits` — quote spec text + page in
|
||||
commit messages
|
||||
- `feedback_verify_handover_claims` — verify spec citations + numeric
|
||||
claims before implementing the prescribed fix
|
||||
- `feedback_zero_error_strict` — pyright net-zero per touched file
|
||||
- `feedback_commit_per_slice` — one slice = one commit
|
||||
- `feedback_aaa_test_convention` — every new test uses literal
|
||||
`# Arrange / # Act / # Assert` headers
|
||||
- `feedback_e2e_validation_philosophy` — component pins at <1e-3;
|
||||
SAP integer delta=0; no adaptive ceilings
|
||||
- `feedback_no_misleading_insulation_type` — field names should reflect
|
||||
what they semantically contain
|
||||
|
||||
## State summary
|
||||
|
||||
This session shipped **S0380.85..90** — six spec-cited slices that:
|
||||
|
||||
1. Closed both named BP main-wall gaps (Curtain Wall §5.18 + thin-wall
|
||||
stone §5.6/§5.8). Cascade walls 443 → 602.40 W/K (worksheet 604.07;
|
||||
0.27% residual).
|
||||
2. **Surfaced and fixed the dominant SH-channel over-count** via
|
||||
S0380.87 — HP control code 2207 silently routed to control type 2
|
||||
instead of spec type 3. SH residual closed +7924 → **+1460 kWh
|
||||
(82%)**, sap_score 23 → 27.
|
||||
3. **Forecloses the silent-fallback bug pattern across the calculator**
|
||||
via S0380.88-90 strict-raise series. 8 cascade-dispatch sites now
|
||||
raise `UnmappedSapCode` on unmapped codes instead of silently
|
||||
defaulting. Two latent bugs were surfaced as a side-effect:
|
||||
- emitter=2 (Underfloor in screed) was returning R=0.25 instead of
|
||||
spec R=0.75
|
||||
- GOV.UK API digit-string `meter_type='2'` silently fell through to
|
||||
STANDARD on 125 golden certs
|
||||
|
||||
**Cert 000565 state at HEAD `9bfb8524`:**
|
||||
|
||||
| Pin | Cascade | Worksheet | Δ |
|
||||
|---|---:|---:|---:|
|
||||
| sap_score | 27 | 29 | −2 |
|
||||
| sap_score_continuous | 27.3534 | 28.5087 | −1.16 |
|
||||
| space_heating_kwh | 60468.18 | 59008.35 | **+1460** |
|
||||
| hot_water_kwh | 3755.03 | 3755.03 | ✓ 0 EXACT |
|
||||
| (others) | various | various | downstream |
|
||||
|
||||
## Recommended next slice — S0380.91 Party-wall CF Cavity-masonry-filled
|
||||
|
||||
**Highest-leverage remaining single-cause closure for cert 000565.**
|
||||
|
||||
Per RdSAP 10 §5.10 Table 15 (PDF p.42) "U-values of party walls":
|
||||
|
||||
Party wall type U
|
||||
------------------------------ ----
|
||||
Solid masonry / timber / system 0.0
|
||||
Cavity masonry unfilled 0.5
|
||||
Cavity masonry filled **0.2** ← cert 000565 Ext1 lodges CF
|
||||
Unknown, house 0.25
|
||||
Unknown, flat / maisonette 0.0
|
||||
|
||||
### Audit steps
|
||||
|
||||
1. Read RdSAP 10 §5.10 Table 15 (PDF p.42) for the spec text + footnote.
|
||||
2. Read `u_party_wall` at
|
||||
[`domain/sap10_ml/rdsap_uvalues.py:1018`](../../sap10_ml/rdsap_uvalues.py).
|
||||
Current signature takes `(party_wall_construction, is_flat=False)`.
|
||||
For code 4 (Cavity) it returns U=0.5 (unfilled). No CF branch.
|
||||
3. Read the comment at
|
||||
[`datatypes/epc/domain/mapper.py:2196`](../../../datatypes/epc/domain/mapper.py)
|
||||
(Elmhurst mapper) which already flags this as a known approximation
|
||||
since S0380.64. CF currently routes to SAP10 code 4 (same as CU).
|
||||
4. Probe cert 000565 Ext1's `party_wall_construction` value in the
|
||||
built EPC — confirm it's lodged as code 4.
|
||||
|
||||
### Suggested implementation
|
||||
|
||||
The cleanest fix introduces a way to distinguish CF from CU. Options:
|
||||
|
||||
**Option A** (recommended): new wall_construction int specifically for
|
||||
CF — e.g. `WALL_CAVITY_FILLED_PARTY = 11`. Add to `u_party_wall`
|
||||
dispatch returning 0.2. Update both Elmhurst mapper
|
||||
(`_ELMHURST_PARTY_WALL_CODE_TO_SAP10["CF"]: 11`) and API mapper
|
||||
(`_API_PARTY_WALL_CONSTRUCTION_TO_SAP10[3]: 11`).
|
||||
|
||||
**Option B**: add a new optional parameter `is_cavity_filled: bool` to
|
||||
`u_party_wall`. Plumb through `heat_transmission.py`. More invasive
|
||||
but doesn't add a new code.
|
||||
|
||||
Per [[reference-unmapped-sap-code]] strict-raise pattern, the new code
|
||||
must be added to any party-wall dispatch dict (e.g. if other helpers
|
||||
gate on `party_wall_construction`).
|
||||
|
||||
### Slice span
|
||||
|
||||
1. `domain/sap10_ml/rdsap_uvalues.py:u_party_wall` — add CF branch
|
||||
(Option A: new code 11; Option B: new param)
|
||||
2. `datatypes/epc/domain/mapper.py` — update both mapper dispatches
|
||||
to route "CF" / API "Filled" to the new representation
|
||||
3. New tests in
|
||||
`domain/sap10_ml/tests/test_rdsap_uvalues.py` —
|
||||
- `u_party_wall_cavity_masonry_filled_returns_0p2_per_rdsap_10_table_15_row_3`
|
||||
- `u_party_wall_cavity_masonry_unfilled_returns_0p5_per_rdsap_10_table_15_row_2`
|
||||
4. Cascade pin test in
|
||||
`backend/documents_parser/tests/test_summary_pdf_mapper_chain.py` —
|
||||
- `test_summary_000565_ext1_party_wall_cf_routes_to_u_value_0p2`
|
||||
|
||||
### Expected outcome
|
||||
|
||||
- cert 000565 cascade party_walls: 93.26 → ~65 W/K (worksheet 65.13)
|
||||
- cert 000565 SH residual: +1460 → ~+460 kWh
|
||||
- sap_score 27 → 28 (possibly 29 depending on continuous SAP rounding)
|
||||
- Continuous SAP residual: −1.16 → ~−0.4
|
||||
|
||||
### Audit risk
|
||||
|
||||
- Cohort + golden audit: only cert 000565 Ext1 lodges CF in the cohort.
|
||||
- Need to scan corpus for `party_wall_construction` values 3 ("Filled
|
||||
cavity" in API enum) on golden + corpus to catch any cert that
|
||||
changes when CF→0.2.
|
||||
|
||||
## Beyond S0380.91 — remaining cert 000565 work-items
|
||||
|
||||
After S0380.91 the cert 000565 cascade should be within ~+500 kWh SH.
|
||||
Open items:
|
||||
|
||||
- Ventilation infiltration +27 W/K over worksheet (~+900 kWh SH) —
|
||||
RdSAP 10 §5.15 / SAP 10.2 §3 line refs (24)..(25)
|
||||
- Doors cascade missing entirely (cascade 0 vs worksheet ~21 W/K) —
|
||||
check `door_count` plumbing for cert 000565
|
||||
- Lighting +2.19, pumps_fans +2.48 — sub-spec / MEV PCDB gap (deferred)
|
||||
|
||||
## Standard workflow per slice
|
||||
|
||||
1. Read SAP 10.2 / RdSAP 10 spec page for the change — quote it in commit
|
||||
2. Probe current cascade output; identify exact spec-vs-cascade gap
|
||||
3. Write failing test FIRST (AAA structure)
|
||||
4. Implement helper / change
|
||||
5. Verify test passes
|
||||
6. Run full handover suite (command in handover)
|
||||
7. Check pyright on touched files — net-zero from baseline
|
||||
8. Commit with spec citation
|
||||
9. Update relevant memory if state changed
|
||||
|
||||
## How to run the baseline
|
||||
|
||||
```bash
|
||||
PYTHONPATH=/workspaces/model python -m pytest \
|
||||
backend/documents_parser/tests/test_summary_pdf_mapper_chain.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_appendix_h_solar.py \
|
||||
domain/sap10_calculator/rdsap/tests/test_cert_to_inputs.py \
|
||||
domain/sap10_calculator/rdsap/tests/test_golden_fixtures.py \
|
||||
--no-cov -q
|
||||
```
|
||||
|
||||
Expected: **574 pass + 9 expected `test_sap_result_pin[000565-*]` fails**.
|
||||
|
||||
After S0380.91 lands the expected fail count should drop (sap_score
|
||||
likely closes to EXACT or Δ−1; SH residual closes by ~1000 kWh; other
|
||||
downstream pins move with it).
|
||||
|
||||
## What NOT to do
|
||||
|
||||
- **Don't reference SAP 10.3** ([[feedback-sap-10-2-only-never-10-3]]).
|
||||
- **Don't widen pin tolerances or xfail residual gaps**
|
||||
([[feedback-zero-error-strict]]). The 9 cert 000565 fails are the work queue.
|
||||
- **Don't re-investigate Curtain Wall (§5.18), thin-wall stone (§5.6/§5.8),
|
||||
control codes (Table 4e), emitter codes (Table 4d)**, or any of the
|
||||
6 strict-raise dispatches. All closed in S0380.85..90.
|
||||
- **Don't add new helpers to `domain/sap10_ml/`** — that folder is on
|
||||
the deprecation path per [[project-sap10_ml-deprecation]]. New cascade
|
||||
helpers should land under `domain/sap10_calculator/`.
|
||||
- **Don't chase the 12 gas-combi PV certs or the 5 SAP-residual certs
|
||||
without worksheets** — user has explicitly de-prioritised.
|
||||
|
||||
## Memory hygiene
|
||||
|
||||
After the next slice, update:
|
||||
- `project_cert_000565_recovery_state` — append S0380.91 closure +
|
||||
refresh the open work-items table
|
||||
|
||||
Good luck.
|
||||
Loading…
Add table
Reference in a new issue