## F11-overflow — Pixel 9, dark — medium-detent AppBar menu

**Menu behavior is the same on both commits; no menu regression observed. The final scroll endpoints differ: before remains at folder 01; after reaches `zz-added-after-open`. This is the scrolling behavior addressed by the PR. The before folder check remains unverified because scrolling cannot reach the end.**

Both fresh medium sheets show “Refresh files” in the app window above the native sheet, outside its accessibility snapshot. I read the item from each screenshot and tapped `(600, 280)` on both. Both taps dismiss the sheet; no refresh spinner is visible. **Whether the menu refresh callback fired is unverified.** Reopening alone refetches: the sheet unmounts its Files pane on dismissal, and `useFileTreeEntries` calls `refreshRoot()` on mount. The new folder after reopening cannot be attributed to the menu tap. [source-check.md](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/65a3d7da6c2800ef/source-check.md)

Environment: same leased Pixel 9 Android emulator, 1080×2424 whole-device stills/video; dark theme; medium text size, Android font scale 0.94; com.t3tools.t3code.dev, native fingerprint `832d41716ea2dfac7350605db3fd07914f87d6ef`. Same cached native client; matching checkout JavaScript served by Metro on all interfaces at port 8081. Separate fresh databases created by each checkout with `T3CODE_DEV_SEED=0`; backend bound to `0.0.0.0`. Same copied seed driver and synthetic forty-folder fixture per side. No live userdata or paid provider used.

Scripted steps and timestamps, above the recording pair (seconds from recording-start request; remote dispatch time, not exact encoded-video time):

- **Before**: 4.115s: `press label="Open files"`; 19.208s: `press label="More actions"`; 52.508s: create `zz-added-after-open` on disk; 52.508s: `press 600 280`; 75.051s: `press label="Open files"`; 180.602s: expand via header `gesture pan 540 1030 0 -850 650`; 193.173s: `scroll bottom` (no progress). [F11-overflow-before-steps.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a8cb237c9c9d826c/F11-overflow-before-steps.json)
- **After**: 3.415s: `press label="Open files"`; 25.773s: `press label="More actions"`; 75.728s: create `zz-added-after-open` on disk; 75.728s: `press 600 280`; 90.513s: `press label="Open files"`; 102.299s: expand via header `gesture pan 540 1030 0 -850 650`; 107.459s: `scroll bottom` (reaches new folder). [F11-overflow-after-steps.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/94a984df9f5dab2f/F11-overflow-after-steps.json)

The before take includes a pool transport interruption after reopening; recording export initially failed. Capture resumed on the same device, then the two native 180-second recorder chunks were concatenated without re-encoding. The long pause is retained. Neither side pulls the sheet before opening its menu; both menu frames have the same medium detent (top edge about y=972). After the tap, both reopen at medium, then use the same header expansion and scroll-to-bottom command.

| Capture | Before<br>[4c361199f4](https://git.cafe/pingdotgg/t3code/commit/4c361199f47f6ea32a2c14835df392640d0f7c63) | After<br>[23310d1489](https://git.cafe/pingdotgg/t3code/commit/23310d14893fba4b420c4ff0b0c5ae73fe39bbbe) | Diff0: fuzz 0, amplified<br>[4c361199f4](https://git.cafe/pingdotgg/t3code/commit/4c361199f47f6ea32a2c14835df392640d0f7c63) → [23310d1489](https://git.cafe/pingdotgg/t3code/commit/23310d14893fba4b420c4ff0b0c5ae73fe39bbbe) | DiffT: fuzz 2%<br>[4c361199f4](https://git.cafe/pingdotgg/t3code/commit/4c361199f47f6ea32a2c14835df392640d0f7c63) → [23310d1489](https://git.cafe/pingdotgg/t3code/commit/23310d14893fba4b420c4ff0b0c5ae73fe39bbbe) |
|---|---|---|---|---|
| Whole-device recording | [F11-overflow-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2f6999387ae66476/F11-overflow-before.mp4) | [F11-overflow-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a29f360057a8bce9/F11-overflow-after.mp4) | — | — |
| Open menu, same medium detent | ![F11-overflow-before-open-menu.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/24d4b26fb6d1116a/F11-overflow-before-open-menu.png) | ![F11-overflow-after-open-menu.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9c8549016adfea76/F11-overflow-after-open-menu.png) | ![F11-overflow-open-menu-Diff0.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/de1d2f6c83b81cf2/F11-overflow-open-menu-Diff0.png)<br>AE=2621 | ![F11-overflow-open-menu-DiffT.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/454852c927134dd3/F11-overflow-open-menu-DiffT.png)<br>AE=2455 |
| Tap endpoint: sheet dismissed | ![F11-overflow-before-tap-end.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/850951a558a8afcf/F11-overflow-before-tap-end.png) | ![F11-overflow-after-tap-end.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9367477f5e56fea4/F11-overflow-after-tap-end.png) | ![F11-overflow-tap-end-Diff0.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3b9dce9bd2693b44/F11-overflow-tap-end-Diff0.png)<br>AE=756 | ![F11-overflow-tap-end-DiffT.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/c82af8663d097e86/F11-overflow-tap-end-DiffT.png)<br>AE=703 |
| Reopen, expand, scroll to end attempt | ![F11-overflow-before-end-state.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/43b8492e9f4bddd8/F11-overflow-before-end-state.png) | ![F11-overflow-after-end-state.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/fad34ba397ce9250/F11-overflow-after-end-state.png) | ![F11-overflow-end-state-Diff0.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b14cca685243614b/F11-overflow-end-state-Diff0.png)<br>AE=73602 | ![F11-overflow-end-state-DiffT.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/533387c0a899f6e0/F11-overflow-end-state-DiffT.png)<br>AE=67117 |

Settling: every selected source still has two pixel-identical screenshots (AE=0, fuzz 0), requested with a 500 ms wait; actual pool screenshot dispatch spacing is longer. Independent video frame pairs exactly 500 ms apart also have AE=0: before menu 25/25.5s, dismissal 65/65.5s, endpoint 230/230.5s; after menu 40/40.5s, dismissal 85/85.5s, endpoint 120/120.5s. The archive contains both proof methods. [F11-overflow-settling-proof.zip](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2745f70d9e76141d/F11-overflow-settling-proof.zip)

Diff0 maps every changed pixel to white, including a one-level RGB change; DiffT uses the same comparison with fuzz 2%. No crop, normalization, or registration. Source stills and all six diffs were visually reviewed.

What else changed:

- Status-bar clock and cellular indicator pixels differ between runs.
- Menu frames also contain small folder-outline/chevron pixel differences at matching list positions. Menu, header and medium-sheet geometry match.
- The final list offset differs because main cannot scroll the tree; after can. This endpoint difference does not establish a menu-refresh difference.
- Before has a transport pause and two concatenated native recording chunks; after is uninterrupted. No spinner frame is selected as a settled endpoint.

Unverified: the menu callback firing on either side, and whether the newly added folder is visible at the end of the before tree. Reopening refreshes independently, and main cannot scroll there. The disk folder was created before each tap; after visibly shows it after reopening and scrolling.

Cleanup: all started servers and Metro exited; the pool session was closed; both `pr-33223-f11-before` and `pr-33223-f11-after` worktrees were removed. Original evidence-capture-1 and the lead worktree were not modified.

Supporting scripts and verification (ghdrop output reproduced verbatim):

- [run-f11.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d85aab4dcdd07a4e/run-f11.py)
- [diff-manifest.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/08783b4eb74da043/diff-manifest.json)
- [pairs.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/172be4c28bcfacb2/pairs.json)
- [video-stability.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/adb0fe10a38e545f/video-stability.py)
- [video-stability.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/cd487db809665217/video-stability.json)
- [finish-f11.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/96bcfb654cbf0119/finish-f11.py)
- [FRICTION.md](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/7e52d736e9f25bcc/FRICTION.md)
- [source-check.md](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/65a3d7da6c2800ef/source-check.md)
- [package-f11.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e5ce74615cf9e5ea/package-f11.py)
- [upload-f11.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/98318fea3f15ede1/upload-f11.py)
- [device.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/fa0d076bf18ec52b/device.py)
- [capture.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/816ba891ba95d21b/capture.py)
- [diffs.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/434dcfa11b183fa7/diffs.py)
- [settling.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e68d80fc50cf696f/settling.json)
- [seed.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/fbc3f9714ea9a746/seed.mjs)

- [report-f11.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/182ea6e2764a0a7b/report-f11.py)

FRICTION:

- tool | The dev-client install completed, but its automatic open returned “Remote daemon is unavailable”. | Separate install from batch open and use unique request IDs; retry after one minute.
- other | A snapshot requested while install was still running failed Android snapshot-helper instrumentation. | Await installation before sending device commands.
- tool | A later pool screenshot and record-stop both returned “Remote daemon is unavailable”, interrupting the second before take after reopening. | A stable pool transport; resume and retry record export after one minute.
- other | On main, expanding the sheet then scroll bottom reports no progress, and a direct list pan also leaves folder 01 in place. | The PR's scroll fix; the before endpoint cannot show the added folder by scrolling.
- runbook | After clearing app data, the first Metro deep link stayed on the development-client launcher, so the first after pairing route did not reach JavaScript. | Wait for a matching Metro bundle load before pairing; repeat the Metro deep link, then mint a fresh pairing credential.
- tool | The recovered before recording exceeded Android's 180-second screenrecord cap and exported two chunks. | Concatenate the two chunks without re-encoding, and disclose the transport pause.
