Model/domain
Khalim Conn-Kowlessar 546bca3277 Slice S0380.177: oil 6 boiler interlock from room thermostat absence
oil 6 (B30K standard liquid-fuel boiler, Table 4b code 126 winter 80 /
summer 68) lodges Main Heating Controls Sap code 2101 ("No time or
thermostatic control of room temperature") WITH a cylinder thermostat.
The cascade's `no_interlock` gate only checked the cylinder thermostat,
so oil 6 kept raw efficiency despite the P960 worksheet header lodging
"Boiler Interlock: No".

Per RdSAP 10 §3 (PDF p.57): boiler interlock is "assumed present if
there is a room thermostat and (for stored hot water systems heated by
the boiler) a cylinder thermostat. Otherwise not interlocked." Control
code 2101 (and 2102 "Programmer, no room thermostat") provides no room
thermostat — the two Table 4e Group 1 rows carrying the "+0.6 °C /
Table 4c(2)" annotation — so the boiler is NOT interlocked regardless
of the cylinderstat. SAP 10.2 Table 4c(2) (PDF p.169) "No thermostatic
control of room temperature – regular boiler" then deducts 5pp from
BOTH the Space and DHW seasonal efficiency.

Three changes in cert_to_inputs.py:
- new `_BOILER_NO_ROOM_THERMOSTAT_CONTROL_CODES = {2101, 2102}`;
- `no_interlock` now ORs room-thermostat absence with the existing
  stored-HW cylinderstat-absence test (the RdSAP §3 conjunction);
- the Space -5pp leg fires for Table 4b non-PCDB boilers (code
  101-141), not only PCDB-record boilers; the DHW leg is gated on a
  cylinder being present (Table 4c(2) combi DHW = 0).

Result for oil 6: space fuel (211) = 13446.3457 EXACT, HW fuel (219) =
4099.5872 EXACT. ΔSAP +3.0518 → +0.0782, Δcost -£69.79 → -£1.68,
ΔCO2 -240.66 → -1.71, ΔPE -1112.66 → -18.61.

The spec-correct fix exposes a single residual cause (per
[[feedback-software-no-special-handling]]): the central heating pump
(230c) — cascade reads pump_age=2 → Table 4f 41 kWh but ws (230c) =
53.3 kWh. The 12.3 kWh gap fully accounts for the residual across all
three metrics; pinned as the S0380.178 forcing function.

All other 40 corpus variants + 858 section pins + 6 U985 fixtures
unchanged (2101/2102 boiler codes appear only on oil 6). Pyright
net-zero.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 15:40:26 +00:00
..
addresses standardist Address 2026-05-22 10:13:32 +00:00
data_transformation moved classifier data transformation to an easy one 2026-06-01 14:53:34 +00:00
epc Remove EPC and asset_list changes unrelated to SAL handler 2026-06-01 16:39:09 +00:00
geospatial feat(geospatial): GeospatialRepo — OS Open-UPRN coordinate lookup (#1131) 2026-06-01 16:28:48 +00:00
property feat(property): Property aggregate + PropertyRepository (#1132) 2026-06-01 16:28:48 +00:00
property_baseline refactor(property-baseline): rename baseline → property_baseline aggregate (PR #1139 review) 2026-06-01 16:28:48 +00:00
sap10_calculator Slice S0380.177: oil 6 boiler interlock from room thermostat absence 2026-06-04 15:40:26 +00:00
sap10_ml Slice S0380.109: Solid brick + insulation via §5.7 Table 13 + §5.8 Table 14 (RdSAP 10) 2026-06-01 16:28:47 +00:00
tasks added postcode splitter rewrite to ddd 2026-05-19 16:35:09 +00:00
postcode.py get rid of comments 2026-05-20 13:21:11 +00:00