Cracks the 'PCDB disabled' blocker. The PCDF boiler reference resolves the exact
lodged boiler (e.g. 18908 -> Worcester Greenstar 4000, 88.70%) when: (1) the main
heating CODE is empty server-side (else the field + magnifying glass are
aspNetDisabled), and (2) the index is entered via REAL keyboard + Tab (a JS-set
.value doesn't survive the AutoPostBack). Now Elmhurst uses the same boiler
efficiency as the SAP engine, so worksheet vs calculator compare like-for-like.
Verified on 100061275133: Elmhurst now shows 'Efficiency of main space heating
system 1 = 88.70%' (was generic 84%). Includes updated worksheet evidence.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SOLVED the window-grid blocker (per Junte's "keep one and edit, don't
delete all"): set_single_window now ADDS the fresh window (it inserts at
DOM index 0), then deletes the STALE rows BELOW it by index (high->low,
never index 0) via the per-row Delete image button + JS-clicked Yes modal.
The freshly-added row survives as the single window; no 0.00 junk strands
to block the Recommendations gate. Verified end-to-end: cert 100050881708
built, worksheet downloaded, walls (0.70) + roof (0.19) match the engine
EXACTLY. Combined with the earlier fill+Tab (area postback) + frame/gap
(validation) fixes, the per-cert loop now runs autonomously on clean
single-main certs.
Pin: 100050881708 (semi, cavity filled, pitched 225mm, suspended ground
floor, combi) engine 72 = lodged 70 +2; walls/roof accredited-Elmhurst-
matched. NB the build entered the suspended ground floor as an upper
"above unheated space" floor, so Elmhurst's worksheet SAP (61) is not a
clean comparison — the engine uses the correct §3.12 suspended-ground U
(0.74); the pin rests on the walls+roof match + lodged.
No engine change.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Continued hardening for the per-cert Elmhurst loop. Confirmed findings:
- The window Width/Height must be set via Playwright .fill() + Tab (fires
the ASP.NET AutoPostBack so the server commits the area); a JS-set of
.value bypasses the postback and Elmhurst persists a 0.00-area row.
- Frame Type (PVC) + Glazing Gap (12 mm) are REQUIRED per row or the
Recommendations gate blocks the worksheet ("Frame Type/Glazing Gap must
be entered"). add_combined_window now sets both.
KNOWN BLOCKER (documented for the next attempt): the window grid is not
yet reliably automatable when stale rows exist on the shared assessment.
New rows insert at index 0; the delete flow reliably removes only index 0
(the newest), so accumulated 0.00 junk rows BELOW cannot be targeted, and
grid reads are timing-inconsistent across postbacks. A robust handler
needs to either (a) drive the per-row Delete by matching the row's
server-side id rather than DOM index, or (b) start each build from a
freshly-created assessment (not the shared one) so the grid is empty.
Until then the per-cert loop runs only on the FIRST build after a manual
window reset. build_100050881708.py is the WIP template.
No engine change.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Support for the per-cert Elmhurst worksheet loop:
- goto()/save_close(): fall back networkidle -> domcontentloaded on
timeout so an incomplete-validation state (half-set RR, 0-area window)
no longer hangs navigation.
- add_combined_window(): select glazing first (AutoPostBack), then JS
input+change+blur the width/height with settle waits so the Area cell
computes before Add (a plain .fill() raced the postback -> 0.00 row).
- set_single_window(): leave the grid holding exactly one row, deleting
rows carried over from a prior build of the SHARED assessment (the
window grid is the only accumulating page).
- reset_transient_state(): return the shared assessment to neutral after
a run (clear RR age band, secondary = No, meter = Single).
KNOWN RESIDUAL: the window grid still intermittently persists a 0.00 area
through Save & Close (Elmhurst's "each Add wipes the previous row" +
last-row-undeletable behaviour), and the secondary-heating dialog's modal
background can intercept the cascade click. Reliable autonomous grinding of
per-cert builds needs these two hardened further; the loop currently
completes clean single-main gas certs (see the 47084930 flat-roof slice)
but stalls on secondary-heating + stale-window combinations. build_
100021924710.py is the WIP template for that harder shape.
No engine change.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
In-container Playwright runs were flaky: the chromium renderer crashed
mid-build ("Target crashed") on the 64M /dev/shm, and login intermittently
hung. Added `--disable-dev-shm-usage` + `--no-sandbox` launch args, a
4-attempt login retry loop (domcontentloaded + explicit selector wait),
and an `ELM_GUID` env override so a per-UPRN assessment can be targeted
without editing the module. Tooling only — no calculator impact.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>