Model/datatypes
Khalim Conn-Kowlessar 97f44b5364 fix(extractor): capture all 17 openable §11 windows on cert 001431
cert 001431's §11 lodges 17 windows but only 14 surfaced, via two distinct gaps:

1. Extractor (_extract_windows_from_layout): the one "Double glazing, known
   data" row whose §11 Data-Source cell is "BFRC data" was rejected — it is
   laid out as a standalone keyword line with the U-value on the next line
   and lodges no Frame Type/Factor/Gap cells, so it never matched the joined
   "<source> <U>" Manufacturer-line shape. Now anchored by a standalone
   data-source form, with the RdSAP 10 §3.7 default frame factor (0.7) for
   the absent frame cell.

2. Mapper (_is_elmhurst_roof_window): the two "Double pre 2002" rows
   (U 3.1 / 3.4 > 3.0) were reclassified as roof windows by the U-value
   backstop even though both are lodged on an "External wall". A window
   lodged on a wall is vertical by definition; guard the U-value backstop so
   it only fires when location/BP give no roof signal.

With both closed: 17 sap_windows, 0 misrouted to sap_roof_windows.

Re-homed onto the mapper-validation line from feature/bill-derivation
(orig f68cea27); the modelling-only regression test
(tests/domain/modelling/test_window_extraction_001431.py) stays on
bill-derivation. KNOWN: the mapper guard breaks cert 000516's
test_summary_pdf_mapper_chain pins (W6 U=3.10 routing) — must be resolved
before this PRs to main.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 19:00:02 +00:00
..
epc fix(extractor): capture all 17 openable §11 windows on cert 001431 2026-06-05 19:00:02 +00:00
magicplan typing and renaming 🟪 2026-05-07 13:26:49 +00:00
__init__.py further breaking up code 2023-07-20 12:24:34 +01:00
datatypes.py further breaking up code 2023-07-20 12:24:34 +01:00
enums.py completed build of new demo portfolio - some fixed required still 2023-11-20 14:42:16 +00:00