Reference the calculator-side wall_construction=6 disambiguation issue from the strict-xfail tripwire and ADR-0019, so the blocker is traceable both ways. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.6 KiB
Wall Insulation Eligibility (cavity vs IWI vs EWI)
The solid-wall Recommendation Generator must decide, per Property, which wall-insulation Option(s) to offer. We decided eligibility is fixed first by wall construction, then narrowed by planning status, and that External (EWI) and Internal (IWI) wall insulation are two competing Measure Options under one "Main wall" Recommendation (the Optimiser picks at most one), consistent with ADR-0016 and the "cavity-fill vs EWI" exclusivity already described in CONTEXT.md.
Decision
By construction (keyed on the wall_construction code, which is consistent across the API and Elmhurst paths for codes 1-5; the wall description is empty on the Elmhurst ingestion path so it can't be the primary signal — it's a fallback for the ambiguous codes (cob 7) and for refining the as-built trigger on the API path).
System-built is keyed on wall_construction == 6 (WALL_SYSTEM_BUILT; the Elmhurst SY System build label). This code is currently overloaded: B Basement wall also maps to 6 (BASEMENT_WALL_CONSTRUCTION_CODE, mapper.py:2100), so the generator additionally guards on main_wall_is_basement — a basement wall is never solid-wall-insulation-suitable and is excluded regardless of construction. Because main_wall_is_basement is presently derived as wall_construction == 6, every code-6 wall is treated as basement today, so the system-built branch is inert until the calculator disambiguates system-built from basement (target: MAIN wall_construction == 6 with main_wall_is_basement False — tracked in Hestia-Homes/Model#1177). The strict-xfail pin test_system_built_generator_offers_ewi_and_iwi_each_pinning_its_after is the tripwire for that fix. Note wall_construction == 8 is Park home (PH) on the Elmhurst path, not system-built — do not key system-built on 8.
| Construction | Cavity fill | IWI | EWI |
|---|---|---|---|
| Cavity | ✅ only | ❌ | ❌ |
| Solid brick | — | ✅ | ✅ |
| System built | — | ✅ | ✅ |
| Timber frame | — | ✅ | ❌ (not constructable) |
| Cob / Granite-whinstone / Sandstone-limestone | — | ❌ | ❌ |
Planning gates (on top), using three distinct flags (see ADR-0020):
- Conservation area or Flat → remove EWI (external-appearance / whole-block constraints); IWI still offered.
- Listed or Heritage → remove both EWI and IWI (protected fabric).
A Recommendation is produced only when the wall is genuinely uninsulated (description contains "no insulation"), at a fixed 100 mm insulation depth.
Considered options
- Mirror the legacy
is_suitable_for_solid_insulation/ewi_validrules verbatim. Rejected in part: legacy collapsed all three planning flags into onerestricted_measuresboolean that blocked EWI only. We keep the flags distinct so listed/heritage can block IWI too — a deliberate strengthening. - Offer solid-wall insulation on cob/stone (the calculator can model it — Elmhurst produces valid after-certs). Rejected: recommending standard EWI/IWI on breathable cob/rubble-stone fabric risks trapping moisture; we do not auto-suggest it.
Consequences
- Cob and both stone types get no wall-insulation recommendation at all, even though the SAP calculator scores them fine — this is a deliberate building-pathology safeguard, not a gap.
- The conservation/listed/heritage gate depends on Property data not yet ingested (ADR-0020); until that lands the gate is an explicit generator input defaulting to "unrestricted", so the offline generator over-offers EWI in the interim. Not production-exposed.