# F4-Android — compact long-path alert (harness)

Captured 1 / requested 1 row for [#32994](https://git.cafe/pingdotgg/t3code/pull/32994). No other matrix rows recaptured. Before [fa2f4ff2a2](https://git.cafe/pingdotgg/t3code/commit/fa2f4ff2a2bac5ac92e07749f6b83b0003d642a0); after [7fc7ab5eb6](https://git.cafe/pingdotgg/t3code/commit/7fc7ab5eb6a3b2dfd00a9261b7d0d2920e53fadb).

Environment (every still and recording on both sides): leased Pixel 9, Android 16 / API 36, portrait; wm size override 945×2100, wm density explicitly set to 420 (same as physical density); DPR 2.625; verified native window and screen 360×800 dp; OS font_scale 1.5 and native fontScale 1.5; OS and app dark. Whole-screen PNGs 945×2100. Native Android screenrecord exports 944×2100 because the encoder requires an even width; no crop or resize applied by the capture driver. Status-bar demo clock fixed at 10:00 on both sides.

Both real JS apps were bundled and launched through separate Metro instances from their own specified checkouts (before 8081, after 8082). They shared the same native development client and one fresh backend from the after checkout, started with T3CODE_DEV_SEED=0. The scratch replay-provider transcript seeded a minimal project/thread through the app CLI. No live database, lead worktree data, real provider turn, or real customer data was read or copied. No tracked files in the after checkout were modified.

Labelled native harness: the unchanged prior long-path expression replaces refreshAssetUrl at runtime with an actual AssetWorkspaceAssetNotFoundError. The checked path starts /synthetic/mixed spaces-é-資料/, contains eight long segments, and ends last-readable-segment.png. The actual FilePreviewSession and Android Compose Dialog render and dismiss the error. This is deterministic harness proof, not a claim of a persisted long-path filesystem fixture.

Each selected still, path endpoint and starting/settled thread passed two pixel-identical screenshot commands with a 500 ms pause between calls (pool transport adds time). All eight pairs had 0 changed pixels. Starting thread frames and settled thread frames also match between sides byte-for-byte. Every selected image and diff was opened and visually inspected; recording sequences and exact final decoded frames were inspected. The exact final frames are clean threads; a penultimate transitional frame must not be mistaken for the clip's last frame.

## Initial alert stills — 360×800 dp · dark · font 1.5×

| Before | After | Diff0 | DiffT |
| --- | --- | --- | --- |
| ![Before: old reconnect alert](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/29e68963202c51b8/F4-before.png)<br>[fa2f4ff2a2](https://git.cafe/pingdotgg/t3code/commit/fa2f4ff2a2bac5ac92e07749f6b83b0003d642a0) | ![After: scrollable long-path file-not-found alert](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/cc15dad05b05df25/F4-after.png)<br>[7fc7ab5eb6](https://git.cafe/pingdotgg/t3code/commit/7fc7ab5eb6a3b2dfd00a9261b7d0d2920e53fadb) | ![Zero-threshold RGB diff amplified 32×](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/172ccfa3998d0e63/Diff0.png)<br>[fa2f4ff2a2](https://git.cafe/pingdotgg/t3code/commit/fa2f4ff2a2bac5ac92e07749f6b83b0003d642a0) → [7fc7ab5eb6](https://git.cafe/pingdotgg/t3code/commit/7fc7ab5eb6a3b2dfd00a9261b7d0d2920e53fadb) | ![Pixels differing by more than 8/255 marked red](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/131e47032ab48e28/DiffT.png)<br>[fa2f4ff2a2](https://git.cafe/pingdotgg/t3code/commit/fa2f4ff2a2bac5ac92e07749f6b83b0003d642a0) → [7fc7ab5eb6](https://git.cafe/pingdotgg/t3code/commit/7fc7ab5eb6a3b2dfd00a9261b7d0d2920e53fadb) |

Diff0: absolute RGB difference, zero threshold, multiplied 32× with saturation so a one-level change becomes 32/255. DiffT: red wherever any absolute RGB channel difference is >8/255, over the after image white-colorized 70%. Of 1,984,500 pixels, 1,097,052 differ at zero threshold and 1,001,597 exceed 8/255. Outside the half-open alert rectangle [52,63,892,2037], 0 pixels differ at zero threshold. Status bar, background outside that rectangle, and navigation bar are identical.

## Scripted interaction and recordings

Identical driver on both sides: begin on Preview checks → tap missing-image chip → initial alert and stable screenshot pair → eight upward swipes within the alert body (470,1120 to 470,800, 400 ms pause) → stable endpoint → tap OK → stable settled thread → stop. Before's short reconnect body has no path and does not move; the same gestures are attempted. After scrolls to the complete last-readable-segment.png with OK reachable.

Timestamps below are UTC command starts, not exact clip offsets. Android encodes changed frames only and ends at the last encoded frame; long unchanged tails are omitted. Both exact last decoded frames were inspected and show the dismissed thread.

- Before: 11:33:29.100 start; 11:33:33.197 tap chip; 11:33:42.053 eight body swipes; 11:33:49.618 endpoint screenshot; 11:33:57.653 OK; 11:34:03.906 settled-thread screenshot; 11:34:09.509 stop. Export duration 28.840 seconds.
- After: 11:35:38.170 start; 11:35:42.195 tap chip; 11:35:50.382 eight body swipes; 11:35:58.061 final-filename screenshot; 11:36:05.734 OK; 11:36:12.045 settled-thread screenshot; 11:36:17.479 stop. Export duration 27.851 seconds.

| Before recording | After recording |
| --- | --- |
| [F4-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/584de55887496b29/F4-before.mp4)<br>[fa2f4ff2a2](https://git.cafe/pingdotgg/t3code/commit/fa2f4ff2a2bac5ac92e07749f6b83b0003d642a0) | [F4-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/1da2955bee03c30d/F4-after.mp4)<br>[7fc7ab5eb6](https://git.cafe/pingdotgg/t3code/commit/7fc7ab5eb6a3b2dfd00a9261b7d0d2920e53fadb) |

After endpoint: ![After: full final filename and reachable OK](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/df506627dadebf20/path-end.png)

## What else changed

- Body changes from reconnect/moved-or-deleted guidance to the specific file-not-found checked path, including Unicode, spaces and long wrapping segments.
- The dialog grows from a centered card to nearly the full available height. Its title moves upward and OK moves downward; more thread content is occluded. Dialog width, title copy, typography, colors, and OK styling remain the same.
- The long body scrolls while title and OK stay fixed. Partial lines at the scroll viewport edges are expected; the complete final filename is readable at the endpoint.
- No additional visible changes were found. Outside the alert rectangle there are zero changed pixels; both settled thread frames match exactly.

Unverified requested rows: none.

Cleanup verified: wm size reset to 1080×2424; density reset to 420; font_scale reset to 1.0; demo clock exited; agent-device close succeeded. Both Metro sessions exited 130 and backend session exited 143. No listeners remain on 8081, 8082, 14551 or 6248. Before worktree removed; after checkout clean. Scratch removed after final uploads. No PR edits, comments, commits or pushes.

## Verbatim ghdrop output

![F4-before.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/29e68963202c51b8/F4-before.png)
[F4-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/584de55887496b29/F4-before.mp4)
![F4-after.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/cc15dad05b05df25/F4-after.png)
[F4-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/1da2955bee03c30d/F4-after.mp4)
![Diff0.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/172ccfa3998d0e63/Diff0.png)
![DiffT.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/131e47032ab48e28/DiffT.png)
![path-end.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/df506627dadebf20/path-end.png)
[capture-integrity.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e1b901ebb00803ec/capture-integrity.json)

[seed-f4.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/23a12ddb45be6638/seed-f4.py)
[f4-replay-agent.ts](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/c1107e7c0cc4bccf/f4-replay-agent.ts)
[f4-transcript.ndjson](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/eb62bc5089e1e81f/f4-transcript.ndjson)
[capture-f4.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/584cc6de837e2699/capture-f4.py)
[runtime.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/23829a521841e611/runtime.mjs)
[eval-native.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/255a44d34389a11f/eval-native.py)
[pool-adb.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2c13c7a008fa5f44/pool-adb.mjs)
[build-diffs.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2194ae58d051979b/build-diffs.py)
[long-path-expression.txt](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d10b459f6a5b01d4/long-path-expression.txt)
[environment-expression.txt](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/716c6c51b6267625/environment-expression.txt)
[reproduce.sh](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2a2959eddf6f8ce4/reproduce.sh)

[F4-stable-pairs-and-transcripts.zip](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/7682550e433023f3/F4-stable-pairs-and-transcripts.zip)

FRICTION:
- tool | agent-device devices is refused by the pool; settings and session commands intermittently reported Remote daemon unavailable; the leased-device REST ADB passthrough worked | Document the supported pool ADB endpoint and inventory route in device-pool.
- tool | Metro debugger helper failed with missing Origin/transport disconnects; explicit Origin plus relaunch restored direct CDP runtime evaluation | A CDP helper that supplies Metro's required Origin and detects stale app runtime connections.
- tool | Android records only changed frames, so a frame sampled just before the end still showed dismissal animation | Decode the exact last frame; both exact tails show the clean thread. Preserve wall-clock command timestamps separately from clip offsets.
- runbook | An initial vp install ran from /home/user, then was rerun in the requested before checkout; it reported already up to date in the first location | Run checkout creation and dependency installation as separate commands with explicit workdir.

- tool | Optional inline HTML inspection timed out twice; the evidence files and inline render remained available | A healthy headless preview renderer.
