mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Handover: TDD red-green session — 4 more slices (58-60) + RED chain pin
Update NEXT_AGENT_PROMPT.md for the TDD session that landed 3 more
slices on top of Session 1's fabric work:
58: secondary fuel cost routes through lodged secondary_fuel_type
(closes the biggest single gap on cert 001479 — 9 SAP)
59: heat_transmission apportions windows per bp via window_location
60: thermal bridging y uses primary bp's age (dwelling-wide)
Chain pin `test_summary_001479_full_chain_sap_matches_worksheet_pdf_
exactly` is committed RED as the load-bearing TDD forcing function:
Pre-workstream: delta +5.84 SAP (cascade 63.17 vs target 69.0094)
Post-Slice 60: delta −1.19 SAP (cascade 70.20 vs target 69.0094)
Per-bp fabric U-values all match the worksheet exactly. Remaining
1.19 SAP overshoot maps to ~3 W/K of HLC undercount in roof + floor:
- Ext2 PS sloping-ceiling roof area uses floor projection (1.92 m²)
instead of slant area (2.22 m²). −0.81 W/K.
- Main ground-floor U: `u_floor` Table 19 returns 0.60 for age C;
worksheet expects 0.65 (same as age B). −1.52 W/K.
- (31) external area under-count drives bridging gap. −2.08 W/K.
Slice 61 (SapFloorDimension.floor_lodged_u_value override using
Summary §9 "Default U-value") was attempted and reverted: closed
001479 floor gap exactly but broke 000474 cohort's 1e-4 pin (its
cascade calibration uses u_floor age-B 0.77 vs Summary's lodged
0.75). Next session needs a different fix — Table 19 audit for
age C, or selective override.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
31c01a7e8c
commit
0e4f4c051a
1 changed files with 104 additions and 92 deletions
|
|
@ -232,126 +232,138 @@ For the new workflow, you'll want a probe that:
|
|||
## Branch state at handover
|
||||
|
||||
```
|
||||
$ git log --oneline -8
|
||||
$ git log --oneline -10
|
||||
31c01a7e Slice 60: thermal bridging y is dwelling-wide, not per-bp
|
||||
175873b4 Slice 59: heat_transmission apportions window area per bp via window_location
|
||||
e3dc0b28 Slice 58: secondary fuel cost routes through lodged secondary_fuel_type
|
||||
a0d9d094 Handover: 4 cert-001479 slices in (54-57); gap at +7.62 SAP; non-fabric next
|
||||
7a9a8b7e Slice 57: Pre-1950 Elmhurst sloping-ceiling roofs map to thickness=0
|
||||
07ed871f Slice 56: Elmhurst floor exposed to external air routes through u_exposed_floor
|
||||
c89206fc Slice 55: Elmhurst party-wall code "CU" maps to cavity unfilled
|
||||
4427b58a Slice 54: Elmhurst mapper sets extensions_count from len(survey.extensions)
|
||||
a756114a Handover: all 6 Elmhurst Summary→SAP chains closed at 1e-4
|
||||
58088c10 Slice 53: Summary_000487 chain pins SAP at 1e-4 — last cohort cert closed
|
||||
4ccf9c97 Slice 52: Summary_000477 chain pins SAP at 1e-4; electric shower + decimal RIR rounding
|
||||
cb4e31a1 Slice 51: Summary_000516 chain pins SAP at 1e-4; roof-window separation
|
||||
```
|
||||
|
||||
758 cohort + cert-001479 structural tests green; pyright net-zero
|
||||
(35 baseline) on touched files.
|
||||
Chain pin `test_summary_001479_full_chain_sap_matches_worksheet_pdf_
|
||||
exactly` is committed RED (cascade SAP 70.20 vs worksheet 69.0094,
|
||||
delta 1.19) as the load-bearing TDD forcing function. All other
|
||||
chain + golden + heat-transmission tests pass. Pyright net-zero on
|
||||
touched files.
|
||||
|
||||
## Resumption notes for cert 001479 (Slices 54–57 partial progress)
|
||||
## Resumption notes for cert 001479 (Slices 54–60 in; chain pin RED at delta 1.19)
|
||||
|
||||
### What landed
|
||||
Four mapper slices closed real Elmhurst-side gaps that surfaced when
|
||||
the cross-mapper diff against the new API counterpart was run for
|
||||
the first time:
|
||||
### What landed across two sessions
|
||||
|
||||
- **Slice 54** — `extensions_count` now reads `len(survey.extensions)`
|
||||
instead of the hard-coded `0`. No SAP impact (the cascade iterates
|
||||
`sap_building_parts`), but a real correctness fix the cross-mapper
|
||||
parity assertion needs.
|
||||
- **Slice 55** — Elmhurst party-wall code `"CU"` (Cavity masonry
|
||||
unfilled) now maps to SAP10 `WALL_CAVITY=4`; `u_party_wall` returns
|
||||
0.5 W/m²K matching the worksheet's lodged `Party walls Main … 0.50`.
|
||||
- **Slice 56** — Floor location `"E To external air"` now routes
|
||||
through `u_exposed_floor` (Table 20), matching cert 001479 Ext2's
|
||||
cantilevered exposed timber floor at U=1.20.
|
||||
- **Slice 57** — PS (Pitched, sloping ceiling) roofs with no lodged
|
||||
thickness ("As Built") and age band A-D map to `thickness=0`,
|
||||
giving Table 16 row-0 U=2.30 — matches cert 001479 Ext2's worksheet
|
||||
`External roof Ext2 … 2.30`. Ext1 (age M) keeps thickness=None
|
||||
→ cascade default 0.15.
|
||||
**Session 1** (Slices 54-57): fabric mapper gaps from the cross-mapper diff.
|
||||
|
||||
- **Slice 54** — `extensions_count` reads `len(survey.extensions)`.
|
||||
- **Slice 55** — Elmhurst party-wall code `"CU"` → `WALL_CAVITY=4`
|
||||
(U=0.5 matching worksheet's `Party walls Main … 0.50`).
|
||||
- **Slice 56** — Floor location `"E To external air"` routes through
|
||||
`u_exposed_floor` (Ext2 cantilevered floor at U=1.20).
|
||||
- **Slice 57** — PS sloping-ceiling roofs at age A-D with "As Built"
|
||||
thickness map to `thickness=0` → U=2.30 (Ext2 uninsulated roof).
|
||||
|
||||
**Session 2** (Slices 58-60): TDD red-green cycle with the chain pin as
|
||||
forcing function. Two cascade-level fixes + one mapper fix:
|
||||
|
||||
- **Slice 58** — Secondary fuel cost routing. Mapper derives
|
||||
`secondary_fuel_type=26` (mains gas) from SAP code 605; cascade
|
||||
`_fuel_cost` reads `secondary_fuel_type` instead of hardcoding the
|
||||
electric tariff. Closes a £175/yr ECF distortion ≈ **9 SAP** on
|
||||
cert 001479. Golden cert 0300-2747 (also mains-gas secondary)
|
||||
tightens SAP residual −7 → +2 — biggest single golden improvement.
|
||||
- **Slice 59** — `heat_transmission_from_cert` apportions window
|
||||
area per `window_location` to each bp's wall deduction (was all-to-
|
||||
Main). For 001479 Ext1's 6.37 m² window now correctly cuts into
|
||||
Ext1's wall (U=0.26) instead of Main's (U=0.70). Three golden
|
||||
certs (6035, 7536, 8135) with non-Main windows tighten all
|
||||
residuals; cohort certs unaffected (uniform per-bp wall U).
|
||||
- **Slice 60** — Thermal bridging `y` is dwelling-wide (primary bp's
|
||||
age band) rather than per-bp. Multi-age dwellings like 001479
|
||||
(Main=C, Ext1=M, Ext2=C) and golden 7536 (D, L, F) had Ext1
|
||||
bridging under-counted at y=0.08 instead of dwelling's y=0.15.
|
||||
|
||||
**Slice 61 ATTEMPTED + REVERTED**: `SapFloorDimension.floor_lodged_
|
||||
u_value` override using Elmhurst Summary §9 "Default U-value". The
|
||||
override matched 001479's worksheet exactly (Main 0.65, Ext1 0.20,
|
||||
Ext2 1.20) but broke cohort 000474's 1e-4 pin: that cert's cascade
|
||||
calibration relied on `u_floor` returning 0.77 for age B + 12.68 m²,
|
||||
while Summary lodges 0.75. The 0.02 U drift × 12.68 m² shifted SAP
|
||||
beyond 1e-4. **Next session needs a different approach** — either
|
||||
fix `u_floor` Table 19 cascade for age C (currently 0.60, should be
|
||||
0.65) without breaking age B, or selectively apply the override.
|
||||
|
||||
### Where the chain stands
|
||||
|
||||
Mapped Elmhurst cascade for cert 001479:
|
||||
- Pre-Slice 54: SAP 63.17 vs worksheet 69.0094 (gap +5.84)
|
||||
- Post-Slice 57: SAP **61.39** vs worksheet 69.0094 (gap **+7.62**)
|
||||
| Cascade SAP | Delta to 69.0094 | After |
|
||||
|---|---|---|
|
||||
| 63.17 | +5.84 | Initial (pre-this-workstream) |
|
||||
| 61.39 | +7.62 | Post-Slice 57 (fabric only) |
|
||||
| 70.64 | −1.63 | Post-Slice 58 (secondary fuel) |
|
||||
| 70.38 | −1.37 | Post-Slice 59 (window apportionment) |
|
||||
| **70.20** | **−1.19** | **Post-Slice 60 (single-y bridging)** |
|
||||
|
||||
Gap widened because each fix was per-data correct; the previous
|
||||
mapper state was under-counting fabric heat loss in multiple places
|
||||
that were collectively offsetting some over-counting elsewhere.
|
||||
Per-bp wall U-values now all match the worksheet exactly:
|
||||
The chain pin is committed RED at delta 1.19. **Per-bp fabric U-values
|
||||
all match worksheet exactly** (Main wall 0.70, Ext1 wall 0.26, Ext2
|
||||
wall 0.70, etc.). The remaining 1.19 SAP overshoot maps to ~3 W/K of
|
||||
extra HLC that the cascade is still under-counting:
|
||||
|
||||
| BP | Wall | Roof | Party | Floor |
|
||||
|---|---|---|---|---|
|
||||
| Main | 0.70 ✓ | 0.14 ✓ | 0.50 ✓ | 0.65 (ground cascade) |
|
||||
| Ext1 | 0.26 ✓ | 0.15 ✓ | n/a (pwl=0) | 0.20 |
|
||||
| Ext2 | 0.70 ✓ | **2.30 ✓** | n/a (pwl=0) | **1.20 exposed ✓** |
|
||||
| Line ref | Cascade | Worksheet | Gap |
|
||||
|---|---|---|---|
|
||||
| (29a) walls | 39.77 | 39.77 | ✓ |
|
||||
| (30) roof | 9.53 | 10.34 | −0.81 (Ext2 sloping-ceiling area) |
|
||||
| (28a) floor | 21.65 | 23.17 | −1.52 (Main floor U 0.60 vs 0.65) |
|
||||
| (32) party | 17.07 | 17.07 | ✓ |
|
||||
| (27) windows | 43.60 | 43.60 | ✓ |
|
||||
| (26) doors | 5.55 | 5.55 | ✓ |
|
||||
| (36) bridging | 22.27 | 24.35 | −2.08 (driven by (31) under-count) |
|
||||
| **(37) total** | **156.62** | **163.84** | **−7.22 W/K** |
|
||||
|
||||
Fabric is essentially complete. The remaining ~7.6 SAP gap lives in
|
||||
non-fabric inputs.
|
||||
### What likely closes the remaining 1.19 SAP
|
||||
|
||||
### What likely drives the remaining 7.6 SAP
|
||||
1. **`u_floor` Table 19 boundary for age C** (cascade returns 0.60;
|
||||
worksheet expects 0.65 — same as age B). May be a Table 19 row
|
||||
boundary miss. Need to read the canonical xlsx Sheet `Table 19`
|
||||
to confirm correct values. If cascade is wrong, fixing it would
|
||||
affect cohort but probably in the right direction.
|
||||
2. **Ext2 roof area for PS sloping ceiling** — cascade uses floor
|
||||
area (1.92) as roof area; worksheet uses 2.22 (slant length ×
|
||||
width). Factor ≈ 1.156 = sec(30°). Cascade-level: multiply
|
||||
gross_roof_area by an inclination factor when roof_type starts
|
||||
with "PS".
|
||||
3. **`(31)` total external area under-count** of 1.13 m² (drives the
|
||||
bridging gap). Probably the same Ext2 roof area issue (0.30 m²)
|
||||
plus other accumulations. Fix #2 likely closes most of this.
|
||||
|
||||
- **HLP check**: worksheet `HLP (average) 3.1269`; cascade
|
||||
total_w_per_k / TFA = 153.15 / 68.51 = **2.235** — cascade is
|
||||
under-counting total heat loss by ~61 W/K. Combined with cascade
|
||||
ventilation HLC (~46 W/K) gives total ~199 vs worksheet's expected
|
||||
~214 — gap ~15 W/K in non-fabric.
|
||||
- **Living area fraction**: cascade `0.25`, worksheet `0.28`. The
|
||||
worksheet computes 17.13/61.18 (Main TFA only?) vs cascade's
|
||||
17.13/68.51 (all bp TFA). SAP convention question — may need
|
||||
cascade-level fix.
|
||||
- **Internal gains**: cascade `lighting_kwh_per_yr=163` looks low for
|
||||
23 fittings; cascade `pumps_fans_kwh_per_yr=160` may differ from
|
||||
worksheet (which lodges main_heating_category=1).
|
||||
- **Secondary heating**: cascade has fraction=0.1, η=0.4 (matches
|
||||
worksheet). SAP code 605 (gas fire flush, sealed-flue) is not wired
|
||||
through; the cohort 000490 sets `secondary_heating_type` to a SAP
|
||||
code int — verify cert 001479 needs the same.
|
||||
- **PCDB boiler index 17507 (Worcester Greenstar 30i)** — cascade
|
||||
reads `main_heating_efficiency=0.89` (matches worksheet's 89%
|
||||
winter) so likely already resolved. Confirm.
|
||||
- **Per-window U vs avg-U routing**: cascade takes per-window U path
|
||||
(every window has `window_transmission_details`). Worksheet's
|
||||
windows use 2.80 U (default) — verify cascade matches.
|
||||
|
||||
### Source-data caveats found this session
|
||||
### Source-data caveats
|
||||
|
||||
- **Summary PDF vs worksheet age band on Ext1**: Summary §3 says
|
||||
`M 2023 onwards`; worksheet header says `Property Age Band C, Ext1: L,
|
||||
Ext2: C`. Likely assessor data-entry inconsistency. User decision:
|
||||
trust the Summary PDF (M); accept whatever residual the worksheet's
|
||||
L-based calc leaves. Document the caveat in the chain pin docstring
|
||||
when it lands.
|
||||
- **Worksheet "0.0" Type column on External Walls**: looks like an
|
||||
unused column header in Elmhurst's tabular output, not a
|
||||
shelter-factor input. Cascade ignores it correctly.
|
||||
Ext2: C`. Trust Summary (mapper does what data says); chain pin
|
||||
docstring documents the caveat.
|
||||
|
||||
### Probe scripts in /tmp (regenerable)
|
||||
|
||||
- `/tmp/probe_001479.py` — cross-mapper diff + cascade for both
|
||||
mappers; baseline for comparing API vs Elmhurst EpcPropertyData.
|
||||
- `/tmp/sensitivity_001479.py` — single-field patch SAP impact probe;
|
||||
useful for sequencing slices but stale after each commit (re-run).
|
||||
- `/tmp/perbp_001479.py` — per-bp cascade U-value dump vs worksheet
|
||||
expected values; the cleanest "is fabric matching?" check.
|
||||
- `/tmp/probe_001479.py` — cross-mapper diff + cascade.
|
||||
- `/tmp/sensitivity_001479.py` — single-field SAP impact probe.
|
||||
- `/tmp/perbp_001479.py` — per-bp cascade U-value dump vs worksheet.
|
||||
|
||||
Cached cert JSON is at `packages/domain/src/domain/sap/rdsap/tests/
|
||||
fixtures/golden/0535-9020-6509-0821-6222.json` (token-fetched once,
|
||||
no further API calls needed). Summary PDF copied into the chain-test
|
||||
fixtures dir.
|
||||
Cached cert JSON: `packages/domain/src/domain/sap/rdsap/tests/
|
||||
fixtures/golden/0535-9020-6509-0821-6222.json`. Summary PDF in the
|
||||
chain-test fixtures dir.
|
||||
|
||||
### Suggested next steps
|
||||
|
||||
1. Probe the cascade's section-by-section line refs (§3 walls, §3
|
||||
roofs, §3 windows, §3 thermal bridging, §2 ventilation HLC) against
|
||||
the worksheet text to find the ~15 W/K HLC gap.
|
||||
2. Check `living_area_fraction` SAP convention — Main-only vs whole-
|
||||
dwelling TFA. Cohort certs may have been single-bp so this
|
||||
convention difference didn't surface.
|
||||
3. Wire secondary heating SAP code through if a §14 worksheet line ref
|
||||
shows a different secondary contribution than the cascade.
|
||||
4. When the chain SAP is within ~0.1 of 69.0094, land the
|
||||
`test_summary_001479_full_chain_sap_matches_worksheet_pdf_exactly`
|
||||
pin at 1e-4 — that's the forcing function for the workstream.
|
||||
1. **`u_floor` Table 19 audit for age C suspended timber** — verify
|
||||
the cascade matches the canonical RdSAP10 / xlsx. Possible fix
|
||||
without breaking cohort 000474 (which is age B).
|
||||
2. **PS sloping-ceiling roof area inclination factor** — multiply
|
||||
`top_floor_area_m2` by `sec(pitch)` when roof_type is PS. Closes
|
||||
the (30) and (31) gaps simultaneously.
|
||||
3. When the chain pin is within ~0.001 of 69.0094, the RED test goes
|
||||
GREEN — workstream done. Then API ±0.5 pin (test_golden_fixtures
|
||||
_.py) and cross-parity test are the remaining workstreams.
|
||||
|
||||
Good luck.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue