Rebuilt the capture and mapping pipeline after an audit found the simulator's
data could not be trusted:
* Hotspot coordinates never matched the screenshots. Capture now scrolls the
page over CDP and pastes each frame at the measured scrollY, so image pixels
and DOM coordinates share one grid by construction.
* Metrics were synthesised (1200 + n*410) and presented as analytics. Numbers
are now attached only when the catalog has a matching row; metrics.json
carries a `source` label and the UI says "no data" instead of showing zeros.
* Event interception hooked a connector bridge that never fires. The app posts
to api.amplitude.com using the legacy form-urlencoded v1 API; the hook now
reads event_type off the wire. 36 keys are verified as `observed`.
* All device access moved into tools/telecom_cdp.py: dynamic WebView socket
discovery (the PID was hardcoded), id-matched CDP, measured native geometry.
* Editor edits can now be saved to disk; API failures no longer report success
from a stale result file; screenId is no longer interpolated into a shell.
Screens went from 7 (with fabricated markup) to 32, all verified: image height
equals map height, no out-of-bounds hotspots, no dead links.
The id_card screenshot has been manually redacted - it showed a national ID.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>