mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
docs(modelling): handover — parser gate cleared, #1154/#1158/#1159 closed
Records that the Elmhurst recommendation Summaries parse via the extractor chain (not parse_site_notes_pdf), so the "parser gate" never blocked the cascade pins. All four pins close at delta 0; loft 270→300 and the suspended-floor insulation-type field were the two gaps fixed. Remaining: #1157 (HITL schema review) + ProductJsonRepository. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a0b6a952c3
commit
ed6cd9c11a
1 changed files with 32 additions and 14 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# HANDOVER — Modelling stage rebuild
|
||||
|
||||
**Branch:** `feature/bill-derivation` (worktree `/workspaces/home/hestia-worktrees/model-assemble-new-backend`). **HEAD:** `4c104050`.
|
||||
**Branch:** `feature/bill-derivation` (worktree `/workspaces/home/hestia-worktrees/model-assemble-new-backend`). **HEAD:** `a0b6a952`.
|
||||
**PRD:** GitHub `Hestia-Homes/Model#1152`, sliced into #1153–#1161.
|
||||
|
||||
## Issue status
|
||||
|
|
@ -8,15 +8,38 @@
|
|||
| Issue | What | State |
|
||||
|---|---|---|
|
||||
| #1153 | Overlay Applicator + `EpcSimulation` | ✅ closed (`350f4c8e`) |
|
||||
| #1154 | Package Scorer | code done (`7a478cff`); **Elmhurst cascade pin pending parser** |
|
||||
| #1155 | wall Recommendation Generator | ✅ closed (`bb2c0068`) |
|
||||
| #1154 | Package Scorer | ✅ closed — Elmhurst cascade pin landed (`4c0a907a`) |
|
||||
| #1155 | wall Recommendation Generator | ✅ closed (`bb2c0068`); cascade-pinned (`4c0a907a`) |
|
||||
| #1156 | score Options + attribution | ✅ closed (`13dd5fe8`) |
|
||||
| #1157 | persist a Plan via `ModellingOrchestrator` | **not started — HITL (persistence-schema review)** |
|
||||
| #1158 | roof (loft) generator | generator done (`3c87be8e`); end-to-end + pin pending (#1157 + parser) |
|
||||
| #1159 | floor generator | generator done (`4c104050`); end-to-end + pin pending |
|
||||
| #1160 | Optimiser (knapsack + greedy repair) | not started (blocked by #1157/#1158/#1159) |
|
||||
| #1158 | roof (loft) generator | ✅ closed — 270→300 mm + cascade pin (`44d62c0c`) |
|
||||
| #1159 | floor generator | ✅ closed — overlay insulation-type field + solid/suspended pins (`a0b6a952`) |
|
||||
| #1160 | Optimiser (knapsack + greedy repair) | not started (blocked by #1157) |
|
||||
| #1161 | Measure Dependency (ventilation) | not started (blocked by #1160) |
|
||||
|
||||
## Parser gate — CLEARED (was the blocker; turned out not to be)
|
||||
|
||||
The Elmhurst recommendation Summaries route cleanly through the **same chain the
|
||||
worksheet e2e fixtures use**: `pdftotext -layout` → `ElmhurstSiteNotesExtractor`
|
||||
→ `EpcPropertyDataMapper.from_elmhurst_site_notes`. Helper:
|
||||
`tests/domain/modelling/_elmhurst_recommendation.py::parse_recommendation_summary`.
|
||||
The `parse_site_notes_pdf` Textract path still throws `'Manufacturer'` on cert
|
||||
001431 (`_extract_windows` multi-token bug) — but the Modelling pins never use
|
||||
it, so it does **not** block this work. The before/after Summaries are mirrored
|
||||
into `tests/domain/modelling/fixtures/` so the pins don't depend on the unstaged
|
||||
`/workspaces/model` workspace.
|
||||
|
||||
## Cascade pins (`test_elmhurst_cascade_pins.py`) — all 4 at delta 0
|
||||
|
||||
Each pin: parse Elmhurst `before` Summary → drive the matching generator →
|
||||
score its Option's overlay through `PackageScorer` → assert `abs(diff) <= 1e-4`
|
||||
on SAP/CO2/PE vs the calculator's score on the parsed `after` re-lodgement.
|
||||
Two real gaps surfaced and were fixed: **loft** Elmhurst re-lodges at 300 mm
|
||||
(generator was 270 → +0.17 SAP, now 300); **suspended floor** needed the overlay
|
||||
to also set `floor_insulation_type_str='Retro-fitted'` (calculator's sealed/
|
||||
unsealed seal logic, `cert_to_inputs.py:4111` — was +1.40 SAP). Cavity wall and
|
||||
solid floor closed at delta 0 with no generator change.
|
||||
|
||||
## Design (already recorded — read these)
|
||||
|
||||
- **CONTEXT.md** terms: Recommendation (a *target surface*; Recommendations **partition** the modifiable EPD surface so overlays never collide), Measure Option (bundle-capable; deduped by overlay), **Simulation Overlay** (`EpcSimulation`), Product, Cost, Contingency, Measure Dependency. Targeting: building parts by `BuildingPartIdentifier`; **windows by index**; systems direct.
|
||||
|
|
@ -47,15 +70,10 @@ All in `domain/modelling/`, `domain/building_geometry.py`, `repositories/product
|
|||
- **Running tests:** `python -m pytest <path> -q`. Do NOT pass `-p no:cov` (pytest.ini injects `--cov` args that then error). DB repo tests spin up ephemeral Postgres via the `db_engine` fixture (`tests/conftest.py`) — slower; SQLModel tables auto-register on import.
|
||||
- **Conventions:** commit per TDD slice; conventional-commit message ending `Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>`; stay on `feature/bill-derivation` (user's choice). Tests use literal `# Arrange / # Act / # Assert`; assert with `abs(x - y) <= tol` (not `pytest.approx`); pyright strict, zero errors; annotate call-return locals.
|
||||
|
||||
## The two gates
|
||||
## What's left
|
||||
|
||||
1. **Parser fix (in flight — `feature/per-cert-mapper-validation` agent → main).** Once cert **001431** parses, wire the **Elmhurst before/after cascade pins**:
|
||||
- Files (main checkout): `/workspaces/model/sap worksheets/Recommendations Elmhurst Files/<measure>/{before,after}/Summary_*.pdf` — `cavity_wall_insulation - main wall` (001431), `loft_insulation - main building`, `solid_floor`/`suspended_floor - main building`, etc.
|
||||
- Pipeline: `from backend.documents_parser.parser import parse_site_notes_pdf; epd = parse_site_notes_pdf(path)`.
|
||||
- Pin: parse `before` → apply the measure's overlay (the matching `recommend_*` Option's `overlay`) → `PackageScorer.score` → compare to `after` (either the `after` worksheet's SAP/kWh/carbon, or `Sap10Calculator().calculate(parse(after))`). `/tmp/spike_diff.py` diffs before/after EPDs to derive/validate the overlay empirically.
|
||||
- The parser bug being fixed: `_extract_windows` reads `location`/`orientation`/`data_source` as single tokens, but 001431 lodges multi-token values ("External wall", "North West") with a blank Glazing Gap, so `'Manufacturer'` lands on the `u_value` float. (`ec9ef0e8` fixed a *different* symptom.)
|
||||
- Closing these → #1154 done; #1158/#1159 end-to-end once #1157 exists.
|
||||
2. **#1157 persist a Plan (HITL).** Design-review the Plan / Plan Phase / Recommendation persistence schema + `ScenarioRepository` method shapes, then build `ModellingOrchestrator.run(property_ids, scenario_ids)` per ADR-0011/0012 (one UoW, commit once, thread only IDs, read via repos). Template: `orchestration/property_baseline_orchestrator.py`. Then roof/floor end-to-end + #1160 optimiser + #1161 ventilation dependency.
|
||||
1. **#1157 persist a Plan (HITL).** Design-review the Plan / Plan Phase / Recommendation persistence schema + `ScenarioRepository` method shapes **with Khalim**, then build `ModellingOrchestrator.run(property_ids, scenario_ids)` per ADR-0011/0012 (one UoW, commit once, thread only IDs, read via repos). Template: `orchestration/property_baseline_orchestrator.py`. Unblocks #1160 optimiser + #1161 ventilation dependency.
|
||||
2. **`ProductJsonRepository`** behind the existing `ProductRepository` port (file source for ETL-gap costs) — the only parser-independent AFK task remaining besides #1157.
|
||||
|
||||
## Relevant memories (auto-loaded)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue