Captures the 4-slice arc this session — Table 32 default prices (sap_score
28 → 29 EXACT), Table 12a Grid 2 dual-rate CO2 (CO2 65% closed), extractor
gable_type recognition + mapper preservation of cert 9501, and the full
RR mapper + cascade fix per RdSAP 10 §3.9.2 + §3.10 + Table 4 (11
per-BP RR surface areas EXACT vs worksheet PDF).
Documents the BP main-wall residual −161 W/K diagnostic localising the
next slice block to two spec-cited cascade gaps: Curtain Wall (−112
W/K, no _ENG_WALL entry for WALL_CURTAIN=9) + thin-wall stone granite
alt (−47 W/K, _insulation_bucket short-circuit + thin-wall §6.6/§6.7
formula). Each spans extractor → datatype → mapper → cascade and is a
single coherent slice when the spec lookup is tractable.
NEXT_AGENT_PROMPT_POST_S0380_84.md prescribes S0380.85 (Curtain Wall)
as the highest-leverage next slice with audit + implementation +
expected-outcome details.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Documents the full §4 HW cascade closure for cert 000565 across the
S0380.77 → S0380.80 series:
- S0380.77 primary loss WHC 914 routing
- S0380.78 §1x.0 shower extractor + (247a) fallback cost
- S0380.79 (57)m solar storage + separately-timed-DHW cylinder default
- S0380.80 Table 4c −5% DHW for missing boiler interlock
Cumulative cert 000565 closure:
hot_water_kwh: +1399 → ✓ 0 EXACT (100%)
continuous SAP: +0.78 → -0.041 (95% closed)
total cost: -69 → +3.62 (95% closed)
All §4 line refs (45)/(46)/(57)/(59)/(62)/(64)/(217)/(219) EXACT
Open #1 priority for the next agent: deferred ADR-0010 mains-gas
tariff Table 32 vs Table 12 cohort closure. The remaining
sap_score=28 vs worksheet 29 flip is entirely due to this £0.16/100
gas-price delta over 3755 HW kWh = +£6 → +0.041 continuous SAP →
flips integer at the 28.5 boundary. Cohort-wide change; would land
sap_score=29 EXACT for cert 000565 AND likely tighten several other
worksheet certs in the same coordinated pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- HANDOVER_POST_S0380_76.md: full state including the Appendix H
closure narrative (the trap that closed via U3.3 unit-convention
fix), cert 000565 current pin state, and three independent
demand-cascade bugs to tackle in follow-on slices.
- NEXT_AGENT_PROMPT_POST_S0380_76.md: focused briefing pointing at
primary_loss (59)m for HP + external cylinder as the highest-
yield next slice (+1175 kWh fix).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Root cause: SAP 10.2 has an internal unit-convention ambiguity for
(H7)m between page 75 (Equation H1 implies W/m² 24-hour-average flux)
and page 76 (verbatim "Monthly solar radiation per m² from U3.3 in
Appendix U", i.e. kWh/m²/month monthly integrated). Page 77 (H23)
formula's `× hours / 1000` term double-converts when (H7) is W/m².
The cascade's `surface_solar_flux_w_per_m2` returns the §U3.2 24h-avg
flux in W/m² (verified bit-exact vs Elmhurst worksheet line 295: SE
90° Jan region 0 = 36.7938 W/m²). The (H9) helper was using this
directly without applying the U3.3 conversion that page 76's "from
U3.3" cross-reference calls for. Elmhurst-certified software follows
the U3.3 reading.
SAP 10.2 spec p.76 line (H7): "Monthly solar radiation per m² from
U3.3 in Appendix U". Appendix U §U3.3 (p.130) defines the conversion
S_monthly = 0.024 × n_m × S(orient,p,m), where S(orient,p,m) is the
§U3.2 24-hour-average flux in W/m². Therefore:
(H7)m_U3.3 [kWh/m²/month] = flux_U3.2 [W/m²] × hours / 1000
Option A fix (per ChatGPT-mediated research): apply the U3.3
conversion inside the (H9) helper, so (H9) is in kWh/month rather
than W. Spec p.77 (H23) formula then carries the conversion's
dimensional residue correctly without double-counting.
Diagnostic that closed the trap: back-solving poly(X_cas, Y_eff) =
ws_H24/H17 at fixed X across 24 worksheet-positive observations from
4 cert fixtures (000565 + new A/B/C at sap worksheets/Solar PV tests/)
revealed Y_eff/Y_cascade took ONLY two distinct values:
- 0.7200 (exact) for every 30-day month observation
- 0.7440 (exact) for every 31-day month observation
i.e. exactly days × 24 / 1000. No utilizability function, no missing
constant — a per-month unit-conversion factor that the polynomial
non-linearity had been masking.
Closure metrics (HEAD post-fix):
- 000565 (W-30, modest): annual Δ −0.0000 kWh (every month exact)
- A-baseline (S-30, modest): annual Δ +0.0001 kWh
- B-highY (S-30, none): annual Δ −0.0000 kWh (incl Oct 10.5905)
- C-lowY (N-60, signif): annual Δ −4.36 kWh (polynomial zero-clamp
boundary; worksheet poly = 0.0024 → 0.41 kWh, cascade poly =
−0.04 → 0)
47/48 month-observations pin at <1e-4 kWh.
Test baseline: 547 pass + 9 expected `test_sap_result_pin[000565-*]`
cascade-gap fails (unchanged — orchestrator still NOT integrated
into water_heating.py:943; that's the follow-on slice that closes
cert 000565's HW pin +272 → ~0).
Pyright net-zero on both touched files.
Files:
- domain/sap10_calculator/worksheet/appendix_h_solar.py: rename
`monthly_solar_energy_available_h9_w` → `_h9_kwh_per_month`,
add `hours_in_month` param, apply U3.3 conversion. Y23 param
renamed accordingly. Orchestrator updated.
- domain/sap10_calculator/worksheet/tests/test_appendix_h_solar.py:
add cert 000565 (H24)m monthly magnitude pin at abs < 1e-3 kWh;
update H9 + Y23 unit tests for new kWh/month units.
- BRIEF_APPENDIX_H_EN_15316_RESEARCH.md: new "Closure" section with
the days-in-month diagnostic, root cause, and lessons.
- HANDOVER_POST_4_CERT_EMPIRICAL.md: NEW — closure handover.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Session-end handover docs for the cert 000565 wacky-stress-test
investigation. Three documents covering:
- **HANDOVER_POST_S0380_73_APPENDIX_H_BLOCKED.md** — full state
of the cohort closure work (S0380.70-.73) plus the Appendix H
Solar HW investigation findings. Cumulative ASHP cluster
compression −3.10 → −0.06 PE kWh/m² over 4 slices. Cert
000565 HW pin blocked at +272 kWh/yr on a 1.81× formula
over-count.
- **BRIEF_APPENDIX_H_EN_15316_RESEARCH.md** — self-contained
brief for a research agent or human looking up BS EN 15316-4-3
Method 2 to identify the missing clamp / useful-gain rule /
validity envelope behind the over-count. Includes the cert
000565 diagnostic (per-month ratio 1.5-1.7× summer, 3-4×
shoulder), seven specific questions ranked by hypothesis
likelihood, and the 36-data-point empirical-fit setup.
- **NEXT_AGENT_PROMPT_POST_S0380_73.md** — directive for the
next agent. Awaits 3 user-generated solar-HW cert worksheets
(A baseline / B high-Y / C low-Y) to empirically test whether
the 1.81× ratio is systematic or cert-specific. Decision
point: ship an empirical correction (if 36-point fit closes
all 3 certs + cert 000565) or hold for the EN standard.
Also resolves the long-standing H3=4.0 / H4=0.01 default mystery:
sub-agent located the source in RdSAP 10 Specification §10.11
Table 29 row "Solar panel" page 58. RdSAP overrides the input
set; the calculator is still SAP 10.2 Appendix H. So the
defaults aren't the source of the over-count.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
New `HANDOVER_POST_S0380_69.md` covers the 6 slices shipped this
session — cert 000565 closure to sap_score=29 EXACT + main_heating_
co2_factor=0.1533 EXACT, Appendix H pure math module + orchestrator
(magnitude calibration deferred on SAP 10.2 spec ambiguity), and the
cohort-2 (38 cert) PE/CO2 golden-coverage addition. Includes
residuals table, open work breakdown with reasons (Appendix H spec
ambiguity, RR fold-in geometry, MEV PCDB external blocker, House
coal secondary cascade), spec-source quick-reference, and key-file
map.
Predecessor `HANDOVER_CERT_000565_COST_CASCADE.md` (S0380.52..63)
gets a "superseded by" note at the top so the chain is navigable.
`NEXT_AGENT_PROMPT_POST_S0380_69.md` is a self-contained prompt for
a new agent picking this up cold — references the memories to load,
ranks 5 well-scoped next-slice options (cert 2102 House coal /
Appendix H magnitude calibration / RR fold-in / PE cluster / MEV
coupled set), and includes the standard probe commands. Reinforces
`feedback_sap_10_2_only_never_10_3` as a critical-load constraint.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User clarified end-of-session: mapper is a thin enum-and-shape
translation; when residuals remain after closing mapper coverage
gaps, the gap is in the **calculator cascade**. This unlocks an
Elmhurst-only fixture path that doesn't need API JSON at all.
The fixture shape mirrors the 6 historical Elmhurst U985 fixtures
(000474, 000477, 000480, 000487, 000490, 000516) at
`domain/sap10_calculator/worksheet/tests/_elmhurst_worksheet_NNNNNN.py`
+ `test_e2e_elmhurst_sap_score.py`:
build_epc() → cert_to_inputs → calculate_sap_from_inputs
↳ every SapResult field pinned at abs=1e-4 against U985 line refs
Any failing pin is definitionally a calculator bug. The user generates
certs in Elmhurst SAP and exports Summary + worksheet ZIPs — no gov.uk
EPB lodgement required.
Extended test case (000565) ready at `sap worksheets/extended test case/`:
- Summary_000565.pdf (input)
- U985-0001-000565.pdf (worksheet ground-truth)
Cert 000565 is a wacky stress-test that exercises 3-4 zero-coverage
cascade paths in one cert: Main + 4 extensions, age mix A through J,
RR on every part with mixed ages, conservatory with fixed heaters,
curtain-wall Ext2 post-2023, mixed wall types (solid brick + stone +
curtain wall), mixed party walls (CU + CF + Unable to determine).
After this cert lands, the user has agreed to generate single-feature
certs (oil only, LPG only, solid fuel only, electric direct only,
multi-main-heating, basement) to surface single-cause calculator gaps.
Handover doc now has implementation outline (mirror
_elmhurst_worksheet_000474.py shape) and a coverage-paths table
showing which targets each fuel-type/config exercises.
Captures the per-cert validation state at HEAD b7fbbcca:
- 5 slices shipped this session: cost cascade β-split (.47), schema
gap closure for real-API battery_capacity (.48), Table 12e
effective-monthly PE factor for PV (.49), §4 seasonal HW for PV β
cascade (.50), UnmappedApiCode strict-raise pattern on API mapper
(.51).
- 769 pass + 0 fail across the full baseline; pyright net-zero on
every touched file.
Crucial finding for the next agent: cohort-2 (38 certs) is chain-
tested at 1e-4 SAP vs worksheet but NOT in test_golden_fixtures.py
— PE/CO2 cascades have NO regression guard. Probed at HEAD:
14/38 cohort-2 certs have non-trivial PE residuals invisible to any
current test, including cert 2102 at +20.4 PE / -0.79 CO2 (single
worst undetected residual in the cohort).
Agreed next slice: add all 38 cohort-2 certs to
test_golden_fixtures.py with current PE/CO2 pinned. Surfaces cert
2102 as the next closure target (worksheet exists under
`sap worksheets/`) and creates PE/CO2 regression guards across the
worksheet-backed cohort.
Open threads ranked by tractability:
- Cert 2102 +20.4 PE — worksheet exists, well-scoped
- PV (233a)+(233b) monthly mystery — documented memory entry; ~0.5
kWh/m² across ASHP cohort
- _api_glazing_transmission strict-raise extension — mechanical
- 8 open-front golden certs (oil + RR) at high residuals — blocked
on worksheets
Fuel-type diversity guidance: heating system breakdown across all
60+ fixtures shows 34 gas, 20 ASHP, 2 oil (both open-front no
worksheets), 0 solid fuel, 0 LPG, 0 electric direct. Closure on
oil + solid fuel + LPG + electric blocked on worksheet availability
— the gov.uk EPB downloads UI returns API JSON only; dr87 worksheets
come from the assessor's tool (typically Elmhurst SAP) export ZIP.
Handover doc at docs/HANDOVER_GOLDEN_COVERAGE.md.
Finalises the handover doc after S0380.49 ships the effective-monthly
Table 12e PE factor for the PV split. Full cohort residual trajectory
table across all four milestones (pre-44 / post-45 / post-48 /
post-49), final cross-cascade architecture diagram, and the punch-list
of open work (β fine-tuning, HP electricity demand, monthly E_PV
distribution) — none in the β-split phase scope, each a candidate
follow-up slice.
Cluster PE residual closed by ~50% magnitude over the phase:
-7..-14 → -2.8..-3.7 kWh/m². CO2 all <0.11 t/yr; SAP all exact.
Updates the PV β-split handover doc after the three new slices land:
- S0380.47 cost cascade wiring (zero cohort impact via Table 32 collapse)
- S0380.48 real-API battery_capacity schema gap (cohort PE +2.7..+8.1
→ -3.5..-4.5)
- Restates the open slice (S0380.49) as wiring effective-monthly
Table 12e PE factor into the PV cascade — the remaining ~4 kWh/m²
PE delta is structural (currently uses annual factors instead of
monthly-weighted).
Key narrative correction: the prior handover's "E_PV magnitude bug"
hypothesis ("cascade thinks 2570 kWh/yr vs worksheet 831") was wrong.
Reading the cert 0380 worksheet PDF directly (dr87-0001-000899.pdf
page 3 line 233) shows -2563.3692 kWh/yr — matching our cascade
exactly. The real bug was the schema dropping flat-shape
battery_capacity, fixed in S0380.48. Lesson captured in the doc:
verify handover-cited numerics against the source PDF before
implementing the prescribed fix (same discipline as spec-floor
skepticism applied to handover claims).
Includes the full PE residual cohort table across all three milestones
(pre-44 / post-45 / post-48) and the Slice 6 implementation outline.
Replaces stale legacy content (cert-mapper-validation workflow, dated
to a 9-triple staging slice) with the current handoff: branch state,
3 shipped slices (S0380.44 → S0380.46), and concrete directives for
the 3 remaining slices (cost cascade wiring, E_PV magnitude audit,
final fixture re-pin).
Companion to docs/HANDOVER_PV_BETA_SPLIT.md.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Documents progress on the SAP 10.2 Appendix M1 β-factor split for the
PE / CO2 / cost cascades + golden-fixture residual closure.
Shipped:
- Slice 1 (S0380.44): pure β-factor calculator module + 13 unit tests
- Slice 2 (S0380.45): wire β into PE cascade
- Slice 3 (S0380.46): wire β into CO2 cascade
Cert 9501 (PV no battery): PE Δ -8.28 → +0.25, CO2 Δ +0.20 → -0.05 —
clean spec validation. The 7-cert ASHP+battery cohort overshoots PE
by +2.7..+8.1 because the cascade's E_PV is ~3× the worksheet's
value (cert 0380 cascade 2570 kWh vs worksheet 831 kWh). E_PV
magnitude audit deferred to Slice 5.
Open:
- Slice 4 (S0380.47, next): wire β into cost cascade
- Slice 5 (S0380.48): E_PV magnitude audit
- Slice 6 (S0380.49): re-pin fixtures + verify chain tests <1e-4
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Session shipped 5 slices that closed the entire cohort-2 API-path
cluster (S0380.39 bulk-fetch, S0380.40 parametrized test, S0380.41
RdSAP 21 → SAP 10.2 glazing alias, S0380.42 Decimal HALF_UP per-window
areas, S0380.43 SAP 631 → spec fuel).
Documents:
- Cross-mapper parity at cascade established for all 38 cohort-2
certs (and 9 cohort-1 ASHP); both paths < 1e-4 vs worksheet.
- Tolerance tightening deferred — 1e-4 is the realistic floor at
HEAD (worst residual 4.91e-5 on cert 2102).
- Lessons learned: GOV.UK RdSAP 21 enum != cascade enum (codes
needing remap are incremental as fixtures surface them);
Decimal HALF_UP per-window areas extends the S0380.34/35
pattern; SAP heating-type → spec fuel dispatch is the new
forcing-function pattern for cert-lodgement inconsistencies.
- Open front: golden-residuals → ~0 on PE/CO2. ASHP cluster
(-7..-15 kWh/m² PE / +0.16..+0.28 t/yr CO2 across 7 certs with
the same PCDB heat pump) is the highest-value single thread —
likely SAP 10.2 Appendix L1 / Table 12 PE-factor or CO2-factor
cascade gap. Three concrete diagnostic probes proposed.
Test baseline at HEAD: 750 pass + 0 fail.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Documents the 5-slice session that closed the prior handover's
"precision floor" cluster end-to-end:
S0380.26 RdSAP10 §5.8 dry-lining adjustment (cert 7700)
S0380.27 floor_construction_type → _main_floor_u_value (cert 9796)
S0380.28 SAP 10.2 Appendix N fn 43 reciprocal η interpolation
(closes the +0.03..+0.06 ASHP cluster cohort-wide)
S0380.29 _ASHP_COHORT_CHAIN_TOLERANCE 0.07 → 0.04
S0380.30 glazing codes 8-15 (RdSAP 21 schema) — closes API path
cohort-1 +0.014..+0.031 cluster
Final state:
Cohort-2 Summary path (38): 33 exact + 5 ≤0.07
Cohort-1 ASHP cohort (7): 6/7 <1e-4 both Summary + API paths
cert 2636 -0.015 (cantilever, path-symmetric) — only open thread
The prior `HANDOVER_CERT_0380_MIT_CASCADE.md` had concluded the
+0.04 ASHP cluster was unfixable without Elmhurst access; the
spec citation (SAP 10.2 Appendix N fn 43) was sitting in the same
PDF that handover referenced. Be skeptical of "spec-precision
floor" framing — see [[feedback-spec-floor-skepticism]].
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Captures 5 slices shipped this session (S0380.21..25):
- Table 3a rows 1+4 + PCDB keep-hot dispatch
- Per-BP roof exposure (Ext1 flat roof on flats)
- RdSAP §11.1 b) % of roof area PV synthesis
- SAP code 631 → house coal secondary fuel
- SAP codes 2111/2113 → control type 2
Cohort-2 outcome: 22/38 exact (<1e-4), max residual ±0.55 SAP,
0 RAISES, 0 big-gaps. All structural cascade gaps closed.
Open threads diagnosed in detail:
1. Cert 7700 -0.44 SAP — wall U code conflict
(_WALL_INSULATION_NONE=4 vs Elmhurst "As Built"=4). Wider than
a single slice; needs regression testing.
2. Cert 9796 +0.55 SAP — MIT precision floor (Mid-Terrace
bungalow + HP, +0.06°C across all months). Same mechanism as
cohort-1 HP-COP residuals.
3. API-path closure for all 38 certs (deferred).
4. Tighten cohort-1 chain tests to 1e-4 once thread 2 closes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds the next-agent handover and the BRE technical papers referenced
by the cohort-2 negative-band investigation:
- `HANDOVER_TABLE_3A_NO_KEEP_HOT.md` — picks up from Slice S0380.20.
Covers cohort distribution at HEAD `4879e8c3`, the verified
Table 3a Row 1 spec formula `(61)m = 600 × fu × nm / 365`, the
dispatch recipe for `pcdb_combi_loss_override`, watch-outs (cert
0360 / cohort-1 cert 000490 behaviour after the slice lands), the
diagnostic probe script, test baselines, and the open-thread
priority list (Ext1 roof, HP-COP, big-gap 2102, API path, parity).
- `specs/STP09-B04_Combi_boiler_tests.pdf` — 2009 BRE methodology
paper (Alan Shiret, BRE) defining the combi-loss test programme
that produced the SAP Table 3a 600/900 kWh/yr keep-hot assumptions.
Source: https://bregroup.com/documents/d/bre-group/stp09-b04_combi
_boiler_tests.
- `specs/sap10 technical papers/S10TP-{02..13}.pdf` — full SAP 10
supporting technical paper set (Issue 1.2 / 1.3 / 1.4 across the
eight papers). S10TP-12 §9.4 confirms: "No changes to the SEDBUK
calculation method for water heating efficiency were considered
necessary" — so the STP09-B04 (SAP 2009) Table 3a methodology
carries through to SAP 10 unchanged.
These docs replace web-fetched references with locally-tracked copies
so the slice S0380.21 implementor can grep / pdftotext them directly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Hands off the next workstream: the 38 cert subdirs at
`sap worksheets/additional with api 2/`. Each subdir is named after
the 20-digit EPC cert reference and contains a Summary PDF + dr87
worksheet PDF. API JSONs are NOT in the dataset but ARE fetchable
via the existing `EpcClientService` (token in `backend/.env` as
`OPEN_EPC_API_TOKEN`).
User's stated ordering: Elmhurst Summary mapping FIRST, API path
SECOND. Folder names = cert refs; need to verify the matching before
bulk-pinning (any mis-filed PDF would silently invalidate slice
work).
Handover ships with verified dataset and first-attempt baselines:
- Folder-vs-cert sweep: **38/38 match** at handover (postcode
parity check between Summary PDF and Open EPC API).
- First-attempt Summary-path probe across 38 certs:
24 ✅ closed at ±0.07 (first-try, zero new slices needed)
9 ~ small gap (<1 SAP) — likely 1 slice each
3 ✗ big gap (>1 SAP) — multi-slice investigation
2 RAISES UnmappedElmhurstLabel: cylinder_size='Normal'
The two `Normal` cylinder raises are the immediate Phase 1 slice —
Slice S0380.15's strict-enum pattern paid off on its first new
cohort by surfacing the gap at extraction time instead of as a
downstream SAP delta.
Workstream phases documented in the handover:
Phase 0: folder-vs-cert sweep (already done — 38/38)
Phase 1: fix 'Normal' cylinder unmapped-label raise
Phase 2: bulk-pin the 24 first-try-closures as chain tests
Phase 3: close the 9 small-gap certs one slice each
Phase 4: investigate the 3 big-gap certs (likely HP-routing)
Phase 5: fetch + persist API JSON for all 38, run API path tests
Phase 6: cross-mapper EPC parity (Summary EPC ≡ API EPC) — the
user's stated north-star
Includes:
- Paste-able diagnostic probe scripts (Summary path + folder-vs-
cert sweep + .env loader + EpcClientService usage example).
- Full table of first-attempt deltas per cert with classifications.
- All 15 prior-session slice commits indexed.
- Memory references to the slicing / methodology conventions.
- Per-cert diagnostic recipe template.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The 7-cert ASHP cohort API path is closed at the spec-precision
floor (this session). Next workstream is the Summary path for cert
0380 — the user's preferred starting point because the Summary +
worksheet PDFs surface labelled intermediate values that the API
path lacks.
Cert 0380 Summary PDF (`Summary_000899.pdf`) is already in the
test fixtures dir; just needs a path constant + RED chain test.
Previous handover flagged the extractor at Δ -58.37 SAP for HPs
— the immediate diagnostic is whether the mapper surfaces
main_heating_category=4 and main_heating_index_number=104568.
The handover also documents the user's "Elmhurst-specific"
challenge worth re-exploring: closed boiler certs hit 1e-4 vs
Elmhurst via the same cascade, so the residual is precisely at the
Appendix N3.6 PSR interpolation step. Cross-check with the BRE
xlsx canonical calculator is suggested.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Updates the handover with the final state after 11 slices:
- All 7 ASHP cohort certs cascade SAP integer == lodged (residual 0).
- Continuous SAP residual clusters within +0.030..+0.060.
- BRE web confirmed max_output_kw values (4.39 / 3.933) match cascade
exactly — the remaining drift is NOT a max_output bug.
- Cascade (39) annual avg HLC EXACTLY matches worksheet (39) at 4 dp
for cert 0380 and 2225 — HLC is NOT the bug either.
- Implied drift is ~0.15% in η_space interpolation precision, likely
in Elmhurst's internal rounding convention (not in public SAP 10.2
spec or BRE PCDB).
Recommends Path A (ship Layer 4 chain tests at ±0.07 SAP tolerance)
as the spec-precision floor. Path B (close to 1e-4) requires Elmhurst
implementation access that's outside public docs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Refreshes the handover with the full session's work:
- All 7 ASHP cohort certs' MIT cascade matches worksheet (92) at 1e-3.
- 6/7 cohort SAP residuals cluster at +0.03..+0.06 vs worksheet.
- Identified PSR-formula drift root cause: max_output_kw ≈ 4.40 kW
back-solved from 3 certs' worksheet η_space pins, vs the 4.39 lodged
at PCDB position 47 (likely a field-position misread; needs BRE web
cross-check for PCDB 104568 / 102421).
- Identified cert 2636's +0.49 outlier as missing cantilever Exposed
floor (3.74 m² = upper-floor 42.92 − ground-floor 39.18 area diff).
Recommends Path A (resolve max_output + cantilever to land 1e-4) or
Path B (widen Layer 4 tolerance to 0.1 with documented limitations).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Session shipped 6 slices closing cert 0380's SAP residual from
+0.5999 → +0.0594 vs worksheet 88.5104. The MIT cascade now matches
worksheet line (92) at 1e-3 per month and is spec-faithful through
SAP 10.2 Appendix N3.5 + Equation N5. Remaining residual is a
single PSR-formula divergence (cascade PSR 1.4266 per spec vs
worksheet-implied 1.4321, ~0.4%) that propagates to η_space at 0.2%
and ~0.045 SAP. Three candidate root causes documented; investigation
deferred to next session as the blocker for slice 102f's Layer 4
1e-4 chain test.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cert 0380 (semi-detached bungalow ASHP) was the prior handover's
"defer until HP go-ahead" pilot. Three slices this session closed
the dwelling-shape part of the gap:
- 101a: glazing_type=14 → DG/TG post-2022 (windows HLC exact)
- 101b: cavity wall + filled cavity + external insulation
(composite U via Table 14 R_ins + 2 d.p. round; walls HLC exact)
+ Table 11 cat-4 secondary fraction = 0
- 101c: Table 4f cat-4 pumps/fans kWh = 0
(37) total fabric heat loss is now EXACT vs worksheet 96.0889.
Remaining gap (Δ +2.92 SAP) is dominated by the hot water cascade:
the cert lodges a 160 L cylinder (storage loss + primary loss) and
the HW HP COP is model-specific (PCDB index 104568 → 1.711 per
worksheet, not the Table 4a generic 2.3 our cascade uses). Both
require new cascade work — HP HW-specific COP from PCDB plus
cylinder storage/primary loss application.
Cert 0380's HW work will benefit all 6 sibling ASHPs sharing PCDB
idx 104568 (and partially the 102421 outlier).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cert 9501 (top-floor flat + RR + measured PV) is now CLOSED on both
Summary and API paths at 1e-4 vs worksheet 68.5252 (Slices 99a-99e
on Summary + 100a-100c on API). Three boiler certs in total now
have Layer 4 production gates.
Updated handover lists the 7 ASHP workstream (still deferred), the
8 cohort certs without worksheets (residuals tightened by Slice
100c's gap-aware DG-pre-2002 glazing lookup), and captures the 7
key learnings from cert 9501 closure as guidance for the HP
workstream.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Captures session state after cert 0330 closed both Summary and API
Layer 4 1e-4 gates (Slices 96-98). Cert 9501 fixtures are staged
(commit 5d1778ac) but the Summary path is RED at Δ -5.25 SAP because
the cert is a flat with RR + party-floor / party-ceiling — a
fundamentally different cascade shape from the boiler houses we've
validated.
Handover quantifies the cascade-component gaps (-69.92 W/K on walls
because RR gables aren't surfaced, +9.25 W/K on floor because the
party-floor exposure isn't recognised, +7.36 W/K on party walls
because U_party=0 isn't being applied), lists the 4 fixes likely
needed in slice order, and leaves the heat-pump workstream sketch
intact for when the user gives the go-ahead.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Rewrites the cert 001479 closure handover into a forward-looking
brief for the new workstream: validating the API EpcPropertyDataMapper
against 9 newly-staged (Summary + worksheet + API) cert triples.
Key contents:
- User's stated workflow (verbatim): Summary path proves itself
against the worksheet → becomes canonical reference for API parity.
- Folder-structure changes since the prior handover were written
(packages/domain/ removed; sap10_calculator + sap10_ml now at the
repo root under a PEP 420 namespace; docs/sap-spec/ moved into
domain/sap10_calculator/docs/; PCDB data into tables/pcdb/data/).
- New test data layout: `sap worksheets/Additional data with api/
<cert-ref>/{Summary_NNNNNN.pdf, dr87-0001-NNNNNN.pdf}`.
- Cert reference table with heating type, PCDB index, worksheet SAP,
TFA, bp count, dwelling type for all 9 triples.
- Major scope discovery: 7 of 9 are Air Source Heat Pumps (PCDB
104568 / 102421). The mapper has never been validated against HPs;
cert 0380 pilot showed catastrophic deltas (Summary -70 / API -18
SAP vs worksheet). Recommended deferring HP certs until boiler
workflow is proven.
- Cert 0330 (mid-terrace gas boiler) pilot status: fixtures staged
uncommitted; Summary path +0.47 SAP, API path +2.15 SAP vs
worksheet 61.5993. Cascade-component diff localises 2 specific
gaps (windows HLC +6.71 W/K likely from glazing_type=14 missing
from Slice 93's transmission map; HW kWh +1060 needs §4
subsystem probe).
- Tooling shortcut: use OPEN_EPC_API_TOKEN (not EPC_AUTH_TOKEN) in
backend/.env with EpcClientService._fetch_certificate(cert_ref)
to fetch raw JSON.
- First actions for next agent: confirm baseline, commit cert 0330
fixtures, add RED Layer 2 test, iterate.
Lesson preserved: cohort hand-builts encode non-spec quirks
(e.g. has_suspended_timber_floor=False to override §(12) spec
inference and match the non-spec worksheet). Cross-check against
spec-inferred mapper output before trusting hand-built fields.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Locality of reference — SAP-specific docs, specs, and runtime data
now live alongside the calculator that consumes them, mirroring the
prior packages→domain layout moves.
Move targets:
- Narrative MDs → domain/sap10_calculator/docs/
NEXT_AGENT_PROMPT.md, HANDOVER_NEXT.md, SAP_CALCULATOR.md
- Spec PDFs → domain/sap10_calculator/docs/specs/
RdSAP 10 Specification 10-06-2025.pdf
PCDF_Spec_Rev-06b_12_May_2021.pdf
sap-10-2-full-specification-2025-03-14.pdf
sap-10-3-full-specification-2026-01-13.pdf
- PCDB runtime data → domain/sap10_calculator/tables/pcdb/data/
pcdb10.dat (8.3MB) + 7× pcdb_table_*.jsonl (18MB total)
Path code rewrites (load-bearing):
- tables/pcdb/__init__.py: replaced parents[4]/'docs'/'sap-spec' with
Path(__file__).resolve().parent/'data' for Table 105 JSONL loading.
- tables/pcdb/postcode_weather.py: same rebase for the pcdb10.dat path
read by _postcode_climate_table().
- tables/pcdb/etl.py __main__: same rebase for the manual ETL invocation
(source + output_dir both now point inside the package).
- tests/test_pcdb_etl.py: _PCDB_DAT_PATH now derives from
parents[1]/'tables'/'pcdb'/'data' (was parents[3]/'docs'/'sap-spec').
Citation rewrites:
- 12 .py docstrings and 4 .md docs (ADRs + READMEs + narrative docs)
had `docs/sap-spec/<file>` strings rewritten to their new locations.
- Two cases where the catch-all sed misfired (an ADR-0009 line about a
PCDB extract; the pcdb __init__.py docstring about ETL output) were
hand-corrected to point at tables/pcdb/data/ rather than docs/specs/.
docs/sap-spec/ is now empty (will be removed in a follow-up sweep or
left as a vestigial empty dir for future repurposing). ADRs 0009 and
0010 remain at docs/adr/ — they're part of the chronological
cross-cutting decision log, not calculator-specific narrative.
Verified:
- Calculator's 1e-4 production gate
(test_api_001479_full_chain_sap_matches_worksheet_pdf_exactly) GREEN.
- Wider sweep (domain/sap10_calculator/ + domain/sap10_ml/): 1654
passed / 20 failed — exact pre-move baseline. All 20 failures
pre-existing (10 hand-built skeleton + 4 cohort chain + 6 cohort
diff).
- Pyright net-zero on the 4 touched runtime/test files (0 errors)
and unchanged on heat_transmission.py (13) / cert_to_inputs.py (35) /
mapper.py (33).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>