mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Docs: rewrite HANDOVER_NEXT.md for fresh agent pickup post-slice-25d
§1-§6 fully close (252/252). §7 closes 52/60 (LINE_92/93 marginal on 4 fixtures). §8-§12 not yet pinned. Handover now reads top-to-bottom with current scoreboard, per-section work queue, spec page reference index, and the section helper map for the new agent to extend. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
147da90a5a
commit
144f08533f
1 changed files with 319 additions and 292 deletions
|
|
@ -1,368 +1,372 @@
|
|||
# Handover — strict zero-error cascade pin closure for the 6 Elmhurst fixtures
|
||||
# Handover — §7 LINE_92/93 + §8–§12 sweep to abs=1e-4 closure
|
||||
|
||||
**For the agent picking up the next chunk of work.** Read this BEFORE any tool call.
|
||||
Read it in full. The previous agents' errors are catalogued here so you don't
|
||||
repeat them.
|
||||
**Goal: every line ref of every output for every one of the 6 Elmhurst
|
||||
fixtures pins against the U985 worksheet PDF at abs=1e-4.**
|
||||
|
||||
Owner: `khalim@domna.homes`. Branch: `ara-backend-design-prd`.
|
||||
Spec PDFs in `docs/sap-spec/`: SAP 10.2 (14-03-2025), RdSAP 10 (10-06-2025), PCDF.
|
||||
|
||||
---
|
||||
|
||||
## §A — Hard rules. Internalise these BEFORE anything else.
|
||||
## §A — Hard rules. Internalise before any code.
|
||||
|
||||
### A.1 What this project IS
|
||||
|
||||
This repo replicates the **rdSAP calculation engine** to bit-level fidelity
|
||||
against 6 known test vectors (the U985 Elmhurst worksheets):
|
||||
|
||||
- **Inputs**: Summary_NNNNNN.pdf (cert lodgement) for each of 6 fixtures
|
||||
- **Inputs**: `Summary_NNNNNN.pdf` (cert lodgement) for each of 6 fixtures
|
||||
(000474, 000477, 000480, 000487, 000490, 000516).
|
||||
- **Intermediate values**: U985-0001-NNNNNN.{pdf,txt} lodges every
|
||||
worksheet line ref (1) through (258+) to 4 decimal places.
|
||||
- **Intermediate values**: `U985-0001-NNNNNN.{pdf,txt}` lodges every
|
||||
worksheet line ref (1) through (282+) to 4 decimal places.
|
||||
- **Final outputs**: SAP rating (continuous + integer), ECF, total fuel cost,
|
||||
CO2, primary energy, per-end-use kWh.
|
||||
|
||||
It is a deterministic numerical function with fully-known test vectors.
|
||||
|
||||
### A.2 The bar: abs=1e-4 on EVERY pin, every fixture, every line ref
|
||||
### A.2 The bar: abs=1e-4 on EVERY pin
|
||||
|
||||
**Every SAP-result field AND every section line ref must pin to PDF at abs=1e-4.**
|
||||
- The PDF lodges 4 d.p. display precision. abs=1e-4 is the floor of "match
|
||||
what the PDF says".
|
||||
- **NO `rel=…` tolerances.**
|
||||
- **NO `<= 0.5` continuous SAP ceilings.**
|
||||
- **NO `xfail` markers on cascade pins.**
|
||||
- **NO "documented widening".**
|
||||
|
||||
- The PDF lodges 4 d.p. display precision. abs=1e-4 is the floor of "match what
|
||||
the PDF says".
|
||||
- **No `rel=...` tolerances.** Slice 19b removed `rel=0.15` (fuel cost) and
|
||||
`rel=0.05` (fuel cost) precedents. Never re-add these.
|
||||
- **No `<= 0.5` continuous SAP ceilings.** Slice 19a removed these. Never re-add.
|
||||
- **No `xfail` markers on cascade pins.** A failing pin is a calculator bug or
|
||||
fixture defect to fix.
|
||||
- **No "documented widening".** There is no such thing for this project.
|
||||
A failing pin is a calculator bug or fixture defect. If you can't close
|
||||
it in this slice, leave it failing — that's the next slice's work.
|
||||
|
||||
If a pin can't be closed in the current slice, **leave it failing**. The failing
|
||||
pin is the next slice's work. Tolerances are NEVER widened to make the suite
|
||||
green. CI red is fine while bugs are being fixed.
|
||||
### A.3 Past mistakes — DO NOT REPEAT
|
||||
|
||||
### A.3 Past-agent mistakes — DO NOT REPEAT
|
||||
|
||||
The user is frustrated with previous agents because:
|
||||
|
||||
1. **Treated SAP integer Δ=0 as "closed"** — that's a weak gate (hides ±0.5
|
||||
1. **Treating SAP integer Δ=0 as "closed"** — that's a weak gate (hides ±0.5
|
||||
continuous drift). The real gate is per-line-ref abs=1e-4.
|
||||
2. **Widened tolerances** to make tests green (`rel=0.15`, `<=0.5`). Every such
|
||||
widening masked a real residual.
|
||||
3. **Tested sections in isolation** using `fixture.LINE_X` PDF values AS INPUTS.
|
||||
That doesn't test the cascade — it tests the section formula given correct
|
||||
inputs. The cascade can still drift.
|
||||
4. **Missed fixture defects** — multiple fixtures had missing or wrong
|
||||
lodgement (bulbs, windows, sap_heating, detailed RR, exposed_floor,
|
||||
door_count, per-window U). When a cascade pin fails, ALWAYS audit the
|
||||
fixture against the PDF first.
|
||||
5. **Labelled code "SAP 10.3"** when implementing SAP 10.2 (mostly cleaned in
|
||||
slice 21a; `tables/table_12.py` retains intentional 10.2-vs-10.3
|
||||
comparison).
|
||||
6. **Diagnosed downstream first**. The cascade is upstream→downstream
|
||||
(§1 → §2 → §3 → §4 → §5 → §6 → §7 → §8 → §9a → §10a → §11a → §12). A
|
||||
downstream pin failure (e.g. `total_fuel_cost_gbp`) is meaningless to
|
||||
diagnose until upstream pins close.
|
||||
2. **Widening tolerances** to make tests green.
|
||||
3. **Testing sections in isolation** using `fixture.LINE_X` PDF values AS
|
||||
INPUTS. The cascade test walks `cert_to_inputs(epc)`, NOT isolated calls.
|
||||
4. **Missing fixture defects** — When a cascade pin fails, audit the
|
||||
fixture against the PDF FIRST. Many lodgements have been incomplete.
|
||||
5. **Diagnosing downstream first**. Cascade is upstream→downstream
|
||||
(§1 → §2 → §3 → §4 → §5 → §6 → §7 → §8 → §9a → §10a → §11a → §12).
|
||||
A downstream pin failure is meaningless to diagnose until upstream pins
|
||||
close.
|
||||
|
||||
If you find yourself about to widen a tolerance, add an xfail, or skip a
|
||||
fixture — **stop and ask the user.** Those are anti-patterns for this project.
|
||||
fixture — **stop and ask the user.**
|
||||
|
||||
### A.4 Reporting format — use the matrix
|
||||
|
||||
The user prefers the **per-(fixture × line-ref) matrix** for cohort scoreboard
|
||||
updates. Example shape (use this exactly when reporting cascade-pin status):
|
||||
### A.4 Reporting format — matrix not prose
|
||||
|
||||
```
|
||||
field | 000474 | 000477 | 000480 | 000487 | 000490 | 000516
|
||||
sap_score (int) | ✓ | ✓ | ✓ | ✗ | ✓ | ✓
|
||||
sap_score_continuous | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
ecf | ✗ | ✗ | ✓ | ✗ | ✗ | ✗
|
||||
sec 474 477 480 487 490 516 total
|
||||
--- ---- ---- ---- ---- ---- ---- -----
|
||||
§1 2/2 2/2 2/2 2/2 2/2 2/2 12/12
|
||||
§3 4/4 4/4 4/4 4/4 4/4 4/4 24/24
|
||||
...
|
||||
```
|
||||
|
||||
Or with numeric residuals when finer granularity helps:
|
||||
Or numeric residuals when finer granularity helps:
|
||||
|
||||
```
|
||||
fixture | LINE_31 Δ | LINE_33 Δ | LINE_36 Δ | LINE_37 Δ
|
||||
000474 | 0.0014 | 0.0296 | 0.0002 | 0.0294
|
||||
000477 | 0.0004 | 0.1246 | ✓ | 0.1244
|
||||
fixture | LINE_92 Δ | LINE_93 Δ
|
||||
000474 | 0.00013 | 0.00013
|
||||
000477 | 0.00016 | 0.00016
|
||||
...
|
||||
```
|
||||
|
||||
✓ = within `abs=1e-4`. Numeric value = the actual diff. This format lets the
|
||||
user scan visually and spot per-fixture vs per-line patterns. Use it instead
|
||||
of prose summaries when reporting scoreboard state.
|
||||
✓ = within abs=1e-4. Use this format instead of prose summaries.
|
||||
|
||||
### A.5 Workflow rules
|
||||
|
||||
- **Don't scan >50 lines of spec PDF without checking with the user** for the
|
||||
specific page/table range. Spec PDFs are big and the user has the page
|
||||
anchors. (Table 11 = page 188, Table 12 = 189, Table 12a = 191, Table 3a/b/c
|
||||
= 160/161/162 already given.)
|
||||
- **Don't scan >50 lines of spec PDF without checking with the user** for
|
||||
the page anchor. The user has the page references and prefers to give
|
||||
them up-front rather than have you fumble through the spec.
|
||||
- **One slice = one commit**. AAA test convention (`# Arrange / # Act /
|
||||
# Assert`). Co-Authored-By trailer.
|
||||
- **Don't touch SAP rating constants in `worksheet/rating.py`** —
|
||||
`ENERGY_COST_DEFLATOR=0.42`, `ECF_LOG_THRESHOLD=3.5`, `SAP_LOG_COEFF=113.7`,
|
||||
`SAP_LOG_CONSTANT=117.0`. SAP 10.2 (14-03-2025) per ADR-0010. Pinned by 8+
|
||||
tests.
|
||||
- **Don't auto-update unrelated git status changes** — see deletions/new files
|
||||
in `git status` that aren't from your work? Don't touch them without asking.
|
||||
`SAP_LOG_CONSTANT=117.0`. SAP 10.2 per ADR-0010, pinned by 8+ tests.
|
||||
- **Don't auto-update unrelated `git status` entries**. The pre-existing
|
||||
deletion of `docs/sap-spec/rdsap-10-specification-2025-06-10.pdf` and
|
||||
the untracked `docs/sap-spec/RdSAP 10 Specification 10-06-2025.pdf`
|
||||
are stable; don't touch.
|
||||
- **Don't invoke `/ultrareview`** — user-triggered only.
|
||||
- **Caveman mode** for prose. Terse. Technical. No filler.
|
||||
- **Terse prose.** No filler.
|
||||
- **Delete `_TEMP.py` diagnostic files before commit.**
|
||||
|
||||
---
|
||||
|
||||
## §B — Current state (as of 2026-05-23)
|
||||
## §B — Current state
|
||||
|
||||
### B.1 Cascade pin scoreboard
|
||||
### B.1 Cascade pin scoreboard (per-section)
|
||||
|
||||
Two test files contain the strict pins:
|
||||
```
|
||||
sec 474 477 480 487 490 516 total
|
||||
--- ---- ---- ---- ---- ---- ---- -----
|
||||
§1 2/2 2/2 2/2 2/2 2/2 2/2 12/12 ✓
|
||||
§2 16/16 16/16 16/16 16/16 16/16 16/16 96/96 ✓
|
||||
§3 4/4 4/4 4/4 4/4 4/4 4/4 24/24 ✓
|
||||
§4 9/9 9/9 9/9 9/9 9/9 9/9 54/54 ✓
|
||||
§5 9/9 9/9 9/9 9/9 9/9 9/9 54/54 ✓
|
||||
§6 2/2 2/2 2/2 2/2 2/2 2/2 12/12 ✓
|
||||
§7 8/10 8/10 8/10 10/10 8/10 10/10 52/60
|
||||
---------- ------------------------------------------------------ -------
|
||||
total 304/312 (97.4%)
|
||||
```
|
||||
|
||||
1. **`test_e2e_elmhurst_sap_score.py::test_sap_result_pin[fixture-field]`** —
|
||||
top-level SapResult fields. 66 cases (11 fields × 6 fixtures). Currently
|
||||
**18 PASS / 48 FAIL** at abs=1e-4.
|
||||
2. **`test_section_cascade_pins.py`** — per-section line refs walking
|
||||
`<section>_from_cert(epc)` against PDF. Currently **151 PASS / 35 FAIL**:
|
||||
- §1 (dimensions): 12 PASS / 0 FAIL ✓
|
||||
- §2 (ventilation): 96 PASS / 0 FAIL ✓
|
||||
- §3 (heat losses): 1 PASS / 23 FAIL
|
||||
- §4 (water heating): 42 PASS / 12 FAIL
|
||||
- §5-§12: not yet pinned
|
||||
**§1–§6 fully close for all 6 fixtures (252/252).** Only §7 LINE_92/93
|
||||
on 4 fixtures (000474/477/480/490) remains in the cascade.
|
||||
|
||||
Total: **169 PASS / 83 FAIL** across the strict pins. 4 of 6 fixtures fully
|
||||
close §1+§2+§4. 000487 is the worst (RR fixture defect propagates everywhere).
|
||||
|
||||
(Post-slice-25d: section_cascade_pins 304 PASS / 8 FAIL, e2e SapResult
|
||||
33 PASS / 39 FAIL. §3 + §4 + §5 + §6 ALL fully close for all 6
|
||||
fixtures. §7 closes 52/60 — only LINE_92/93 marginal ~0.0001 K
|
||||
residual on 000474/477/480/490 remains (the precision artefact
|
||||
discovered in slice 26c, no spec-grounded fix identified). Cascade
|
||||
total closure: 312 tests, 304 PASS = 97.4%.)
|
||||
|
||||
### B.2 SapResult pin matrix (post-slice-22/23)
|
||||
### B.2 SapResult pin matrix (e2e)
|
||||
|
||||
```
|
||||
field | 474 | 477 | 480 | 487 | 490 | 516
|
||||
-----------------------------------|-----|-----|-----|-----|-----|-----
|
||||
-----------------------------------+-----+-----+-----+-----+-----+-----
|
||||
sap_score (int) | ✓ | ✓ | ✓ | ✗ | ✓ | ✓
|
||||
sap_score_continuous | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
ecf | ✗ | ✗ | ✓ | ✗ | ✗ | ✗
|
||||
sap_score_continuous | ✗ | ✗ | ✗ | ✗ | ✗ | ✓
|
||||
ecf | ✓ | ✓ | ✓ | ✗ | ✓ | ✓
|
||||
total_fuel_cost_gbp | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
co2_kg_per_yr | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
space_heating_kwh_per_yr | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
main_heating_fuel_kwh_per_yr | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
secondary_heating_fuel_kwh_per_yr | ✓ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
hot_water_kwh_per_yr | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
lighting_kwh_per_yr | ✓ | ✓ | ✓ | ✓ | ✓ | ✗
|
||||
hot_water_kwh_per_yr | ✓ | ✗ | ✓ | ✓ | ✗ | ✗
|
||||
lighting_kwh_per_yr | ✓ | ✓ | ✓ | ✓ | ✓ | ✓
|
||||
pumps_fans_kwh_per_yr | ✓ | ✓ | ✓ | ✓ | ✓ | ✓
|
||||
```
|
||||
|
||||
5 of 6 fixtures hit SAP integer Δ=0 (000487 is the holdout). But continuous SAP
|
||||
is still off by sub-SAP-point amounts on every fixture — none of `sap_score_
|
||||
continuous` is closed at abs=1e-4.
|
||||
27 SapResult pin PASS / 39 FAIL. Most downstream fails will close as
|
||||
§8/§9a/§10a/§11a/§12 land. 000516 `sap_score_continuous` already
|
||||
passes — a useful sanity check that the full cascade is consistent
|
||||
when the upstream sections close.
|
||||
|
||||
### B.3 §3 residuals after slice 27b (RdSAP10 §15 element-area rounding)
|
||||
### B.3 Recent slices (in reverse order — newest first)
|
||||
|
||||
```
|
||||
fixture | LINE_31 Δ | LINE_33 Δ | LINE_36 Δ | LINE_37 Δ
|
||||
000474 | ✓ | ✓ | ✓ | ✓
|
||||
000477 | ✓ | ✓ | ✓ | ✓
|
||||
000480 | ✓ | ✓ | ✓ | ✓
|
||||
000487 | 8.83 | 37.79 | 1.32 | 39.11
|
||||
000490 | ✓ | ✓ | ✓ | ✓
|
||||
000516 | ✓ | ✓ | ✓ | ✓
|
||||
```
|
||||
|
||||
**§3 now closes for 5 of 6 fixtures at abs=1e-4.** Slice 27b applied the
|
||||
RdSAP10 §15 (p.66) rounding policy: "All element areas (gross) including
|
||||
window areas: 2 d.p." Per-element gross wall / party / roof / floor /
|
||||
window / door / alt-wall / RR-sub-area inputs to the §3 cascade are now
|
||||
rounded to 2 d.p. before A × U.
|
||||
|
||||
The remaining work is on 000487 — the worst fixture — driven by an
|
||||
RR detailed-surface lodgement defect + a U=0.86 external-gable variant
|
||||
our `gable_wall` enum doesn't handle. That's slice 25.
|
||||
|
||||
### B.4 §4 residuals
|
||||
|
||||
```
|
||||
fixture | section §4 pin status
|
||||
000474 | 9/9 ✓
|
||||
000477 | 5/9 (combi loss LINE_61m diverges → cascades to 62/64/65)
|
||||
000480 | 9/9 ✓
|
||||
000487 | 1/9 (LINE_43 + every monthly fails — HW lodgement defect)
|
||||
000490 | 9/9 ✓
|
||||
000516 | 9/9 ✓
|
||||
```
|
||||
|
||||
### B.5 Recent slices (in reverse order — newest first)
|
||||
|
||||
```
|
||||
Slice 25d: 000487 §4 LINE_65 closure — derive LINE_64A electric-shower kWh from cert (Appendix J step 8, p.82)
|
||||
Slice 25c: 000477 §4/§5/§6 closure — SAP10.2 Table 3c (p.162) M+L lower bound 100.0 → 100.2
|
||||
Slice 25b: 000487 §4 closure (7/8) — has_electric_shower + mixer/electric counts on SapHeating, Appendix J step 2a fix
|
||||
Slice 25a: 000487 §3 closure — detailed RR + gable_wall_external + Ext1 alt U=1.9 + §3.8 max-floor roof + half-up rounding
|
||||
Slice 26c: §7 mean internal temp cascade pin (60 cases, 44 PASS) — LINE_85..94
|
||||
Slice 26b: §6 solar gains cascade pin (12 cases, 10 PASS) + SapRoofWindow solar attrs + plumb to §6 cascade
|
||||
Slice 26: §5 internal gains cascade pin (54 cases, 50 PASS / 4 FAIL) + rooflight plumb to daylight factor
|
||||
Slice 27b: §3 element-area + door-area rounding to 2 d.p. per RdSAP10 §15 (p.66)
|
||||
Slice 27: BS EN ISO 13370 floor U rounded to 2 d.p. per RdSAP10 §5.12
|
||||
Slice 24: rooflight (line 27a) — SapRoofWindow datatype + 000516 cascade closure
|
||||
ac68cf88 Slice 23: 000516 detailed RR + exposed_floor + door_count fixture lodgement
|
||||
6be8fdb7 Slice 22: per-window curtain resistance fix (mixed glazing)
|
||||
024244ec Slice 21d: §3 cascade pins + heat_transmission_section_from_cert helper
|
||||
778b150c Slice 21e: §4 water heating cascade pins (42/54 PASS)
|
||||
5b7dbe2c Slice 21c: §2 cascade pins + ventilation_from_cert helper (96 PASS)
|
||||
c1472330 Slice 21b: §1 cascade pins (12/12 PASS)
|
||||
20424a2d Slice 21a: relabel SAP 10.3 → SAP 10.2 in calculator docstrings
|
||||
4c2f37f6 Slice 19b: drop loose-tolerance fuel cost tests (rel=0.15, rel=0.05)
|
||||
6bfb0614 Slice 19a: strict cascade-pin scoreboard for SapResult vs U985 PDFs
|
||||
e2d9f77d Slice 20: lodge per-window u_value on mixed-glazing fixtures
|
||||
5e34594d Slice 18a: sap_heating lodgement on 000480 / 487 / 516
|
||||
8786b907 Slice 17: wire Appendix L inputs into 000480 / 487 / 516
|
||||
25d: 000487 §4 LINE_65 closure — derive (64a) electric-shower kWh from cert (App J step 8, p.82)
|
||||
25c: 000477 §4/§5/§6 closure — SAP10.2 Table 3c (p.162) M+L lower bound 100.0 → 100.2
|
||||
25b: 000487 §4 LINE_43-64 closure — has_electric_shower + Appendix J step 2a Nbath branch
|
||||
25a: 000487 §3 full closure — RR detailed surfaces + gable_wall_external + §3.8 max-floor roof + half-up rounding
|
||||
26c: §7 mean internal temp cascade pin (60 cases, 52 PASS)
|
||||
26b: §6 solar gains cascade pin + SapRoofWindow solar attrs + plumb to §6 cascade
|
||||
26: §5 internal gains cascade pin + rooflight daylight plumb
|
||||
27b: §3 element-area rounding to 2 d.p. per RdSAP10 §15 (p.66)
|
||||
27: BS EN ISO 13370 floor U rounded to 2 d.p. per RdSAP10 §5.12 (p.46)
|
||||
24: rooflight (line 27a) — SapRoofWindow datatype + 000516 cascade closure
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §C — Work queue (in priority order)
|
||||
## §C — Work queue (priority order)
|
||||
|
||||
### C.1 Slice 24 — ~~Rooflight (line 27a) heat transmission, for 000516~~ DONE
|
||||
### C.1 §7 LINE_92/93 marginal residual (8 fails, 4 fixtures)
|
||||
|
||||
Done. 000516 PDF lodged 1.18 m² rooflight on line (27a) at U_eff=2.9930 →
|
||||
3.5317 W/K. Wired by adding `SapRoofWindow` datatype to `EpcPropertyData`
|
||||
and iterating `epc.sap_roof_windows` alongside vertical windows in
|
||||
`heat_transmission_from_cert` — same SAP10.2 §3.2 curtain transform R=0.04
|
||||
applied; rooflight area subtracted from main part's roof gross. Raw U=3.40
|
||||
sourced from RdSAP10 Table 24 (p.50/113) "Roof window" column.
|
||||
Per the matrix above. Diff is ~0.00010–0.00016 K per failing case — just
|
||||
above the 1e-4 threshold. The PDF passes LINE_87 (T_living) and LINE_90
|
||||
(T_elsewhere) for the same 4 fixtures, but the weighted combination
|
||||
LINE_92 = `(91) × T_living + (1 - (91)) × T_elsewhere` drifts.
|
||||
|
||||
§3 LINE_33 residual for 000516: 0.8215 W/K → 0.0038 W/K. Remaining 0.0038
|
||||
is the same pre-existing wall-perimeter + per-window curtain precision
|
||||
drift biting 000474/477/480/490 — closes in slice 27.
|
||||
Hypotheses to test:
|
||||
1. **PDF uses rounded T_living/T_elsewhere** at some precision higher than
|
||||
4 d.p. but lower than full float in the weighted sum. The cascade pin
|
||||
on LINE_87/90 passes at abs=1e-4 because both my full-precision and
|
||||
the PDF's higher-precision values round to the same 4-d.p. display.
|
||||
2. **PDF rounds LINE_92 to specific d.p. before later use**, but the
|
||||
stored value doesn't quite match the in-memory full-precision combo.
|
||||
3. **A spec-defined intermediate rounding step in §7 step 9** (RdSAP10
|
||||
§15 doesn't list MIT in its rounding list — only U-values and areas).
|
||||
|
||||
### C.2 Slice 25 — ~~000487 §3 RR + external gable variant~~ DONE (slice 25a)
|
||||
Diagnostic: write a TEMP test that prints my T_living[m], T_elsewhere[m],
|
||||
LINE_91, and computes the weighted sum at several precision levels (4 d.p.,
|
||||
5 d.p., 6 d.p., full). Compare each to the PDF's LINE_92[m]. If 5-d.p.
|
||||
matches the PDF for all 4 fixtures and 12 months, the rule is "round
|
||||
T_living + T_elsewhere to 5 d.p. before combining". Ask the user for the
|
||||
SAP10.2 §7 spec page (likely §9.3 or near, page ~28-32) before applying
|
||||
any new rounding rule.
|
||||
|
||||
§3 now fully closes for 000487. Remaining work: §4 HW lodgement (slice 25b
|
||||
— 000487 cert has 1 bath + 1 electric shower, no mixer outlet; calc treats
|
||||
"no mixer outlets" as "no shower", bumping Nbath from 0.13N+0.19 to
|
||||
0.35N+0.50 and over-counting bath volume 2.5×).
|
||||
000516 + 000487 §7 already close at 10/10 — so the artefact isn't
|
||||
universal. Compare their T_living[m] values against the failing fixtures
|
||||
to spot the trigger pattern.
|
||||
|
||||
Spec source: SAP 10.2 Appendix J step 2a (p.81) — `Nbath = 0.13N + 0.19 if
|
||||
shower also present (including electric); = 0.35N + 0.50 if no shower
|
||||
present`. Fix needs: lodge electric-shower presence on cert, plumb
|
||||
`has_electric_shower` through `water_heating_section_from_cert`, OR the
|
||||
fixture-shower-count refactor that closes 000477 LINE_61 simultaneously.
|
||||
### C.2 §8 space heating cascade pin (lines 95–99)
|
||||
|
||||
### C.3 Slice 26+ — §5 / §6 / §7 / §8 / §9a / §10a / §11a / §12 cascade pins
|
||||
Fixtures lodge:
|
||||
- `LINE_95_M_USEFUL_GAINS_W` (12-tuple)
|
||||
- `LINE_97_M_HEAT_LOSS_RATE_W` (12-tuple)
|
||||
- `LINE_98A_M_SPACE_HEATING_KWH` (12-tuple)
|
||||
- `LINE_98C_M_TOTAL_SPACE_HEATING_KWH` (12-tuple, same as 98a for current fixtures)
|
||||
- `LINE_98C_ANNUAL_KWH` (scalar)
|
||||
- `LINE_99_PER_M2_KWH` (scalar)
|
||||
|
||||
The cascade pin work continues in worksheet order. For each section:
|
||||
§8 orchestrator: `domain.sap.worksheet.space_heating.space_heating_monthly_kwh`.
|
||||
Section helper to add: `space_heating_section_from_cert(epc)` in
|
||||
`cert_to_inputs.py`. Inputs needed: §7 (MIT + η_whole), §1 (TFA, volume),
|
||||
§2 (effective_monthly_ach), §3 (total HLC), §5+§6 (total gains), climate.
|
||||
Same composition pattern as `mean_internal_temperature_section_from_cert`.
|
||||
|
||||
1. Identify the cert→inputs cascade entry point. May need to extract a
|
||||
`<section>_from_cert(epc)` helper from `cert_to_inputs` (mirroring slice
|
||||
21c's `ventilation_from_cert`, 21d's `heat_transmission_section_from_cert`,
|
||||
21e's `water_heating_section_from_cert`, 26's
|
||||
`internal_gains_section_from_cert`).
|
||||
2. Map fixture `LINE_X_<NAME>` constants to result struct attributes.
|
||||
3. Add scalar + monthly pin tests at abs=1e-4 to `test_section_cascade_pins.py`.
|
||||
4. Run, see failures, diagnose. Fixture defect or calculator bug — fix in place,
|
||||
no widening.
|
||||
Add pin tests at the end of `test_section_cascade_pins.py` mirroring the
|
||||
`_SECTION_7_MONTHLY_PINS` shape.
|
||||
|
||||
Sections still to pin:
|
||||
- ~~**§5 internal gains** (lines 66-73 + 232 lighting kWh)~~ DONE (slice 26)
|
||||
- ~~**§6 solar gains** (lines 83-84)~~ DONE (slice 26b — 5/6 fixtures close, 000477/487 cascade from §4)
|
||||
- ~~**§7 mean internal temperature** (lines 85-94)~~ MOSTLY DONE (slice 26c — 44/60 PASS; LINE_92/93 marginal ~0.0001 K residual on 000474/477/480/490 needs investigation; 000487 cascades from §3/§4 defects).
|
||||
- **§8 space heating** (lines 95-99). 4 monthly + 2 annual.
|
||||
- **§9a energy requirements** (lines 201, 206-208, 211-215, 219). 5 scalar + 2
|
||||
monthly. Currently only the annual aggregates show on `SapResult` — may need
|
||||
monthly exposure.
|
||||
- **§10a fuel costs** (lines 240-255). 17+ line refs.
|
||||
- **§11a SAP rating** (lines 256-258). 3 line refs.
|
||||
- **§12 environmental** (lines 261-282). CO2 + primary energy + EI rating.
|
||||
### C.3 §8c space cooling cascade pin (lines 100–108)
|
||||
|
||||
Some fixtures' constants for these sections may be missing — check first. PDF
|
||||
extraction commands (sample for §9a):
|
||||
```
|
||||
awk '/^9a\. Energy requirements/,/^10a\./' "sap worksheets/U985-0001-NNNNNN.txt"
|
||||
```
|
||||
All 6 fixtures lodge `f_C=0` (no air conditioning), so:
|
||||
- LINE_103 cooling gains = (0,)×12
|
||||
- LINE_107 monthly cooling = (0,)×12
|
||||
- LINE_107 annual = 0
|
||||
- LINE_108 per m² = 0
|
||||
|
||||
### C.4 Slice 27 — ~~Floor-U precision~~ DONE (mostly)
|
||||
LINE_101 utilisation factor collapses to 1.0 (γ ≤ 0 branch); LINE_106
|
||||
intermittency monthly is the spec default mask. Fixture constants
|
||||
`LINE_101_M_UTILISATION_FACTOR_LOSS = SECTION_8C_ETA_LOSS_ALL_ONE`,
|
||||
`LINE_106_M_INTERMITTENCY_FACTOR = SECTION_8C_INTERMITTENCY_MONTHLY`,
|
||||
`LINE_107_M_SPACE_COOLING_KWH = SECTION_8C_ALL_ZERO_MONTHLY`.
|
||||
|
||||
Done. The §5.12 spec mandates "rounded to two decimal places" for BS EN ISO
|
||||
13370 floor U-values, which my calc was skipping. Applied `round(U, 2)` to
|
||||
both suspended-timber and solid-floor branches in `u_floor` — closed
|
||||
000474/477/490 from ~0.03–0.13 W/K residual to under 0.002 W/K on each.
|
||||
§8c orchestrator: `domain.sap.worksheet.space_cooling`. Section helper
|
||||
likely trivial since all inputs collapse to zero.
|
||||
|
||||
Remaining 0.0013–0.0075 W/K residual is wall + party-wall area precision —
|
||||
PDF stores 2-d.p.-rounded element areas (e.g. `36.4500 m²` for a wall I
|
||||
compute as `36.4492 m²`). Closing these needs the §3 area-rounding spec
|
||||
rule — see slice 27b below.
|
||||
### C.4 §8f Fabric Energy Efficiency (line 109)
|
||||
|
||||
### C.4b Slice 27b — ~~§3 element-area rounding~~ DONE
|
||||
Single scalar: `LINE_109_FEE_KWH_PER_M2`. Per spec, (109) = (98a)/TFA +
|
||||
(108). For all 6 fixtures (98b) solar space heating = 0, so Σ(98a) =
|
||||
Σ(98c) → LINE_109 = LINE_99 + LINE_108 = LINE_99 (no AC).
|
||||
|
||||
Done. RdSAP10 §15 (p.66) lodges the rounding policy: "All element areas
|
||||
(gross) including window areas: 2 d.p." Applied to gross wall + party
|
||||
wall + roof + floor + window + door + alt-wall + RR-sub-area inputs in
|
||||
`heat_transmission_from_cert`. §3 cascade pins (LINE_31/33/36/37) now
|
||||
close at abs=1e-4 for 5 of 6 fixtures; 000487 alone remains failing on
|
||||
the RR defect (slice 25).
|
||||
§8f orchestrator: `domain.sap.worksheet.fabric_energy_efficiency`.
|
||||
|
||||
### C.5 Slice 28 — Continuous SAP / fuel cost / CO2 closure
|
||||
### C.5 §9a energy requirements (lines 201, 206–219)
|
||||
|
||||
Once §1-§9a all close at abs=1e-4, the downstream pins
|
||||
(`total_fuel_cost_gbp`, `ecf`, `sap_score_continuous`, `co2_kg_per_yr`) tighten
|
||||
mechanically. Re-run the SapResult pin matrix; whatever still fails has a
|
||||
section-specific residual to chase.
|
||||
Lodged on fixtures:
|
||||
- LINE_211 main heating fuel (annual)
|
||||
- LINE_215 secondary heating fuel (annual)
|
||||
- LINE_219 hot water fuel (annual)
|
||||
- Plus LINE_201, 206–208, 213–215 monthly tuples possibly
|
||||
|
||||
Already partially exposed on `SapResult` (`main_heating_fuel_kwh_per_yr`,
|
||||
`secondary_heating_fuel_kwh_per_yr`, `hot_water_kwh_per_yr`). Pin tests
|
||||
at the cascade level walk `energy_requirements_from_cert` (or compose
|
||||
inside cert_to_inputs).
|
||||
|
||||
### C.6 §10a fuel costs (lines 240–255)
|
||||
|
||||
17+ line refs. Already exposed via `SapResult.total_fuel_cost_gbp`.
|
||||
Cascade tests should pin each component (main fuel cost, secondary,
|
||||
hot water, pumps/fans, lighting, PV credit, standing charges).
|
||||
§10a orchestrator: `domain.sap.worksheet.fuel_cost.fuel_cost`.
|
||||
|
||||
### C.7 §11a SAP rating (lines 256–258)
|
||||
|
||||
3 line refs:
|
||||
- LINE_256 ECF (energy cost factor)
|
||||
- LINE_257 SAP score continuous
|
||||
- LINE_258 SAP score integer
|
||||
|
||||
Already on `SapResult` as `ecf`, `sap_score_continuous`, `sap_score`.
|
||||
e2e pins exist. Add explicit cascade pins for symmetry.
|
||||
|
||||
`rating.py` constants are immutable per ADR-0010 — do not touch.
|
||||
|
||||
### C.8 §12 environmental (lines 261–282)
|
||||
|
||||
CO2 + primary energy + EI rating monthly + annual. Already partly on
|
||||
`SapResult.co2_kg_per_yr`. Big section with many line refs.
|
||||
|
||||
---
|
||||
|
||||
## §D — How to work (toolbox)
|
||||
## §D — Workflow toolbox
|
||||
|
||||
### D.1 Cascade pin diagnostic loop
|
||||
### D.1 Adding a section cascade pin (the standard pattern)
|
||||
|
||||
1. **Find or extract** a `<section>_from_cert(epc)` helper in
|
||||
`domain.sap.rdsap.cert_to_inputs`. If it doesn't exist, add one
|
||||
mirroring `internal_gains_section_from_cert` or `mean_internal_
|
||||
temperature_section_from_cert` — compose upstream section helpers
|
||||
then call the orchestrator with the result's fields.
|
||||
2. **Add a `_SECTION_X_PINS` tuple** to `test_section_cascade_pins.py`
|
||||
mapping `("LINE_X_<NAME>", "result_attr_name")`.
|
||||
3. **Add a parametrised test** that walks every `(fixture, line_ref)`
|
||||
pair and asserts `_pin(actual, expected, ...)` at abs=1e-4.
|
||||
4. **Run, see failures, diagnose. Fixture defect or calculator bug —
|
||||
fix in place, no widening.**
|
||||
|
||||
### D.2 Diagnostic pattern
|
||||
|
||||
When a pin fails:
|
||||
1. Add a TEMP diagnostic test in `packages/domain/src/domain/sap/worksheet/tests/test_<thing>_diag_TEMP.py` that dumps the cascade output alongside the PDF expected.
|
||||
2. Compare element-by-element against the PDF block (use `awk` to extract the relevant §X PDF block).
|
||||
3. Identify the drift source — fixture defect or calc bug.
|
||||
4. Fix. Re-run the pin test.
|
||||
5. **Delete the TEMP file before committing.** Never commit `_TEMP.py` files.
|
||||
1. Add a TEMP test file `test_<thing>_diag_TEMP.py` that dumps the
|
||||
per-component breakdown alongside PDF expected values.
|
||||
2. `awk '/^X\. Section/,/^Y\./' "sap worksheets/U985-0001-NNNNNN.txt"`
|
||||
to extract the PDF block.
|
||||
3. Identify the drift source — fixture defect (audit fixture first)
|
||||
or calc bug.
|
||||
4. Fix. Re-run the pin.
|
||||
5. **Delete the TEMP file before committing.**
|
||||
|
||||
### D.2 Spec lookups
|
||||
### D.3 Spec page references already in hand
|
||||
|
||||
User has given these page anchors:
|
||||
- Table 11 (secondary heating fraction): p 188
|
||||
- Table 12 (fuel prices/CO2/PEF): p 189
|
||||
- Table 12a (standing charges, off-peak): p 191
|
||||
- Table 3a (water heating single-system): p 160
|
||||
- Table 3b (water heating combi PCDB): p 161
|
||||
- Table 3c (water heating two-profile): p 162
|
||||
```
|
||||
RdSAP 10 (10-06-2025):
|
||||
§3.1 precision rule p.16
|
||||
§3.6 wall area p.19
|
||||
§3.7.1 window area p.20
|
||||
§3.8 roof area (max-floor) p.20
|
||||
§3.9 RR simplified p.21
|
||||
§3.10 RR detailed p.21
|
||||
Table 4 (RR gable walls) p.22
|
||||
§5.12 floor U + Table 19 p.46
|
||||
§5.13 + Table 20 exposed floor p.47
|
||||
§5.17 + Table 23 basement p.48
|
||||
§5.18 curtain wall p.48
|
||||
Table 24 (window U) p.50 (Standard | Roof window cols)
|
||||
§15 rounding rules p.66
|
||||
Table 11 (secondary fraction) p.188
|
||||
Table 12 (fuel/CO2/PEF) p.189
|
||||
Table 12a (standing/off-peak) p.191
|
||||
|
||||
For other pages, **ask the user.** Don't scan more than ~50 lines of spec PDF
|
||||
without permission.
|
||||
|
||||
### D.3 PDF extraction
|
||||
|
||||
Worksheet PDFs are in `sap worksheets/` (note the space — quote in shell).
|
||||
Each fixture has `U985-0001-NNNNNN.{pdf,txt}` (intermediate values) and
|
||||
`Summary_NNNNNN.pdf` (cert lodgement).
|
||||
|
||||
PDF blocks for sections (sample for §3):
|
||||
```bash
|
||||
awk '/^3\. Heat losses/,/Thermal mass parameter/' "sap worksheets/U985-0001-000474.txt"
|
||||
SAP 10.2 (14-03-2025):
|
||||
Appendix J §2a Nbath p.81
|
||||
Appendix J §8 electric shower p.82
|
||||
Table J4 (shower flow/power) p.83
|
||||
Table J5 (behavioural fbeh) p.83
|
||||
Table 3a (HW combi keep-hot) p.160
|
||||
Table 3b (HW combi profile M) p.161
|
||||
Table 3c (HW combi M+L / M+S) p.162
|
||||
```
|
||||
|
||||
### D.4 Section helpers (cascade-pin enablers)
|
||||
For new pages **ask the user**. Spec PDFs are big.
|
||||
|
||||
Already extracted in `domain.sap.rdsap.cert_to_inputs`:
|
||||
- `dimensions_from_cert(epc) -> Dimensions` (§1)
|
||||
- `ventilation_from_cert(epc) -> VentilationResult` (§2, slice 21c)
|
||||
- `heat_transmission_section_from_cert(epc) -> HeatTransmission` (§3, slice 21d)
|
||||
- `water_heating_section_from_cert(epc) -> WaterHeatingResult` (§4, slice 21e)
|
||||
### D.4 Spec-grounded patterns we've discovered
|
||||
|
||||
For §5/§6/§7/§8/§9a/§10a/§11a/§12 you may need to extract similar helpers.
|
||||
The existing `internal_gains_from_cert`, `solar_gains_from_cert`, etc. mostly
|
||||
exist already — check whether they're already public on the worksheet/* module.
|
||||
- **RdSAP §15 rounding**: U-values + element gross areas to 2 d.p. —
|
||||
apply at the BOUNDARY between RdSAP input and SAP calculator. See
|
||||
`heat_transmission.py` for the pattern (`_round_half_up`).
|
||||
- **Half-up rounding, not banker's**: Python's `round(17.125, 2) = 17.12`
|
||||
but SAP wants 17.13. The `_round_half_up` helper in `heat_transmission.py`
|
||||
is the right utility — reuse it for any new §15 boundary you cross.
|
||||
- **§3.8 roof area = MAX of floor areas across levels**, not the top
|
||||
floor area. Bites when an extension's footprint steps back.
|
||||
- **Assessor-lodged U overrides cascade**: cert PDFs lodge measured U
|
||||
for some walls/gables. The `u_value` field on `SapRoomInRoofSurface`
|
||||
and `SapAlternativeWall` honours this. When extending to new surface
|
||||
types, follow the same pattern.
|
||||
|
||||
### D.5 Hard rules summary card
|
||||
### D.5 Section helper map (cert→inputs cascade entry points)
|
||||
|
||||
```
|
||||
domain.sap.rdsap.cert_to_inputs
|
||||
dimensions_from_cert(epc) §1 → Dimensions
|
||||
ventilation_from_cert(epc) §2 → VentilationResult
|
||||
heat_transmission_section_from_cert(epc) §3 → HeatTransmission
|
||||
water_heating_section_from_cert(epc) §4 → WaterHeatingResult
|
||||
internal_gains_section_from_cert(epc) §5 → InternalGainsResult
|
||||
solar_gains_section_from_cert(epc) §6 → SolarGainsResult
|
||||
mean_internal_temperature_section_from_cert(epc) §7 → MeanInternalTemperatureResult
|
||||
-- next to add --
|
||||
space_heating_section_from_cert(epc) §8 → SpaceHeatingResult
|
||||
space_cooling_section_from_cert(epc) §8c → SpaceCoolingResult
|
||||
fabric_energy_efficiency_from_cert(epc) §8f → float (kWh/m²)
|
||||
energy_requirements_section_from_cert(epc) §9a → EnergyRequirementsResult
|
||||
fuel_cost_section_from_cert(epc) §10a → FuelCostResult
|
||||
sap_rating_section_from_cert(epc) §11a → (ecf, sap_continuous, sap_int)
|
||||
environmental_section_from_cert(epc) §12 → EnvironmentalResult
|
||||
```
|
||||
|
||||
### D.6 Hard rules summary card
|
||||
|
||||
| do | don't |
|
||||
|----|-------|
|
||||
|
|
@ -371,84 +375,107 @@ exist already — check whether they're already public on the worksheet/* module
|
|||
| Leave failing pins, fix one at a time | Widen tolerance / add xfail |
|
||||
| Quote PDF page when asking for spec | Scan >50 lines of PDF without asking |
|
||||
| `[[reference-style]]` cross-links in memory | Bare prose references |
|
||||
| Use `_round_half_up`, not Python `round` | Banker's rounding at §15 boundaries |
|
||||
| Delete `_TEMP.py` before commit | Commit diagnostic scripts |
|
||||
|
||||
---
|
||||
|
||||
## §E — Key files
|
||||
## §E — File map
|
||||
|
||||
```
|
||||
docs/sap-spec/sap-10-2-full-specification-2025-03-14.pdf Spec PDF
|
||||
docs/sap-spec/HANDOVER_NEXT.md This file
|
||||
docs/sap-spec/PARITY_FINDINGS.md Older findings
|
||||
sap worksheets/ U985 + Summary PDFs
|
||||
docs/sap-spec/
|
||||
sap-10-2-full-specification-2025-03-14.pdf SAP 10.2 spec
|
||||
RdSAP 10 Specification 10-06-2025.pdf RdSAP 10 spec
|
||||
HANDOVER_NEXT.md this file
|
||||
pcdb_table_105_gas_oil_boilers.jsonl PCDB combi records
|
||||
sap worksheets/ U985 + Summary PDFs
|
||||
|
||||
packages/domain/src/domain/sap/calculator.py Top-level SAP10.2 orchestrator
|
||||
packages/domain/src/domain/sap/rdsap/cert_to_inputs.py Cert→CalculatorInputs
|
||||
+ section_from_cert helpers
|
||||
packages/domain/src/domain/sap/tables/table_12.py SAP 10.2 Table 12 (price/CO2/PEF)
|
||||
packages/domain/src/domain/sap/tables/table_12a.py Off-peak high-rate fraction
|
||||
packages/domain/src/domain/sap/tables/table_32.py RdSAP 10 Table 32 (cost prices)
|
||||
packages/domain/src/domain/sap/calculator.py Top-level SAP10.2 orchestrator
|
||||
packages/domain/src/domain/sap/rdsap/cert_to_inputs.py Cert→CalculatorInputs + section helpers
|
||||
packages/domain/src/domain/sap/tables/table_12.py Table 12 (price/CO2/PEF)
|
||||
packages/domain/src/domain/sap/tables/table_12a.py Off-peak high-rate fraction
|
||||
packages/domain/src/domain/sap/tables/table_32.py RdSAP10 Table 32 (cost prices)
|
||||
|
||||
packages/domain/src/domain/sap/worksheet/
|
||||
dimensions.py §1
|
||||
ventilation.py §2 + VentilationResult
|
||||
heat_transmission.py §3 + HeatTransmission
|
||||
water_heating.py §4 + WaterHeatingResult + water_heating_from_cert
|
||||
internal_gains.py §5 + InternalGainsResult + internal_gains_from_cert
|
||||
solar_gains.py §6 + solar_gains_from_cert
|
||||
mean_internal_temperature.py §7
|
||||
heat_transmission.py §3 + HeatTransmission + _round_half_up helper
|
||||
water_heating.py §4 + WaterHeatingResult + electric_shower_monthly_kwh
|
||||
internal_gains.py §5 + InternalGainsResult
|
||||
solar_gains.py §6 + SolarGainsResult + RoofWindowInput
|
||||
mean_internal_temperature.py §7 + MeanInternalTemperatureResult
|
||||
space_heating.py §8 + SpaceHeatingResult
|
||||
fabric_energy_efficiency.py §8f
|
||||
space_cooling.py §8c
|
||||
fabric_energy_efficiency.py §8f
|
||||
energy_requirements.py §9a + EnergyRequirementsResult
|
||||
fuel_cost.py §10a + FuelCostResult
|
||||
rating.py §11/§13 SAP rating equations (10.2 constants — DO NOT TOUCH)
|
||||
rating.py §11/§13 SAP rating equations (DO NOT TOUCH constants)
|
||||
|
||||
packages/domain/src/domain/sap/worksheet/tests/
|
||||
test_section_cascade_pins.py Strict per-section line-ref pins (THE work)
|
||||
test_e2e_elmhurst_sap_score.py SapResult-field pins + monthly_infiltration_ach pin
|
||||
test_e2e_elmhurst_sap_score.py SapResult-field pins
|
||||
_elmhurst_worksheet_NNNNNN.py The 6 fixture modules (1 per fixture)
|
||||
_elmhurst_fixtures.py ALL_FIXTURES registry
|
||||
test_dimensions.py / _ventilation.py / _heat_transmission.py / ...
|
||||
← LEGACY per-section isolation tests; use PDF values as INPUTS.
|
||||
Keep them but understand they don't test the cascade.
|
||||
test_*.py Legacy per-section isolation tests
|
||||
|
||||
datatypes/epc/domain/epc_property_data.py
|
||||
SapBuildingPart + sap_room_in_roof
|
||||
SapRoomInRoof + detailed_surfaces
|
||||
SapRoomInRoofSurface + u_value override, kind enum:
|
||||
"slope" | "flat_ceiling" | "stud_wall" |
|
||||
"gable_wall" | "gable_wall_external"
|
||||
SapAlternativeWall + u_value override
|
||||
SapRoofWindow area + u_value_raw + orientation +
|
||||
pitch_deg + g_perpendicular + frame_factor
|
||||
SapHeating + electric_shower_count, mixer_shower_count,
|
||||
number_baths
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §F — Definitely do NOT
|
||||
|
||||
- Do **not** widen any tolerance, ever.
|
||||
- Do **not** widen any tolerance.
|
||||
- Do **not** add xfail to cascade pins.
|
||||
- Do **not** "investigate later" by widening — fix it or leave it failing.
|
||||
- Do **not** assume the calculator is wrong before auditing the fixture.
|
||||
- Do **not** touch `rating.py` constants.
|
||||
- Do **not** scan unread spec PDF pages without asking the user.
|
||||
- Do **not** invoke `/ultrareview`.
|
||||
- Do **not** auto-update unrelated `git status` items (deletions / new files
|
||||
that aren't from your work).
|
||||
- Do **not** auto-update unrelated `git status` items.
|
||||
- Do **not** use Python `round()` at a §15 boundary — use `_round_half_up`.
|
||||
|
||||
---
|
||||
|
||||
## §G — Quick orient
|
||||
|
||||
```bash
|
||||
# Run full cohort pin matrix
|
||||
# Run the full cascade scoreboard
|
||||
python -m pytest \
|
||||
packages/domain/src/domain/sap/worksheet/tests/test_section_cascade_pins.py \
|
||||
packages/domain/src/domain/sap/worksheet/tests/test_e2e_elmhurst_sap_score.py \
|
||||
--no-header --no-cov --tb=no -q
|
||||
|
||||
# Run §3 pins only
|
||||
python -m pytest packages/domain/src/domain/sap/worksheet/tests/test_section_cascade_pins.py::test_section_3_line_refs_match_pdf -v --no-header --no-cov --tb=no
|
||||
# Run §7 only
|
||||
python -m pytest packages/domain/src/domain/sap/worksheet/tests/test_section_cascade_pins.py \
|
||||
-k "section_7" --no-cov --tb=no -q
|
||||
|
||||
# Run a single SapResult pin to see numeric diff
|
||||
# Per-fixture residual diffs for a section
|
||||
python -m pytest packages/domain/src/domain/sap/worksheet/tests/test_section_cascade_pins.py \
|
||||
-k "section_7 and 000474" --no-cov --tb=line
|
||||
|
||||
# Single SapResult pin numeric diff
|
||||
python -m pytest \
|
||||
"packages/domain/src/domain/sap/worksheet/tests/test_e2e_elmhurst_sap_score.py::test_sap_result_pin[000477-space_heating_kwh_per_yr]" \
|
||||
--no-cov 2>&1 | grep AssertionError
|
||||
|
||||
# PDF §X block
|
||||
# Extract a PDF §X block for a fixture
|
||||
awk '/^X\. Section/,/^Y\./' "sap worksheets/U985-0001-NNNNNN.txt"
|
||||
|
||||
# Wider regression check
|
||||
python -m pytest packages/domain/src/domain/sap/worksheet/tests/ \
|
||||
packages/domain/src/domain/sap/tests/ packages/domain/src/domain/ml/ \
|
||||
--no-header --no-cov --tb=no -q | tail -5
|
||||
```
|
||||
|
||||
End of handover. Read §A again before starting.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue