# Evidence capture: issue 24812

Before: 5398be0d44ef06fb1646d8ad54b81b5613a03193. After: 381080517e4932f3ff4c59f719ad9d0d6717e0e9. Checkout remained clean and at after SHA throughout; no source edits, commits, pushes, comments, watches or merges.

Method: git show extracted each commit's CdpRelay.ts into scratch. Actual ServerBrowserPage.snapshot(renderScale="display") imported from clean final checkout; its blob 129eaa8a89bb579725793e59df514538e816181e is identical in both commits. Only CdpRelay.ts and its test differ between before and after. Relevant relay/snapshot files also have no diff between earlier a8603afcf1 and requested baseline, independently verified; old runtime.log was not reused as new evidence. Baseline relay blob 82264cc4b870b2d245e18fc2b9a11a413967ccc2; head relay blob 9c322cad70a29762057ba4103d007810dff7dd81.

Environment: Linux 6.1.102 x64, Electron 44.9.3, Chromium 152.0.7977.167, Electron Node 24.22.0, Playwright 1.60.0. headless-desktop Xvfb 1920x1080x24/D-Bus, display :103. esbuild 0.28.2 binary executed directly, CJS bundled TS with Electron/Playwright/ws external. Separate freshly created temporary userData per run. Driver uses app.whenReady callback. Runtime logs print source SHA/blob and versions.

Protocol matrix observations:
- First connection: baseline and head actual snapshot pass with heading "Snapshot probe" and button "Test" refs, screenshot dimensions 900x573. Native evaluation succeeds.
- Reconnect: same webContents ID 1 and unchanged target ID within each run; debugger attached once and still attached both rounds. Baseline B4403847D45F4991CF82210D69237498: second native evaluation succeeds but actual snapshot fails with busy timeout. Head BB36069D530F3BF6FC70601FC88E7E2F: second native evaluation and actual snapshot pass, heading/button refs and 900x573 image. No reload, guest replacement, debugger detach or snapshot retry.
- Repeated enables / extra synthetic page alias: scratch protocol assertion passes; three enables forward to native main page with only one disable and original reply sessions preserved.
- Concurrent enables while disable pending: controlled deferred Promise shows only disable sent and neither enable replied until release; both then forward. No timed polling.
- Reset rejects: injected Runtime.disable rejection still invokes enable; successful result and injected enable error each preserve command ID and page session. This does not establish context recovery after a native reset failure.
- Child Runtime.enable: no reset; params and real child session preserved.
- Other routing: child DOM and resume forwarding, main resume bypass pass scratch assertions. Existing final relay/host suites pass 14/14, including browser/root, page aliases, events and downloads.

Regression red: exact test text extracted from test-only commit 23c7858311e866f2cc3b1113fb6f826707239824, only import redirected to baseline extracted relay. Its production relay blob equals requested baseline. Selected named regression passes first connect assertion and fails second connect assertion at line 233: expected executionContextCreated, received []. Six unrelated tests filtered out. Regression green: unmodified exact-head CdpRelay.test.ts + DesktopBrowserHost.test.ts, 2 files / 14 tests passed.

Scope: real Electron native debugger + relay + Playwright + actual server snapshot integration, not packaged app/transport end-to-end verification. Deterministic target fixture supplies branch safeguards. No render changes; empty visual matrix, no screenshot/recording artifacts needed. macOS remains unverified; remote/tunnel/mobile not runtime exercised.

Cleanup: both runtime runners exited 0 through app.quit; spawned process groups 2638974 and 2639556 have no remaining processes. No server started. Electron recreated small profile directories during shutdown; both newly created profiles explicitly removed afterward. Existing lead profile untouched. Scratch retained in /tmp/issue-24812, node_modules symlink only for test resolution; source checkout clean. Generated bundles/profiles are not uploaded.

FRICTION | build flags | esbuild rejects external wildcard with two stars | use exact absolute package external paths
FRICTION | scratch fixture | JS default parameter converted explicit undefined into page session | use ROOT sentinel to omit sessionId; corrected scratch fixture passes
FRICTION | cleanup | Electron recreated profile files after pre-quit removal | remove new profiles after process exit and verify process groups
