# Integrated desktop runtime evidence

Before: [80e62619f5](https://github.com/pingdotgg/t3code/commit/80e62619f5c01d84579bcf70ea6d566712007412); after: [1b38b8ce40](https://github.com/pingdotgg/t3code/commit/1b38b8ce4013459df0066f29528632bf26a3057f).

Ubuntu 24.04.4 LTS Linux x64; Electron 44.10.1 / Chromium 152.0.7977.169; Xvfb 1920x1080x24 + Openbox; --no-sandbox --disable-gpu --ozone-platform=x11 --password-store=basic --inspect=0 --remote-debugging-port=<ephemeral>. Raw Electron spawn; Playwright CDP attaches only after startup. Before E/D absent; after E=CDPScreenshotNewSurface, D absent. Each own server creates a fresh isolated T3CODE_HOME with T3CODE_DEV_SEED=0.

The same driver, deterministic synthetic page and isolated settings are used on both sides. A local protocol fixture holds a synthetic agent turn open, obtaining the normal thread-scoped MCP credential; no model service is called. Tools traverse production MCP → ServerBrowser/ServerBrowserPage → desktop CDP relay/host → renderer IPC → actual Electron webview. Runtime confirms a webview guest and rejects a headless fallback. The recording encoder scratch browser is a normal production dependency, not the tab being tested.

R3: 8 shown, 8 hidden, 8 shown again, 4 after reload; hidden native element at (-100000,-100000), status.visible=false; shown native element (617,80) 483x700; reload loadId changes. Each capture checks decoded PNG pixel (10,10), current visible text and accessibility tree. R4: viewer attach, snapshot, viewer motion and delayed ACKs to trigger production settle JPEG refresh, then recording start → four snapshots → stop. R5: native minimize event and isMinimized=true, snapshot, native restore event and isMinimized=false, two snapshots. One-second presentation holds make each window state visible in the uncut x11grab screen recordings.

| Row / phase | Before count; median / max ms | After count; median / max ms | Result |
|---|---|---|---|
| R3 | 28/28; 49 / 77 | 28/28; 64 / 110 | All fresh text/tree/pixels; no snapshot timeout |
| R4 | 5/5; 62 / 64 | 5/5; 53 / 61 | All fresh text/tree/pixels; no snapshot timeout |
| R5 | 3/3; 47 / 64 | 3/3; 39 / 43 | All fresh text/tree/pixels; no snapshot timeout |

| JPEG / coordination observation | Before ms | After ms |
|---|---|---|
| Viewer first JPEG CDP capture | 23 | 17 |
| Viewer subsequent still-refresh JPEG captures | 23, 21, 13, 28, 12, 12, 21 | 17, 5, 5, 7, 6, 7, 6 |
| Viewer first received frame after attach | 37 | 45 |
| Recording seed JPEG CDP capture | 15 | 7 |
| Full recording_start call (includes encoder preparation) | 5024 | 12590 |
| Full recording_stop call | 73 | 86 |

All native CDP timings are observed by a call-through wrapper of the actual guest debugger.sendCommand. It records method/format/duration/result length and returns the original result unchanged. Source files are unmodified. JPEG refreshes and PNG snapshot pause/resume commands are retained in full NDJSON. The viewer first received frame can be a live screencast frame; the separate captureScreenshot JPEG trace establishes the still path independently.

Both sides pass this finite integrated fixture. The original busy-page timeout did not reproduce here; these runs establish integration/regression behavior, not a measured stall improvement or a latency benchmark. The recording-start timing difference includes a fresh encoder setup and download; its actual CDP JPEG capture is measured separately. Native Wayland, GPU-enabled/sandbox-enabled operation, packaged distribution, physical macOS and Windows are outside this run. R6= cannot-verify macos; R7= cannot-verify windows.

What else changed: only the three PR source files differ between the two SHAs. Builds, driver/page, flags, settings, protocol fixture and CDP observer are identical; UUIDs, ephemeral ports, capture timestamps and encoder initialization timing differ. No source edits, commits, pushes, real thread imports or live T3 database reads/seeds.

desktop-before-after.mp4 places the uncut source captures side by side, aligned at recording start; the before frame freezes after its run completes. Each side has its own UTC timestamp and scripted step above it. This presentation is not synchronized by phase or used for timing comparisons; original recordings and NDJSON remain authoritative.
