Regression guard: category 8 + control 2701 keep the ADR-0048 coherence
invariant satisfied for SAP codes 421/422/424.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WS2 of PRD #1435, diagnosed on property 711795: an electric-underfloor
override inherits the replaced community-heating category (no pathway,
baseline mis-rated 51 vs 67), and wall generators offer £4k insulation
that cannot change an age-band-L wall's derived U (0.280 → 0.280).
Glossary: Wall U-Value Gate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sizing selects the aroTHERM plus rung nearest PSR ~0.8 (0.8 x design heat
loss) — the Appendix-N efficiency peak, reproducing the pump a real
installer fits — rather than the MCS PSR>=1.0 capacity target, which
oversizes. Validated against the relodged Elmhurst ASHP cert (delta 0
held at the 5 kW Vaillant); the two self-snapshot pins re-pin to their
correctly-sized larger pumps, and the orchestrator/harness thread the
calculator's design heat loss so production sizes to the dwelling. Manual
SapResult test stubs carry the new design_heat_loss_kw field.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
_ashp_option threads its sized design heat loss into ashp_cost_inputs so
the cost band and the pump's efficiency record share one figure — a leaky
dwelling's larger pump is priced on the matching band.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
_ashp_option now selects the aroTHERM plus PCDB record matching the
threaded design heat loss (floor-area proxy fallback), so the overlay's
efficiency anchor is sized to the dwelling instead of a fixed 5 kW unit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Walked the water-heating worksheet section: assumed occupancy (42) matched
exactly (2.4234 both sides), but (43) average daily hot water use was
117.41 L/day (Elmhurst) vs 110.73 L/day (ours) — same occupancy, different
shower/bath demand. Root cause: the cert's shower_outlets field is
genuinely unlodged, which the mapper correctly maps to 0 mixer showers
per its documented, already-validated "no entry = no shower" convention.
Elmhurst's build shows a "Non-electric shower" fixture anyway — its UI
silently defaults one when the build script doesn't explicitly configure
"0 showers" to match the cert.
Verified: a single 7 L/min vented mixer reproduces Elmhurst's (42a)
monthly series exactly (4 d.p., all 12 months) and closes hot water to
2616.04 vs Elmhurst's 2616.03. Corpus-wide check across 170 certs sharing
this "bath present, no shower data" pattern shows no systematic bias
(mean dSAP +0.12, median -0.04) — confirms the mapper convention is
correct on average; this is a build-entry artifact on this one cert, not
a mapper bug (no code change warranted).
Combining all three found causes (window orientation, Table 11, shower
default): SAP 72.4567 vs Elmhurst's precise 72.0681 — residual 0.39,
~91% of the original 4.26-point gap now precisely explained.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
design_heat_loss_kw = annual-average HLC x 24.2 K (SAP design temperature
difference) / 1000, the quantity Appendix N's PSR divides a heat pump's
rated output by — surfaced so the ASHP recommendation can size the pump.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The sizing ladder (Vaillant aroTHERM plus 3.5-12 kW PCDB records) picks
the smallest rung whose rated output meets the design heat loss, so SAP
10.2 Appendix N reads the heat-pump efficiency near its PSR peak instead
of collapsing on an undersized fixed unit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Walked the worksheet section-by-section (dimensions, ventilation, fabric,
internal/solar gains, MIT, space-heating requirement, fuel cost) against
the calculator's matching intermediates. Internal gains and heat loss
matched closely, but solar gains (worksheet line 83) was 2.2x off in
January (56.9 W vs our 123.4 W) — traced to the Elmhurst BUILD entering
all 12 real windows (3 orientations: NW 7.05 m2, NE 1.21 m2, SE 7.06 m2)
as a single synthetic 15.32 m2 "North" group, understating solar gain.
Verified by reproducing both build artifacts in the calculator: real
windows + real Table-11 gating = 76.33 (our answer, matches lodged 76
exactly); collapsing to a synthetic single-North window + forcing Table
11 on = 72.62, reproducing Elmhurst's 72 almost exactly. Confirms neither
residual is a mapping or calculator bug — one is a deliberate,
regression-tested spec choice (Table 11) and the other is an artifact of
how this specific Elmhurst reconciliation build was entered.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The prior comment blamed a stale build-side combi artifact (already fixed
this session) and my earlier conversational claim that Elmhurst's overall
SAP used regional weather was wrong too — verified the worksheet's (5)
dwelling volume and wind table match our UK-average rating cascade exactly.
The actual, now-quantified driver: Elmhurst's worksheet (201)/(202)/(215)
show it unconditionally applies SAP 10.2 Table 11's 10% secondary/portable-
electric-heater fraction based on main heating category alone, with no
secondary lodged on the cert. Our `_secondary_fraction` deliberately gates
this on an actual lodged/forced secondary (see the adjacent S-B30 note:
applying it unconditionally regressed the full 1000-cert corpus MAE by
+0.16). Forcing Table 11 on for just this cert moves 76.33 -> 73.62 (~62%
of the 76.33-vs-72 gap) — confirms this, not a mapping error, drives the
residual. Documented so the next reader doesn't re-litigate it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per the PR #1439 handoff: swept every cert now sitting at |Δ| in [1.0, 2.0)
(58 certs) using the cost-vs-demand signature bucketer (why_diverge.py's
logic) plus field_bias.py's full-corpus subgroup scan (re-run clean after
the two engine fixes above — no |meanΔ|>=0.5 systematic subgroup with
coherent median).
Breakdown: 17 room-in-roof (already spec-mandated/worksheet-validated per
PRs #1440/#1441), 7 electric cost/tariff variants (spec-faithful vs lodged,
consistent with the diagnosed electric cluster), 4 non-electric cost
residuals (spec-faithful), ~26 non-electric fabric/demand certs. Manually
inspected geometry (floor areas/perimeters/heights, wall/roof codes,
window/door counts) for the 4 largest fabric/demand outliers in the band
(100031768368, 100070450818, 100110097281, 100051051866) — no data-entry
anomaly comparable to the earlier 12109191 decimal-floor-area bug. This
confirms the handoff's "our calc faithful, lodged differs" pattern holds
across the band; no engine bug survived the pass. Notes appended per-cert
in worklist.md (`<-`, preserved by build_worklist.py reruns).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>