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.96..103 (RIR Unknown + §9 floor + MEV PCDB arc + HP-on-E7 cost split)
8 slices shipped this session: S0380.96 RIR Unknown insulation (RdSAP 10 §3.10.1) S0380.97 Floor §9 insulation thickness (RdSAP 10 §5.13 Table 20) S0380.98 PCDB Table 322 ETL+parser (PCDF Spec §A.19) S0380.99 PCDB Table 329 ETL+parser (PCDF Spec §A.20) S0380.100 MEV SFPav + (230a) helpers (SAP 10.2 §2.6.4) S0380.101 HP SAP code → cat=4 mapper (SAP 10.2 Table 4a) S0380.102 Wire MEV into pumps_fans (SAP 10.2 Table 4f 230a) S0380.103 MEV-fan cost split (SAP 10.2 Table 12a Grid 2) Cert 000565 at HEAD `e3abe9b2`: sap_score (int) ✓ EXACT pumps_fans_kwh_per_yr ✓ EXACT (was +2.48 over) hot_water_kwh_per_yr ✓ 0 EXACT sap_score_continuous Δ +0.0182 (SH cascade-driven) 7 expected fails (was 9) Next slice candidate: S0380.104 investigate §3-§8 space-heating cascade -27 kWh under-count (cert-000565-specific; cohort certs pass at 1e-4). Alternative: S0380.105 CO2 MEV split (mirror of .103 for Table 12d monthly factors). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
e3abe9b2b5
commit
7df3fef8bb
2 changed files with 540 additions and 0 deletions
303
domain/sap10_calculator/docs/HANDOVER_POST_S0380_103.md
Normal file
303
domain/sap10_calculator/docs/HANDOVER_POST_S0380_103.md
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
# Handover — post S0380.96..103 (RIR Unknown + §9 floor extractor + MEV PCDB arc + HP-on-E7 cost split)
|
||||
|
||||
Branch: `feature/per-cert-mapper-validation`. **HEAD `e3abe9b2`**.
|
||||
Predecessor: [`HANDOVER_POST_S0380_95.md`](HANDOVER_POST_S0380_95.md).
|
||||
|
||||
## Slices committed this session (S0380.96..103)
|
||||
|
||||
Eight spec-cited slices. The first two closed remaining cert 000565
|
||||
extractor/mapper gaps (RIR "Unknown" insulation + floor §9
|
||||
"Insulation Thickness"). Slices .98..102 built the MEV PCDB
|
||||
decentralised cascade arc end-to-end (Tables 322 + 329 + SFPav
|
||||
formula + HP-category mapper + wiring). The final slice .103 closed
|
||||
the Table 12a Grid 2 MEV-fan cost split, completing the HP-on-E7
|
||||
cost cascade.
|
||||
|
||||
| Slice | Commit | Spec | Cert 000565 outcome |
|
||||
|---|---|---|---|
|
||||
| **S0380.96** | `32a4cf20` | RdSAP 10 §3.10.1 (PDF p.24) — "Unknown" insulation → Table 18 col 4 age-band default | BP[4] FC1 cascade U: 2.30 → **0.15 ✓ EXACT**. roof_w_per_k Δ +12.34 → +1.59 (closed -10.75). Continuous SAP Δ -0.44 → -0.20. |
|
||||
| **S0380.97** | `7121a86b` | RdSAP 10 §5.13 Table 20 (PDF p.47) — exposed/semi-exposed floor U by age × thickness | BP[2] Ext2 floor U: 0.51 → **0.22 ✓ EXACT**. floor_w_per_k **✓ EXACT**. **sap_score 28 → 29 ✓ EXACT**. Continuous SAP Δ -0.0001 (within 1e-4). |
|
||||
| **S0380.98** | `b3330821` | PCDF Spec Rev 6b §A.19 — PCDB Table 322 Format 427/428 | Foundation only. Typed parser + ETL + `decentralised_mev_record(pcdb_id)` lookup. 48 records ingested. No cascade integration. |
|
||||
| **S0380.99** | `433f4a49` | PCDF Spec Rev 6b §A.20 — PCDB Table 329 Format 430/432 | Foundation only. Typed parser + ETL + `mv_in_use_factors_record(system_type)`. 5 records ingested. No cascade integration. |
|
||||
| **S0380.100** | `44fb8c07` | SAP 10.2 §2.6.4 equation (1) + Table 4f line (230a) | New module `worksheet/mev.py` — `mev_sfp_av` + `mev_decentralised_kwh_per_yr` pure helpers. AAA tests pin cert 000565 worksheet values. No cascade integration. |
|
||||
| **S0380.101** | `1b183f9c` | SAP 10.2 Table 4a (PDF p.165) — Heat-pump category 4 | HP SAP codes 211-227 / 521-527 → `main_heating_category=4` in `_elmhurst_main_heating_category` (Elmhurst path). Cert 000565 Main 1 (SAP 224) flipped None→4. Transient regression: pumps_fans 255 → 125 (offset bug exposed). |
|
||||
| **S0380.102** | `a0413155` | SAP 10.2 §2.6.4 + Table 4f (230a) — Wire MEV cascade into `_table_4f_additive_components` | **pumps_fans_kwh_per_yr 255 → 252.5159 ✓ EXACT**. Schema + extractor + mapper for MV PCDF index / wet rooms / duct type. Elmhurst fan-count convention reverse-engineered from cert 000565 (TODO: validate on a 2nd MEV cert). |
|
||||
| **S0380.103** | `e3abe9b2` | SAP 10.2 Table 12a Grid 2 (PDF p.191) — `FANS_FOR_MECH_VENT` blended rate on off-peak | MEV-fan cost weighting: 127.5 kWh at 11.6644 p/kWh + 125 kWh at 13.2440 p/kWh → effective 12.4467 p/kWh. cost Δ +£0.39 → -£1.62 (sign flipped; SH cascade residual exposed). |
|
||||
|
||||
**Test baseline at HEAD `e3abe9b2`:** 597 pass + 7 expected `000565`
|
||||
fails (was 585 + 9 at start of session, with .96+.97 closing the
|
||||
sap_score integer fail and .102 closing the pumps_fans fail). The
|
||||
ETL test count grew by ~25 with the new PCDB tables.
|
||||
|
||||
Pyright net-zero per touched file across every slice.
|
||||
|
||||
## Cert 000565 state (HEAD `e3abe9b2`)
|
||||
|
||||
### Fabric subtotals
|
||||
|
||||
| Component | Cascade W/K | Worksheet W/K | Δ | Status |
|
||||
|---|---:|---:|---:|---|
|
||||
| walls | 601.22 | 604.07 | -2.85 | sub-spec |
|
||||
| **party_walls** | **65.13** | 65.13 | ✓ EXACT | S0380.91 |
|
||||
| **floor** | **61.67** | 61.67 | ✓ EXACT | S0380.97 |
|
||||
| roof | 52.97 | 51.38 | +1.59 | residual +1.29 BP[1] formula |
|
||||
| windows | 9.60 | 11.48 | -1.88 | sub-spec |
|
||||
| roof_windows | 5.02 | 3.58 | +1.44 | sub-spec |
|
||||
| **doors** | **11.10** | 11.10 | ✓ EXACT | full pipeline plumbing |
|
||||
| **thermal_bridging** | **129.35** | 128.65 | +0.70 | S0380.95 |
|
||||
| **total external area** | **862.34** | 857.64 | +4.70 | S0380.95 |
|
||||
|
||||
### SapResult pins (HEAD `e3abe9b2`)
|
||||
|
||||
| Pin | Cascade | Worksheet | Δ | Status |
|
||||
|---|---:|---:|---:|---|
|
||||
| **sap_score (int)** | **29** | 29 | **✓ EXACT** | S0380.97 |
|
||||
| sap_score_continuous | 28.5269 | 28.5087 | +0.0182 | SH cascade-driven |
|
||||
| ecf | 5.3850 | 5.3866 | -0.0016 | SH cascade-driven |
|
||||
| total_fuel_cost_gbp | 4678.6372 | 4680.2593 | -1.6221 | SH cascade-driven |
|
||||
| co2_kg_per_yr | 6445.8198 | 6447.6263 | -1.8065 | mix: CO2 MEV split + SH |
|
||||
| space_heating_kwh_per_yr | 58980.8225 | 59008.3499 | -27.5274 | §3-§8 cascade gap |
|
||||
| main_heating_fuel_kwh_per_yr | 34694.6015 | 34710.7941 | -16.1926 | downstream of SH |
|
||||
| **hot_water_kwh_per_yr** | 3755.0288 | 3755.0288 | ✓ 0 EXACT | unchanged |
|
||||
| lighting_kwh_per_yr | 1387.0237 | 1384.8353 | +2.1884 | sub-spec |
|
||||
| **pumps_fans_kwh_per_yr** | **252.5159** | 252.5159 | **✓ 0 EXACT** | S0380.102 |
|
||||
|
||||
### Continuous SAP journey across this session
|
||||
|
||||
| Slice | sap_score (int) | sap_score_continuous | Δ vs ws |
|
||||
|---|---:|---:|---:|
|
||||
| Pre-S0380.96 | 28 | 28.07 | -0.44 |
|
||||
| S0380.96 | 28 | 28.31 | -0.20 |
|
||||
| **S0380.97** | **29** | **28.5086** | **-0.0001** (within 1e-4!) |
|
||||
| S0380.98..100 | 29 | 28.5086 | -0.0001 (no cascade change) |
|
||||
| S0380.101 | 29 | 28.6942 | +0.1855 (transient — HP cat=4 only, MEV not yet wired) |
|
||||
| S0380.102 | 29 | 28.5043 | -0.0044 (MEV wired, restored balance) |
|
||||
| **S0380.103** | 29 | **28.5269** | **+0.0182** (MEV cost split exposed pre-existing SH residual) |
|
||||
|
||||
Per user direction [[feedback-spec-floor-skepticism]] +
|
||||
[[feedback-spec-floor-skepticism]]: each slice closed a true spec-
|
||||
correct intermediate-value bug. The continuous-SAP residual is now
|
||||
driven by a §3-§8 SH cascade under-count (main_heating_fuel -16 kWh)
|
||||
that was previously masked by the +£2.01 pumps_fans cost over-count.
|
||||
|
||||
## Open work — prioritised next slices
|
||||
|
||||
### S0380.104 — Investigate §3-§8 space-heating cascade -27 kWh
|
||||
|
||||
**The current biggest residual driver.** main_heating_fuel_kwh is
|
||||
-16.19 kWh under ws (34694.60 vs ws 34710.79) → SH cost £1.58 under
|
||||
ws → continuous-SAP +0.0182 OVER ws.
|
||||
|
||||
Possible causes:
|
||||
1. **Heat transmission HLC residual** — fabric subtotals net to net
|
||||
~+29 W/K (post-S0380.95 fabric snapshot). Walls -2.85, roof
|
||||
+1.59, thermal_bridging +0.70, total_external_area +4.70.
|
||||
Roof BP[1] residual formula gap (+1.29 W/K, deferred from
|
||||
S0380.95) is the largest single localised item.
|
||||
2. **Internal gains** — pumps_fans gains contribution changes with
|
||||
HP cat=4 path; verify against ws line (70) by month.
|
||||
3. **Solar gains / utilization factor** — sub-spec window U-values
|
||||
leak into solar gains too.
|
||||
4. **Mean internal temperature / per-month solve** — possible
|
||||
convergence-loop tolerance issue on this multi-BP cert.
|
||||
|
||||
**Approach:** probe per-month `space_heat_requirement_kwh` vs ws
|
||||
line (98c)m to localise. The cohort certs (000474..000516) hit SH
|
||||
at 1e-4 so the §8 orchestrator IS correct on simpler dwellings —
|
||||
something cert-000565-specific (Detailed-RR + multi-BP + HP + MEV
|
||||
+ FGHRS + solar HW + draught lobby) is the differentiator.
|
||||
|
||||
Expected closure: continuous SAP +0.0182 → within 1e-4.
|
||||
|
||||
### S0380.105 — CO2 cascade MEV split (Table 12d monthly factors)
|
||||
|
||||
Mirror of S0380.103 for CO2. Cert 000565 worksheet line (267):
|
||||
|
||||
Pumps, fans and electric keep-hot 252.5159 × 0.1412 = 35.3349
|
||||
|
||||
Cascade `pumps_fans_co2_factor_kg_per_kwh = 0.14116` (kWh-weighted
|
||||
Table 12d monthly factor for code 30) → 35.6453 kg → +0.31 over ws.
|
||||
|
||||
Cause: cascade uses a single Table 12d profile across all pumps_fans
|
||||
kWh. MEV fans have a different MONTHLY DISTRIBUTION than central-
|
||||
heating pumps + flue fans (MEV runs year-round at 0.5 ach; pumps
|
||||
run heating season only). The worksheet integrates separately.
|
||||
|
||||
**Slice scope:** add `MevFanEntry`-style CO2 helper + new
|
||||
`pumps_fans_co2_factor_kg_per_kwh` resolution that weights the two
|
||||
streams.
|
||||
|
||||
Impact: -0.31 kg/yr → continuous SAP downstream.
|
||||
|
||||
### S0380.106 — PE cascade MEV split (Table 12e monthly factors)
|
||||
|
||||
Mirror of S0380.105 for primary energy. Analogous structure.
|
||||
|
||||
### S0380.107 — BP[1] residual formula refinement (roof)
|
||||
|
||||
BP[1] Ext1 currently has residual +3.68 m² over worksheet (cascade
|
||||
21.93 vs ws 18.25). The Simplified A_RR formula `12.5 × √(34/1.5)`
|
||||
gives 59.51 — minus 37.58 lodged walls = 21.93. Worksheet uses 18.25.
|
||||
|
||||
Hypothesis: Ext1's RR height = 3.0 m (not 2.45 m assumed by formula).
|
||||
A height-aware formula like `A_RR = perimeter × actual_RR_height`
|
||||
might match. Need investigation against multiple Detailed-mode certs
|
||||
with non-2.45 RR heights.
|
||||
|
||||
Impact if closed: roof -1.29 W/K (residual drops by 3.68 × 0.35).
|
||||
|
||||
### S0380.108 — Lighting +2.19 kWh trace residual
|
||||
|
||||
Cascade 1387.02 vs ws 1384.84. Sub-spec but breaks 1e-4 strict pin.
|
||||
|
||||
§5 Appendix L lighting cascade. Likely a per-cert-lodging gap
|
||||
(bulb count, fixed/non-fixed lighting fraction).
|
||||
|
||||
### Deferred (unchanged from earlier handovers)
|
||||
|
||||
- 12 gas-combi PV certs at +0.5..+1.6 PE (no worksheets)
|
||||
- 5 SAP-residual API-only certs (no worksheets)
|
||||
|
||||
## MEV PCDB arc — architecture summary
|
||||
|
||||
The S0380.98..103 arc landed the entire MEV decentralised cascade
|
||||
end-to-end. Architecture (in dependency order):
|
||||
|
||||
```
|
||||
PCDB pcdb10.dat
|
||||
↓ ETL (etl.py, parser.py)
|
||||
Table 322 (per-fan SFP) ←→ Table 329 (per-ducting IUF)
|
||||
↓ runtime lookups (__init__.py)
|
||||
decentralised_mev_record(pcdb_id) + mv_in_use_factors_record(system_type)
|
||||
↓
|
||||
worksheet/mev.py — pure helpers
|
||||
mev_sfp_av(fan_entries) → §2.6.4 equation (1) avg SFP
|
||||
mev_decentralised_kwh_per_yr(sfp_av, V) → Table 4f line (230a) kWh
|
||||
↓
|
||||
cert_to_inputs.py
|
||||
_mev_decentralised_kwh_per_yr_from_cert(epc) — composer
|
||||
reads epc.mechanical_ventilation_index_number, .wet_rooms_count,
|
||||
.mechanical_vent_duct_type
|
||||
builds Elmhurst per-fan count distribution
|
||||
invokes mev.py helpers
|
||||
↓
|
||||
_table_4f_additive_components(epc) adds the MEV contribution
|
||||
↓
|
||||
pumps_fans_kwh_per_yr final cascade output
|
||||
|
||||
For COST (S0380.103):
|
||||
_pumps_fans_fuel_cost_gbp_per_kwh(tariff, mev_kwh, total_pumps_fans_kwh)
|
||||
→ kWh-weighted blended rate (FANS_FOR_MECH_VENT vs ALL_OTHER_USES)
|
||||
CalculatorInputs.pumps_fans_fuel_cost_gbp_per_kwh: Optional[float]
|
||||
Calculator legacy path uses it via `or other_fuel_cost_gbp_per_kwh`.
|
||||
```
|
||||
|
||||
**Open question for the next agent:** the Elmhurst per-fan-count
|
||||
convention in `_mev_decentralised_kwh_per_yr_from_cert` was reverse-
|
||||
engineered from cert 000565 alone:
|
||||
- Each PCDB-defined config (1..6) gets baseline count = 1
|
||||
- Through-wall kitchen (5): wet_rooms_count fans total
|
||||
- Through-wall other wet (6): wet_rooms_count + 1 fans total
|
||||
|
||||
When a 2nd MEV cert lands, validate this. May need to consult
|
||||
Elmhurst's documentation or the BRE-published SAP 10.2
|
||||
implementation guide.
|
||||
|
||||
## 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/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 \
|
||||
--no-cov -q
|
||||
```
|
||||
|
||||
Expected: **597 pass + 7 expected `test_sap_result_pin[000565-*]` fails**.
|
||||
|
||||
The 7 expected fails (verbatim):
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
All driven by the §3-§8 SH cascade residual + lighting trace + CO2
|
||||
MEV-split gap.
|
||||
|
||||
## Files touched this session
|
||||
|
||||
| File | Slices | Change |
|
||||
|---|---|---|
|
||||
| `backend/documents_parser/elmhurst_extractor.py` | .96, .97, .102 | "Unknown" insulation token; §9 "Insulation Thickness" cell; §12.1 MV PCDF/Wet-Rooms/Duct-Type fields |
|
||||
| `backend/documents_parser/tests/test_summary_pdf_mapper_chain.py` | .96, .97, .101, .103 | AAA tests for cert 000565 closures |
|
||||
| `datatypes/epc/domain/mapper.py` | .96, .97, .101, .102 | `_elmhurst_rir_insulation_thickness_mm` → `Optional[int]`; floor `insulation_thickness_mm` plumbing; HP SAP-code → category 4; MV duct-type mapper + PCDF plumbing |
|
||||
| `datatypes/epc/surveys/elmhurst_site_notes.py` | .97, .102 | `FloorDetails.insulation_thickness_mm`; `VentilationAndCooling.mechanical_ventilation_pcdf_reference` + `.wet_rooms_count` + `.duct_type` + `.approved_installation` |
|
||||
| `domain/sap10_calculator/tables/pcdb/__init__.py` | .98, .99 | `decentralised_mev_record` + `mv_in_use_factors_record` lookups |
|
||||
| `domain/sap10_calculator/tables/pcdb/etl.py` | .98, .99 | Table 322 + 329 typed ETL |
|
||||
| `domain/sap10_calculator/tables/pcdb/parser.py` | .98, .99 | `DecentralisedMevRecord` + `MvInUseFactorsRecord` + parsers |
|
||||
| `domain/sap10_calculator/tables/pcdb/data/pcdb_table_322_decentralised_mev.jsonl` | .98 | New file — 48 records |
|
||||
| `domain/sap10_calculator/tables/pcdb/data/pcdb_table_329_mv_in_use_factors.jsonl` | .99 | New file — 5 records |
|
||||
| `domain/sap10_calculator/worksheet/mev.py` | .100 | New module — `mev_sfp_av` + `mev_decentralised_kwh_per_yr` helpers |
|
||||
| `domain/sap10_calculator/worksheet/tests/test_mev.py` | .100 | AAA tests pinning cert 000565 SFPav |
|
||||
| `domain/sap10_calculator/rdsap/cert_to_inputs.py` | .102, .103 | `_mev_decentralised_kwh_per_yr_from_cert` composer; `_pumps_fans_fuel_cost_gbp_per_kwh` helper |
|
||||
| `domain/sap10_calculator/calculator.py` | .103 | `CalculatorInputs.pumps_fans_fuel_cost_gbp_per_kwh` field + legacy cost path |
|
||||
| `domain/sap10_calculator/tests/test_pcdb_etl.py` | .98, .99 | Added Tables 322, 329 to file list |
|
||||
| `domain/sap10_calculator/tests/test_pcdb_table_322_lookup.py` | .98 | New file — 3 tests |
|
||||
| `domain/sap10_calculator/tests/test_pcdb_table_329_lookup.py` | .99 | New file — 4 tests |
|
||||
|
||||
## Spec source quick-reference
|
||||
|
||||
- **SAP 10.2 full specification**: `domain/sap10_calculator/docs/specs/sap-10-2-full-specification-2025-03-14.pdf`
|
||||
- §2.6.4 (p.16) — Decentralised MEV SFPav equation (1) — S0380.100
|
||||
- §5 Table 4a (p.165) — Heat-pump category 4 — S0380.101
|
||||
- §5 Table 4f (p.174) — Annual electricity for fans / pumps — S0380.100, .102
|
||||
- §5 Table 4g (p.176) — Default SFP for MV systems — S0380.99
|
||||
- §10a Table 12a (p.191) — High-rate fractions on off-peak tariffs — S0380.103
|
||||
- **RdSAP 10 specification**: `domain/sap10_calculator/docs/specs/RdSAP 10 Specification 10-06-2025.pdf`
|
||||
- §3.10.1 (p.24) — Unknown insulation → Table 18 default — S0380.96
|
||||
- §5.13 + Table 20 (p.47) — Exposed/semi-exposed floor U-values — S0380.97
|
||||
- **PCDF Spec Rev 6b**: `domain/sap10_calculator/docs/specs/PCDF_Spec_Rev-06b_12_May_2021.pdf`
|
||||
- §A.19 Format 427 (Decentralised MEV) — S0380.98
|
||||
- §A.20 Format 430 (MV In-Use Factors) — S0380.99
|
||||
- **SAP 10.3 at** `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 .96..103 + open-work analysis
|
||||
- `MEMORY.md` — index entry refreshed at HEAD `e3abe9b2`
|
||||
|
||||
## 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 7 cert 000565 fails are the
|
||||
work queue.
|
||||
- **Don't re-investigate any closed work** (.91..103). All settled.
|
||||
- **Don't add new helpers to `domain/sap10_ml/`** — deprecation path
|
||||
per [[project-sap10_ml-deprecation]]. New cascade helpers belong
|
||||
under `domain/sap10_calculator/`.
|
||||
- **Don't avoid spec-correct closures because continuous SAP drifts
|
||||
away** — user explicitly OK'd transient drift. Zero error
|
||||
achievable only when every component is spec-correct.
|
||||
|
||||
## Memory hygiene
|
||||
|
||||
After the next slice, update:
|
||||
- `project_cert_000565_recovery_state` — append slice closure +
|
||||
refresh the open work-items table
|
||||
- `MEMORY.md` — refresh HEAD + one-line summary
|
||||
|
||||
Good luck.
|
||||
237
domain/sap10_calculator/docs/NEXT_AGENT_PROMPT_POST_S0380_103.md
Normal file
237
domain/sap10_calculator/docs/NEXT_AGENT_PROMPT_POST_S0380_103.md
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
# Next-agent prompt — post S0380.96..103
|
||||
|
||||
Branch: `feature/per-cert-mapper-validation`.
|
||||
HEAD: `e3abe9b2`.
|
||||
|
||||
Read these in order before any tool call:
|
||||
|
||||
1. [`HANDOVER_POST_S0380_103.md`](HANDOVER_POST_S0380_103.md) — full state
|
||||
2. [`HANDOVER_POST_S0380_95.md`](HANDOVER_POST_S0380_95.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 on the
|
||||
deprecation path; 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_abs_diff_over_pytest_approx` — use `abs(x - y) <= tol`
|
||||
instead of `pytest.approx` to keep pyright net-zero
|
||||
- `feedback_spec_floor_skepticism` — skeptical of "spec-precision
|
||||
floor" claims; verify the spec citation against the PDF first
|
||||
|
||||
## Critical user direction
|
||||
|
||||
The user's **primary metric is `sap_score_continuous`** (not just
|
||||
integer `sap_score`). However the user has explicitly stated:
|
||||
|
||||
> "It's okay if we temp drift away from continuous SAP, as long as we
|
||||
> are actually fixing true problems with the intermediate values.
|
||||
> Eventually, I expect the error of continuous SAP to be zero but
|
||||
> that is only possible if we fix all of the sub components and
|
||||
> remain true to spec."
|
||||
|
||||
**Implication:** ship spec-correct slices even when they cause
|
||||
transient continuous-SAP drift. Closing real intermediate-value bugs
|
||||
is the path to zero error.
|
||||
|
||||
## State summary
|
||||
|
||||
This session shipped **S0380.96..103** — eight spec-cited slices.
|
||||
The first two (.96, .97) closed remaining cert 000565 extractor /
|
||||
mapper gaps; .98..102 built the entire MEV PCDB decentralised
|
||||
cascade arc; .103 closed the Table 12a Grid 2 MEV-fan cost split.
|
||||
|
||||
1. **S0380.96** (`32a4cf20`) — RIR "Unknown" insulation → Table 18
|
||||
col 4 default (RdSAP 10 §3.10.1). BP[4] FC1 U: 2.30→**0.15 ✓**.
|
||||
2. **S0380.97** (`7121a86b`) — Floor §9 "Insulation Thickness"
|
||||
extractor (RdSAP 10 §5.13 Table 20). BP[2] floor U:
|
||||
0.51→**0.22 ✓ EXACT**. **sap_score 28→29 ✓ EXACT**. Continuous
|
||||
SAP Δ -0.0001 (within 1e-4 strict floor).
|
||||
3. **S0380.98** (`b3330821`) — PCDB Table 322 (Decentralised MEV)
|
||||
ETL + parser + lookup foundation (PCDF Spec §A.19).
|
||||
4. **S0380.99** (`433f4a49`) — PCDB Table 329 (MV In-Use Factors)
|
||||
ETL + parser + lookup foundation (PCDF Spec §A.20).
|
||||
5. **S0380.100** (`44fb8c07`) — SFPav + Table 4f (230a) cascade
|
||||
helpers in `worksheet/mev.py` (SAP 10.2 §2.6.4).
|
||||
6. **S0380.101** (`1b183f9c`) — HP SAP code 211-227 / 521-527 →
|
||||
`main_heating_category=4` (SAP 10.2 Table 4a).
|
||||
7. **S0380.102** (`a0413155`) — Wire MEV cascade into
|
||||
`_table_4f_additive_components`. **pumps_fans_kwh_per_yr ✓
|
||||
EXACT** (was +2.48 over). Schema + extractor + mapper for MV
|
||||
PCDF index / wet rooms / duct type.
|
||||
8. **S0380.103** (`e3abe9b2`) — MEV-fan cost split via Table 12a
|
||||
Grid 2 `FANS_FOR_MECH_VENT` rate. cost residual Δ +£0.39 →
|
||||
-£1.62 (sign flipped; SH cascade residual now exposed).
|
||||
|
||||
**Cert 000565 state at HEAD `e3abe9b2`:**
|
||||
|
||||
| Pin | Cascade | Worksheet | Δ |
|
||||
|---|---:|---:|---:|
|
||||
| **sap_score (int)** | **29** | 29 | **✓ EXACT** |
|
||||
| sap_score_continuous | 28.5269 | 28.5087 | +0.0182 |
|
||||
| ecf | 5.3850 | 5.3866 | -0.0016 |
|
||||
| total_fuel_cost_gbp | 4678.6372 | 4680.2593 | -1.6221 |
|
||||
| co2_kg_per_yr | 6445.8198 | 6447.6263 | -1.8065 |
|
||||
| space_heating_kwh_per_yr | 58980.8225 | 59008.3499 | -27.5274 |
|
||||
| main_heating_fuel_kwh_per_yr | 34694.6015 | 34710.7941 | -16.1926 |
|
||||
| **pumps_fans_kwh_per_yr** | **252.5159** | 252.5159 | **✓ 0 EXACT** |
|
||||
| **hot_water_kwh_per_yr** | 3755.0288 | 3755.0288 | **✓ 0 EXACT** |
|
||||
| lighting_kwh_per_yr | 1387.0237 | 1384.8353 | +2.1884 |
|
||||
|
||||
## Recommended next slice — S0380.104 § Investigate §3-§8 SH cascade -27 kWh
|
||||
|
||||
**The current biggest residual driver.** Cert 000565 cascade
|
||||
space_heating_kwh = 58980.82 vs ws 59008.35 → Δ -27.53 kWh under.
|
||||
This propagates downstream to main_heating_fuel (-16.19 kWh under)
|
||||
and total_fuel_cost (-£1.62 under). It is the dominant cause of
|
||||
continuous-SAP residual +0.0182 OVER ws.
|
||||
|
||||
### Why it's now exposed
|
||||
|
||||
S0380.103 closed the +£2.01 MEV-cost over-count (Table 12a Grid 2
|
||||
split). Pre-slice that over-count nearly cancelled the SH under-
|
||||
count → cost looked +£0.39 over. Post-slice the SH under-count
|
||||
shows through to cost / co2 / continuous SAP.
|
||||
|
||||
The SH cascade IS correct on the cohort fixtures (000474..000516 at
|
||||
1e-4) so this is **cert-000565-specific**. The differentiators are:
|
||||
- 5 building parts (Main + 4 extensions)
|
||||
- Heat pump + gas combi WHC 914
|
||||
- Detailed-RR with residual area (S0380.95 closure)
|
||||
- MEV decentralised
|
||||
- FGHRS, solar HW, draught lobby, basement walls (Ext3/Ext4),
|
||||
Curtain Wall Post-2023 (Ext2), CF + CU party walls
|
||||
|
||||
### Investigation approach
|
||||
|
||||
1. **Probe per-month `space_heat_requirement_kwh`** vs ws line
|
||||
(98c)m to identify which month(s) carry the residual:
|
||||
|
||||
```python
|
||||
from domain.sap10_calculator.worksheet.tests._elmhurst_worksheet_000565 import build_epc
|
||||
from domain.sap10_calculator.rdsap.cert_to_inputs import cert_to_inputs
|
||||
epc = build_epc()
|
||||
inputs = cert_to_inputs(epc)
|
||||
print("monthly SH:", inputs.space_heating_monthly_kwh)
|
||||
# Compare to ws (98c)m line refs from U985-0001-000565.pdf
|
||||
```
|
||||
|
||||
2. **Check the fabric subtotals** — net cascade HTC is +29.45 W/K
|
||||
over ws. Closing roof BP[1] residual (+1.29 W/K, deferred) +
|
||||
thermal_bridging (+0.70) brings it to +27.5. Walls are -2.85
|
||||
under and windows/roof_windows offset.
|
||||
|
||||
Big +29 W/K HTC should DRIVE space_heating UP, but cascade SH is
|
||||
-27 kWh UNDER. That means the cascade is OVER-counting heat
|
||||
GAINS somewhere, or UNDER-counting demand by an offsetting factor.
|
||||
|
||||
3. **Check internal gains** — pumps_fans gains (line 70) changed
|
||||
between cohort certs and cert 000565 (HP cat=4 → 0W heating-
|
||||
season pump). Verify against ws line (70)m by month.
|
||||
|
||||
4. **Check solar gains** (line 74-83) — sub-spec window U could
|
||||
propagate to gain magnitude.
|
||||
|
||||
5. **Check utilisation factor / mean-internal-temp solve** — multi-
|
||||
BP cert with mixed age bands might hit a corner case.
|
||||
|
||||
Expected closure: continuous SAP +0.0182 → within 1e-4.
|
||||
|
||||
## Alternative next slice — S0380.105 § CO2 cascade MEV split
|
||||
|
||||
Mirror of S0380.103 for CO2. Cert 000565 worksheet line (267):
|
||||
|
||||
```
|
||||
Pumps, fans and electric keep-hot 252.5159 × 0.1412 = 35.3349
|
||||
```
|
||||
|
||||
Cascade `pumps_fans_co2_factor_kg_per_kwh = 0.14116` (kWh-weighted
|
||||
Table 12d monthly factor for code 30) → 35.6453 kg → +0.31 over ws.
|
||||
|
||||
The cascade applies a single Table 12d profile across all
|
||||
pumps_fans. The worksheet integrates MEV (year-round) separately
|
||||
from heating-season pumps + flue fans.
|
||||
|
||||
**Slice scope:** add an MEV-weighted CO2 factor analogous to
|
||||
`_pumps_fans_fuel_cost_gbp_per_kwh`. Add field
|
||||
`CalculatorInputs.pumps_fans_co2_factor_kg_per_kwh` resolution that
|
||||
weights two streams.
|
||||
|
||||
Impact: -0.31 kg/yr → continuous SAP downstream marginal change.
|
||||
|
||||
This is the **lower-leverage** of the two open options. S0380.104
|
||||
SH investigation is higher leverage.
|
||||
|
||||
## 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 below)
|
||||
7. Check pyright on touched files — net-zero from baseline
|
||||
(use `git stash` + re-run pyright to compute baseline)
|
||||
8. Commit with spec citation + verbatim quote
|
||||
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/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 \
|
||||
--no-cov -q
|
||||
```
|
||||
|
||||
Expected: **597 pass + 7 expected `test_sap_result_pin[000565-*]` fails**.
|
||||
|
||||
After S0380.104 lands the expected fail count should drop by 5-7
|
||||
(sap_score_continuous, ecf, total_fuel_cost_gbp, co2_kg_per_yr,
|
||||
space_heating_kwh_per_yr, main_heating_fuel_kwh_per_yr) if the SH
|
||||
cascade closes. Lighting (+2.19 kWh) is unrelated and survives as
|
||||
its own slice.
|
||||
|
||||
## 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 7 cert 000565 fails are the
|
||||
work queue.
|
||||
- **Don't re-investigate any closed work** (.91..103). All settled.
|
||||
- **Don't add new helpers to `domain/sap10_ml/`** — deprecation path
|
||||
per [[project-sap10_ml-deprecation]]. New cascade helpers belong
|
||||
under `domain/sap10_calculator/`.
|
||||
- **Don't avoid spec-correct closures because continuous SAP drifts
|
||||
away** — user explicitly OK'd transient drift. Zero error
|
||||
achievable only when every component is spec-correct.
|
||||
|
||||
## Memory hygiene
|
||||
|
||||
After the next slice, update:
|
||||
- `project_cert_000565_recovery_state` — append closure + open work-
|
||||
items refresh
|
||||
- `MEMORY.md` index — refresh HEAD + one-line summary
|
||||
|
||||
Good luck.
|
||||
Loading…
Add table
Reference in a new issue