Commit graph

7546 commits

Author SHA1 Message Date
KhalimCK
ebca28f704
Merge pull request #1447 from Hestia-Homes/fix/electric-underfloor-pathway-and-noop-walls
Electric underfloor gets its heating pathway; wall insulation gated on derived U (WS2 of #1435)
2026-07-03 13:17:36 +01:00
Jun-te Kim
5c510e1b15
Merge pull request #1439 from Hestia-Homes/feat/sap-corpus-campaign
test(accuracy): corpus-1000 — 74.2% → 77.7% within-0.5, MAE 0.721 → 0.637 (8 fixes; mapper+calc validated vs Elmhurst)
2026-07-03 12:52:57 +01:00
Khalim Conn-Kowlessar
bc39030707 The e2e candidate menu is generated from the Effective EPC, not the lodged cert 🟩
The printed "candidate measures considered" now matches what the
orchestrator actually offered — on 711795 the lodged cavity wall printed
a cavity-fill candidate the plan (timber-frame effective wall) never saw.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:42:29 +00:00
Khalim Conn-Kowlessar
da4aec9840 Treatable old-band solid walls keep their EWI and IWI options under the gate 🟩
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:41:56 +00:00
Khalim Conn-Kowlessar
7a039d30bc Cavity fill is withheld when it cannot lower the derived wall U 🟩
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:41:33 +00:00
Khalim Conn-Kowlessar
5f74c34f9a Cavity fill is withheld when it cannot lower the derived wall U 🟥
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:41:02 +00:00
Khalim Conn-Kowlessar
7c8b161653 Solid-wall insulation is withheld when it cannot lower the derived wall U 🟩
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:40:41 +00:00
Khalim Conn-Kowlessar
574e58a5c8 Solid-wall insulation is withheld when it cannot lower the derived wall U 🟥
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:39:32 +00:00
Khalim Conn-Kowlessar
573588d4e7 Underfloor overrides no longer log an incomplete companion set 🟩
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>
2026-07-03 11:37:57 +00:00
Khalim Conn-Kowlessar
07362b357a Electric underfloor override drags the conservative Group 7 control (2701) 🟩
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:37:19 +00:00
Khalim Conn-Kowlessar
566374bf34 Electric underfloor override drags the conservative Group 7 control (2701) 🟥
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:36:51 +00:00
Khalim Conn-Kowlessar
57e899e8d9 Electric underfloor override stamps the Table 4a underfloor category (8) 🟩
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:36:30 +00:00
Khalim Conn-Kowlessar
51fa497793 Electric underfloor override stamps the Table 4a underfloor category (8) 🟥
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:35:55 +00:00
Khalim Conn-Kowlessar
e110dd0746 Record ADR-0050 (underfloor override companions) and ADR-0051 (wall U-value gate) 🟪
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>
2026-07-03 11:35:05 +00:00
Daniel Roth
7abf466b56
Merge pull request #1445 from Hestia-Homes/feature/abri-api-integration
Abri deal abandonment check
2026-07-03 11:48:37 +01:00
Daniel Roth
1a5368571f add typehint 2026-07-03 10:46:24 +00:00
Daniel Roth
f4f915cfb7 Abri deal abandonment names its attempt threshold 🟪
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:19:06 +00:00
Jun-te Kim
645789456e docs(corpus): find the third driver — mixer-shower default, 91% of gap now traced
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>
2026-07-03 10:19:05 +00:00
Daniel Roth
18989252f4 Deal differ detects number of attempts changes for db update 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:17:51 +00:00
Daniel Roth
c00ae894ee Deal differ detects number of attempts changes for db update 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:14:22 +00:00
Daniel Roth
58ce855e0b Abri deal abandonment fires only when the deal newly becomes abandoned 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:13:58 +00:00
KhalimCK
f822f8a15d
Merge pull request #1443 from Hestia-Homes/fix/electric-room-heater-overlay-companions
Electric room heaters override forces its category + control (fix silent storage-companion inheritance)
2026-07-03 11:13:35 +01:00
Daniel Roth
9559f23741 Abri deal abandonment fires only when the deal newly becomes abandoned 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:12:59 +00:00
Daniel Roth
6de0da869e Abri deal abandonment requires a negative outcome 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:11:14 +00:00
Daniel Roth
41d62ce2b2 Abri deal abandonment requires a negative outcome 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:10:26 +00:00
Daniel Roth
88093eb7cd Abri deal abandonment requires at least three parseable attempts 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:10:03 +00:00
Daniel Roth
af85e0ed2b Abri deal abandonment requires at least three parseable attempts 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:07:38 +00:00
Daniel Roth
79423f594c Abri deal abandonment ignores deals that are not Abri condition deals 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:06:53 +00:00
Daniel Roth
33848a76fe Abri deal abandonment ignores deals that are not Abri condition deals 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:04:45 +00:00
Daniel Roth
262f22764a Abri deal abandonment triggers after three attempts with a negative outcome 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:03:57 +00:00
Daniel Roth
aca507cc47 Abri deal abandonment triggers after three attempts with a negative outcome 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:03:42 +00:00
Jun-te Kim
d15ea8b7d4 docs(corpus): find the second driver of 100061275133's residual gap
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>
2026-07-03 09:52:22 +00:00
Jun-te Kim
f69d345493 docs(corpus): correct 100061275133 pin comment — real driver is Table 11
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>
2026-07-03 09:41:09 +00:00
Daniel Roth
701a6aa5cd Merge branch 'main' into feature/abri-api-integration 2026-07-03 09:40:18 +00:00
Daniel Roth
71a309ad0a
Merge pull request #1442 from Hestia-Homes/feature/abri-api-integration
Abri API Integration: check for tenant data fetch trigger
2026-07-03 10:33:44 +01:00
Jun-te Kim
5abc87ea18 chore(corpus): reconciliation pass over the 1-2 SAP band, no new bug found
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>
2026-07-03 09:26:05 +00:00
Khalim Conn-Kowlessar
dd30903ace Merge remote-tracking branch 'origin/main' into fix/electric-room-heater-overlay-companions 2026-07-03 09:25:11 +00:00
Khalim Conn-Kowlessar
244c5b65ed Document heating-companion coherence: category/control forced, fuel/meter deferred (ADR-0048)
ADR-0048 records why a system-replacing heating override must emit a
complete companion set — category and control archetype-forced for
coherence, fuel and meter deferred where multiple values are valid, and
an unmapped companion logged rather than silently inherited. Adds the
Heating Companion Set glossary term to CONTEXT.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 09:21:47 +00:00
Jun-te Kim
6c1828e8bf chore(hyde): fix 100061275133 Elmhurst build — 0 fans + PCDB exact boiler
ventilation(): the cert lodges no extract-fan count and RdSAP 10 Table 5's
age-band B default is 0, but the build entered 1 — inflating Elmhurst's own
(8)/(21) infiltration lines relative to both the cert and our engine.

space_heating(): switched from the generic "Combi condens" SAP-Table dialog
code (84% efficiency, no PCDB record) to elmhurst_lib.set_pcdb_boiler(18908)
via clear_main_heating_code — resolves the exact lodged product (Worcester
Greenstar 4000, 88.70%) and its correct keep-hot classification (None),
matching the SAP engine's own PCDB lookup and removing the "Standard Combi"
keep-hot artifact the reused generic code carried.

Also corrected the file's stale docstring (described a different property
entirely — mid-terrace/250mm/DUAL meter/11 windows/lodged 63 — left over
from a copy-paste).

Verified against the refreshed worksheet: (21) shelter-adjusted ACH 0.6938
now EXACT vs our engine's ventilation_from_cert; (61) combi loss monthly
kWh matches ours to ~0.01 kWh (was carrying a ~360 kWh/yr keep-hot artifact).
Both open items from the PR #1439 handoff are resolved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 09:20:12 +00:00
Khalim Conn-Kowlessar
962a443ed2 A complete room-heater overlay does not log a companion gap 🟩
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 09:17:06 +00:00
Khalim Conn-Kowlessar
390e3e89d7 The overlay logs an error when it cannot complete a heating companion set 🟩
A system-replacing override whose category or control is not yet mapped
now logs an error naming the archetype and code, so the incomplete
companion set (which otherwise silently inherits the replaced system's
value) is visible for review — log-and-continue, matching flag_fuel_mismatch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 09:16:25 +00:00
Khalim Conn-Kowlessar
ea113b58fb The overlay logs an error when it cannot complete a heating companion set 🟥
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 09:15:31 +00:00
Khalim Conn-Kowlessar
ffd21689fd An electric room heaters override sets the room-heater charge control 🟩
Control 2601 (SAP Table 4e Group 6 room-heater, +0.3 C conservative
default) now overlaid for electric room heaters, matching the gas/oil/
solid siblings, so a replaced storage heater's manual charge control
2401 (+0.7 C) no longer survives and over-warms the modelled dwelling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 09:13:32 +00:00
Khalim Conn-Kowlessar
cfd9799500 An electric room heaters override sets the room-heater charge control 🟥
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 09:13:03 +00:00
Jun-te Kim
dee72bbdfa fix(rdsap): §5 (12) floor infiltration falls back to floors[].description
_has_suspended_timber_floor_per_spec only read the Main bp's per-part
floor_construction_type lodgement; the gov-API mapper frequently leaves
that None even when the global epc.floors[].description carries an
explicit "Suspended, ..." observation. _main_floor_u_value already fell
back to this joined description for the U-value calc — the infiltration
rule did not, so a genuinely suspended-timber floor silently entered
(12)=0 instead of 0.2 unsealed. Extracted the shared
_effective_floor_description helper and added a tri-state resolver
(explicit lodgement -> description, excluding "not timber" -> Table 19
footnote-1 age-A/B default) so both paths agree.

Cert 100061275133 (Elmhurst-validated build, PR #1439 handoff): engine
77.24 -> 76.33, now an exact match to lodged (76). Corpus gauge 77.7% ->
77.8% within-0.5, MAE 0.637 -> 0.636; floors ratcheted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 09:12:19 +00:00
Khalim Conn-Kowlessar
bf032d17d0 An electric room heaters override sets the room-heater heating category 🟩
Category 10 (SAP Table 4a Room heaters) now overlaid for electric room
heaters (691-701), so a replaced storage heater's category 7 no longer
survives onto the effective cert and mis-bills via the Table 12a resolver.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 09:12:19 +00:00
Khalim Conn-Kowlessar
5e7e51d8b2 An electric room heaters override sets the room-heater heating category 🟥
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 09:11:38 +00:00
Daniel Roth
05ca0bb280 move static method below non-statics 2026-07-03 08:33:10 +00:00
Daniel Roth
a36fe00132 Abri tenant data fetch resolves abri deals by associated project id 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 08:28:25 +00:00
Daniel Roth
5df1237b90 Abri tenant data fetch requires a parseable new commencement date 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 08:27:42 +00:00