mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
docs: handover post S0380.170..173
Captures the 4-slice community-heating closure phase: blocked tier emptied (.170), CHP cost split (.171), heat-network heat-source-eff scaling (.172), WHC=901 HW main-fuel routing (.173). Open fronts ranked: SAP 302 CHP credit cascade (3-variant cohort), +£12 lighting/standing overage on CH1/CH3, oil 3/4/6 + no-system follow-ups. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
c17330b319
commit
0a657453fc
1 changed files with 287 additions and 0 deletions
287
domain/sap10_calculator/docs/HANDOVER_POST_S0380_173.md
Normal file
287
domain/sap10_calculator/docs/HANDOVER_POST_S0380_173.md
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
# Handover — post Slices S0380.170..173
|
||||
|
||||
Branch: `feature/per-cert-mapper-validation`. **HEAD `e71987c2`**.
|
||||
Predecessor: [`HANDOVER_POST_S0380_169.md`](HANDOVER_POST_S0380_169.md).
|
||||
|
||||
## TL;DR
|
||||
|
||||
Four community-heating slices landed. The **blocked tier emptied** for
|
||||
the first time in the corpus's history (`.170`); cost cascade closed
|
||||
on the CHP cluster (`.171`); CO2/PE closed on non-CHP variants
|
||||
(`.172`, `.173`).
|
||||
|
||||
All 41 corpus variants now run end-to-end through the cascade:
|
||||
**36 EXACT + 9 pinned** (oil 3/4/6 + no system + 5 community
|
||||
heating). The 5 community-heating variants carry forcing-function
|
||||
residuals scoped to specific Elmhurst-mirror divergences detailed
|
||||
below.
|
||||
|
||||
| Slice | HEAD | Scope |
|
||||
|---|---|---|
|
||||
| S0380.170 | `9f0d23ad` | **Community heating mapper unblock.** New `CommunityHeating` dataclass on `ElmhurstSiteNotes.main_heating`; extractor `_extract_community_heating()` reads §14.1 Heat Source × Fuel Type. Mapper `_resolve_community_heating_fuel_code(heat_source, fuel)` dispatches per SAP 10.2 Table 12 (PDF p.189): Boilers+Gas→51, CHP→48, HP+Elec→41, Boilers+Oil→53, Boilers+Coal→54. All 5 variants unblocked; 5 forcing-function residuals pinned. Blocked tier tuple emptied. |
|
||||
| S0380.171 | `a4b5f4e7` | **RdSAP 10 §C CHP heat-fraction cost split.** New `MainHeatingDetail.community_heating_chp_fraction` + `community_heating_boiler_fuel_type` fields populated by the mapper for SAP code 302. `_fuel_cost_gbp_per_kwh` returns `0.35 × CHP_price + 0.65 × boiler_price` when fields set. CH2/CH4 cost gap −£104 → +£0.17 (essentially exact); SAP +4.50 → −0.008. CH6 regressed (-3.52 → -8.03 SAP) — spec-correct fix exposed cert-side DLF=1.0 quirk that only CH6 lodges (in P960 input data, not in Summary). |
|
||||
| S0380.172 | `36d4bf87` | **Table 4a heat-network heat-source-eff CO2/PE factor scaling.** New `_HEAT_NETWORK_HEAT_SOURCE_EFFICIENCY` dict (301→0.80, 304→3.00 per SAP 10.2 Table 4a PDF p.164). `_heat_network_heat_source_efficiency_scaling(main)` returns 1/eff. Wired into `_main_heating_co2_factor_kg_per_kwh` + `_main_heating_primary_factor` non-electric branches. CH1 CO2/PE -787/-3827 → -126/-967; CH3 CO2/PE +1614/+11879 → +473/+1749. SAP 302 excluded — converges with CHP credit in follow-up. |
|
||||
| S0380.173 | `e71987c2` | **WHC=901 HW path inherits main fuel for community heating.** New `_is_community_heating_hw_from_main(epc)` predicate (WHC ∈ {901,902,914} + heat-network main + SAP code in heat-source-eff table). `_hot_water_fuel_cost_gbp_per_kwh` gains `inherit_main_for_community_heating` kwarg; HW CO2/PE get top-level branches scaled by 1/heat_source_eff. CH1 PE −967 → **−9** (essentially closed); CH3 PE +1749 → −387 (~78%); CH3 CO2 +473 → −86 (~82%). Cost/SAP signs flip on CH1/CH3 — HW matches worksheet exactly, exposing +£12 lighting/standing overage. |
|
||||
|
||||
Extended handover suite at HEAD: **926 pass + 1 skipped, 0 fail.**
|
||||
Pyright net-zero on affected files (32 → 32 across the 4 slices).
|
||||
|
||||
## Current residual state at HEAD `e71987c2`
|
||||
|
||||
### Cascade-OK tier (41 variants — all populated corpus folders)
|
||||
|
||||
**36 variants EXACT (|Δ| < 1e-3) on all 4 metrics.** 9 variants
|
||||
carry pinned non-zero residuals (forcing functions, ranked by
|
||||
total magnitude):
|
||||
|
||||
| Variant | ΔSAP_c | Δcost | ΔCO2 | ΔPE | Closure driver |
|
||||
|---|---:|---:|---:|---:|---|
|
||||
| CH6 (CHP/Coal) | −8.03 | +£185 | −2935 | +7865 | DLF=1.0 in P960 + CHP credit |
|
||||
| CH4 (CHP/Oil) | −0.008 | +£0.17 | −4397 | +495 | CHP credit (CO2) |
|
||||
| CH2 (CHP/Gas) | −0.008 | +£0.17 | −1430 | +1506 | CHP credit (CO2 + PE) |
|
||||
| oil 6 (B30K) | +3.05 | −£70 | −241 | −1113 | Table 4b code 126 SH+HW kWh gap |
|
||||
| oil 3 (FAME) | +2.59 | −£62 | −15 | −967 | Table 4b code 128 HW kWh gap |
|
||||
| oil 4 (FAME) | +2.56 | −£57 | −13 | −885 | Table 4b code 129 HW kWh gap |
|
||||
| CH3 (HP/Elec) | −0.53 | +£12 | −86 | −387 | Lighting/standing + 0.8523 multiplier |
|
||||
| CH1 (Boilers/Gas) | −0.53 | +£12 | +52 | **−9** | Lighting/standing (PE essentially closed) |
|
||||
| no system | +1.18 | −£27 | −50 | −562 | §A.2.2 portable-electric defaults |
|
||||
|
||||
### Blocked tier (0 variants)
|
||||
|
||||
**Empty for the first time.** All previously blocked variants
|
||||
(`community heating 1/2/3/4/6`, `electric 11-14`, `oil 2-6`, `no
|
||||
system`, `pcdb 3`) now cascade-execute. The
|
||||
`_BLOCKED_BY_MISSING_MAIN_FUEL_TYPE` tuple in
|
||||
[`test_heating_systems_corpus.py`](../../../backend/documents_parser/tests/test_heating_systems_corpus.py)
|
||||
is empty; the parametrized raise-test is `pytest.mark.skipif`'d
|
||||
with reason `"all blocked variants have been unblocked (latest:
|
||||
S0380.170)"`.
|
||||
|
||||
## Open fronts ranked by leverage
|
||||
|
||||
### 1. SAP 302 CHP CO2/PE credit cascade (3 variants — CH2, CH4, CH6)
|
||||
|
||||
Highest cohort leverage: closes ~−8 SAP-equivalent across CH2 / CH4
|
||||
/ CH6 + their large CO2 / PE residuals simultaneously.
|
||||
|
||||
Per spec block 13b PE (PDF p.153) + 12b CO2:
|
||||
|
||||
```
|
||||
Space heating from CHP (307a) × 100 ÷ (462) = ... (463)
|
||||
less credit emissions −(307a)×(461) ÷ (462) = ... (464)
|
||||
Water heated by CHP (310a) × 100 ÷ (462) = ... (465)
|
||||
less credit emissions −(310a)×(461) ÷ (462) = ... (466)
|
||||
Heat from heat source 2 [(307b)+(310b)] × 100 ÷
|
||||
(467b) = ... (468)
|
||||
```
|
||||
|
||||
Per RdSAP 10 §C (PDF p.58) defaults: **CHP overall eff 75%,
|
||||
heat-to-power ratio 2.0 → heat_eff 50% + electric_eff 25%; boiler
|
||||
eff 80%**. Verified against CH2/CH4/CH6 worksheet (461)/(462) = 25%
|
||||
/ 50% exactly.
|
||||
|
||||
**Per-line worksheet caveat.** The Elmhurst worksheet (463) energy
|
||||
column = spec_formula × 0.8523 uniformly across non-CHP heat-
|
||||
network rows. This 0.8523 multiplier appears in CH1 (467) too (=
|
||||
spec `(307+310) × 100/80` × 0.8523 → 16717.79 instead of 19614.94).
|
||||
Mechanism unidentified; not RdSAP 10 / SAP 10.2 spec-derived as
|
||||
far as the spec PDFs document. **Do per-line walks before forming
|
||||
hypotheses** per [[feedback-spec-floor-skepticism]]. This may need
|
||||
a SAP_CALCULATOR.md §8 row.
|
||||
|
||||
Implementation sketch: add CHP credit factor + boiler-fuel-code
|
||||
fields to MainHeatingDetail; the .172 scaling helper already keys
|
||||
on `_HEAT_NETWORK_HEAT_SOURCE_EFFICIENCY` — add 302 there with
|
||||
weighted overall eff once the split formula is in place. The
|
||||
.173 predicate `_is_community_heating_hw_from_main` also gates on
|
||||
table membership and will pick up SAP 302 automatically.
|
||||
|
||||
Likely 2-3 slices: (a) CHP credit + boiler-side eff for SH; (b)
|
||||
mirror for HW path; (c) Elmhurst 0.8523 multiplier if it turns out
|
||||
to be load-bearing.
|
||||
|
||||
### 2. CH1 / CH3 lighting / standing overage (+£12 cost)
|
||||
|
||||
Surfaced by S0380.173 closing the HW path. Cascade cost matches
|
||||
worksheet exactly on SH + HW, leaves +£12 over on lighting + standing.
|
||||
|
||||
Probable mechanisms (in rank order):
|
||||
|
||||
1. Standing charge double-count. Worksheet (351) = £120 for code 51
|
||||
(heat-network). Cascade may also apply the Mains-gas standing
|
||||
even though water_heating_fuel still lodges code 26 → API code 1.
|
||||
2. Lighting kWh rate mismatch. Cascade uses `other_fuel_cost_gbp_
|
||||
per_kwh = 0.1367` (18-hour high) — verify against worksheet (350)
|
||||
= 282 × 0.1367.
|
||||
3. (313) electricity-for-heat-distribution kWh stream billed at
|
||||
wrong rate. Worksheet uses heat-network rate 4.24 for this; check
|
||||
cascade.
|
||||
|
||||
Probably 1 slice once diagnosed via per-line walk. Closes CH1 +
|
||||
CH3 fully.
|
||||
|
||||
### 3. CH6 DLF=1.0 lodging in P960 (cert-side architecture gap)
|
||||
|
||||
CH6 P960 input data lodges `Distribution Loss: Two adjoining
|
||||
dwellings sharing a single heating system` + `Distribution Loss
|
||||
Value: 0.0`, producing worksheet (306) = 1.0000. CH4 with the
|
||||
same §14 Summary shape lodges `Distribution Loss: Calculated +
|
||||
Value: 1.5`, producing (306) = 1.4500.
|
||||
|
||||
The DLF distinguisher is NOT in the Summary PDF — only the P960
|
||||
worksheet input data block. The current architecture only reads
|
||||
Summary; routing through P960 inverts that.
|
||||
|
||||
Two paths forward:
|
||||
- (a) Extend the Elmhurst Summary extractor to look for any `§17
|
||||
Additional Information` line — currently neither CH4 nor CH6
|
||||
Summaries lodge anything here, but if Elmhurst adds it the gap
|
||||
closes.
|
||||
- (b) Accept CH6 as a pinned forcing function. Spec-correct
|
||||
cascade applies DLF=1.45 for age G per Table 12c; CH6's manual
|
||||
override (per spec §C3.1: "For design-stage SAP assessments, a
|
||||
DLF of >= 1 can be manually entered") is unmodelable without
|
||||
P960 access.
|
||||
|
||||
Recommend (b) — pin and document.
|
||||
|
||||
### 4. oil 3 / oil 4 (FAME) HW kWh gap
|
||||
|
||||
Carried over from S0380.168. ΔSAP +2.59/+2.56. Cascade HW kWh
|
||||
~900 less than worksheet on FAME boilers (Table 4b codes 128/129).
|
||||
Per-line walk on `_apply_water_efficiency` vs (219)m. Probably 1
|
||||
slice.
|
||||
|
||||
### 5. oil 6 (B30K) SH + HW kWh gap
|
||||
|
||||
Carried over from S0380.168. ΔSAP +3.05. Likely Table 4b code-126
|
||||
path differs. Probably 1 slice.
|
||||
|
||||
### 6. "no system" §A.2.2 portable-electric defaults
|
||||
|
||||
Carried over from S0380.169. ΔSAP +1.18. Cascade thinks dwelling
|
||||
more efficient than worksheet. Probable §A.2.2 portable-electric
|
||||
defaults gap (responsiveness/control/Table 11). Probably 1 slice.
|
||||
|
||||
## Critical discipline reinforced last session
|
||||
|
||||
**Per-line walk worksheet → spec → fix.** S0380.171 + .172 + .173
|
||||
each landed via per-line worksheet dumps confirming the spec rule
|
||||
before implementation. S0380.173 in particular: probing CH3 HW
|
||||
factors revealed the cascade was billing HW at Mains-gas (Elmhurst
|
||||
§15.0 placeholder) rather than heat-network rate; per-line walk on
|
||||
worksheet (342) confirmed the fix direction.
|
||||
|
||||
**Spec-floor skepticism cuts BOTH ways.** S0380.171 was framed by
|
||||
the prior handover as a single closure for CH2/CH4/CH6 ("biggest
|
||||
leverage by spec-coherent grouping"). The actual implementation
|
||||
closed CH2/CH4 exactly but REGRESSED CH6 — exposing the cert-side
|
||||
DLF=1.0 quirk that was previously masked by offsetting bugs. Per
|
||||
[[feedback-software-no-special-handling]] applied uniformly;
|
||||
documented as forcing function rather than gated out.
|
||||
|
||||
**Gate carefully across SH and HW paths.** S0380.172 + .173 use the
|
||||
same `_HEAT_NETWORK_HEAT_SOURCE_EFFICIENCY` table to gate the
|
||||
heat-source-eff scaling. SAP 302 is intentionally absent — when the
|
||||
CHP credit slice lands, ADD 302 to that table and both SH (via
|
||||
.172's wiring) and HW (via .173's predicate) auto-activate.
|
||||
|
||||
**Cost-side and CO2/PE-side need different efficiencies for heat
|
||||
networks.** Cost uses heat-network unit price × network_input
|
||||
(metered at the dwelling boundary). CO2/PE uses Table 12 factor ×
|
||||
fuel_input = network_input / heat_source_eff. The .172 + .173
|
||||
scaling helpers express this by pre-scaling the Table 12 factor at
|
||||
lookup time, leaving the cost path unaffected.
|
||||
|
||||
## Standard slice workflow (unchanged)
|
||||
|
||||
1. Read spec page + identify rule (or Elmhurst worksheet pattern)
|
||||
2. Probe one variant; verify diagnosis via monkey-patch / direct walk
|
||||
3. Write failing AAA test (literal `# Arrange / # Act / # Assert`)
|
||||
4. Implement helper / dispatch entry / mapper extension
|
||||
5. Re-pin affected variants (DO NOT widen tolerance)
|
||||
6. Run extended handover suite (command below)
|
||||
7. Pyright net-zero check (`git stash` → pyright → `git stash pop` → pyright)
|
||||
8. If mirroring Elmhurst against spec literal: add a row to
|
||||
`SAP_CALCULATOR.md §8 "Elmhurst-mirrored spec divergences"`. The
|
||||
≥2-cert rule applies unless the new divergence shares its shape
|
||||
with an already-documented row (S0380.164 added §8.2 under this
|
||||
exception with a single-cert flag).
|
||||
9. Commit with spec citation + `Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>`
|
||||
10. Update `project-heating-systems-corpus` + `MEMORY.md` index
|
||||
|
||||
## Test baseline at HEAD `e71987c2`
|
||||
|
||||
```bash
|
||||
PYTHONPATH=/workspaces/model python -m pytest \
|
||||
backend/documents_parser/tests/test_summary_pdf_mapper_chain.py \
|
||||
backend/documents_parser/tests/test_heating_systems_corpus.py \
|
||||
backend/documents_parser/tests/test_elmhurst_extractor.py \
|
||||
backend/documents_parser/tests/test_elmhurst_end_to_end.py \
|
||||
domain/sap10_calculator/worksheet/tests/test_e2e_elmhurst_sap_score.py \
|
||||
domain/sap10_calculator/worksheet/tests/test_heat_transmission.py \
|
||||
domain/sap10_calculator/worksheet/tests/test_internal_gains.py \
|
||||
domain/sap10_calculator/worksheet/tests/test_solar_gains.py \
|
||||
domain/sap10_calculator/worksheet/tests/test_dimensions.py \
|
||||
domain/sap10_calculator/worksheet/tests/test_rating.py \
|
||||
domain/sap10_calculator/worksheet/tests/test_ventilation.py \
|
||||
domain/sap10_calculator/worksheet/tests/test_appendix_h_solar.py \
|
||||
domain/sap10_calculator/worksheet/tests/test_mev.py \
|
||||
domain/sap10_calculator/rdsap/tests/test_cert_to_inputs.py \
|
||||
domain/sap10_calculator/rdsap/tests/test_golden_fixtures.py \
|
||||
domain/sap10_calculator/tests/test_pcdb_table_322_lookup.py \
|
||||
domain/sap10_calculator/tests/test_pcdb_table_329_lookup.py \
|
||||
domain/sap10_calculator/tests/test_table_12a.py \
|
||||
--no-cov -q
|
||||
```
|
||||
|
||||
Expected: **926 pass + 1 skipped, 0 fail.**
|
||||
|
||||
## Memories to load (in order)
|
||||
|
||||
```
|
||||
project-heating-systems-corpus # HEAD e71987c2
|
||||
feedback-sap-10-2-only-never-10-3
|
||||
feedback-software-no-special-handling
|
||||
feedback-spec-floor-skepticism
|
||||
feedback-worksheet-not-api-reference
|
||||
feedback-spec-citation-in-commits
|
||||
feedback-verify-handover-claims
|
||||
feedback-zero-error-strict
|
||||
feedback-commit-per-slice
|
||||
feedback-aaa-test-convention
|
||||
feedback-e2e-validation-philosophy
|
||||
feedback-abs-diff-over-pytest-approx
|
||||
feedback-golden-residuals-near-zero
|
||||
feedback-one-e-minus-4-across-the-board
|
||||
feedback-bigger-slices-for-uniform-work
|
||||
reference-unmapped-sap-code
|
||||
reference-unmapped-api-code
|
||||
project-oil-price-spec-divergence
|
||||
```
|
||||
|
||||
## What NOT to do
|
||||
|
||||
- **Don't reference SAP 10.3** — track 10.2 deliberately.
|
||||
- **Don't widen pin tolerances** — re-pin smaller or find the spec gap.
|
||||
- **Don't add empirical gates** to keep cohort pins stable.
|
||||
- **Don't re-investigate Slices .91..173** — all settled.
|
||||
- **Don't add new helpers to `domain/sap10_ml/`** — on deprecation path.
|
||||
- **Don't treat ΔSAP=0.07 as "closed"** — target is <1e-4 vs worksheet.
|
||||
- **Don't form a spec hypothesis without per-line data** — walk the
|
||||
worksheet first. The Elmhurst 0.8523 multiplier on heat-network
|
||||
rows (CH1 (467), CH3 (467), CH2/CH4/CH6 (468)) is unexplained and
|
||||
may be load-bearing for the CHP credit slice.
|
||||
- **Don't gate SH and HW paths separately.** The .172 + .173 wiring
|
||||
shares `_HEAT_NETWORK_HEAT_SOURCE_EFFICIENCY` membership; adding
|
||||
SAP 302 to that table auto-activates both paths.
|
||||
|
||||
## Master doc
|
||||
|
||||
The canonical architecture + API + validation doc lives at
|
||||
[`domain/sap10_calculator/docs/SAP_CALCULATOR.md`](SAP_CALCULATOR.md)
|
||||
(§8.1 + §8.2 documented). The next CHP-credit slice may add §8.3 if
|
||||
the Elmhurst 0.8523 multiplier or block-13b PE/CO2 line formulas
|
||||
turn out to diverge from spec literal.
|
||||
|
||||
## Good luck.
|
||||
Loading…
Add table
Reference in a new issue