# M1 Android replacement — accepted

[PR #26086](https://git.cafe/pingdotgg/t3code/pull/26086). Before [d1c4b52b7c](https://github.com/pingdotgg/t3code/commit/d1c4b52b7c7c7e1b7637ec47e4c959ff0c2d8d99); after [652e9c18ce](https://github.com/pingdotgg/t3code/commit/652e9c18cee800df7e255916365967ba211097ae). Captured 27 October 2026 on fs-21 using separate fresh databases and native clients; synthetic content only. No commits, pushes or PR body edits.

Pixel 9, Android 16 / API36, light appearance, logical viewport 411.428571 × 923.428571, DPR 2.625, physical 1080 × 2424, font scale 1.0. Frozen client/server clock 2026-10-27 12:00:00 UTC; same prompt, title, metadata and keyboard-dismissed state. Full screen, no crops/translations. Status-bar-only exclusion: physical rows 0–62 inclusive.

Root cause: the original short feed mounted bottom aligned (`alignItemsAtEnd`, `initialScrollAtEnd`). Reopening the after thread reproduced 3,446 unrelated Diff16 pixels in the unchanged prompt/timestamp/copy icon in five attempts. Scrolling the short feed did not establish a top origin. The replacement creates the same empty Nonzero exit fixture on both sides and submits the unchanged prompt through the native composer. Its first-submission top anchor stays fixed as the failure arrives. This is native behavior, with no layout instrumentation or image alignment. The real SDK still builds the exit-7 error from the auth-free subprocess stub.

Both idle stills have a second capture after a 500 ms wait between screenshot commands. Each pair is pixel-identical outside the status bar (Diff0 = 0). ![M1-android-before-settle.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e0c57a0116858888/M1-android-before-settle.png) ![M1-android-after-settle.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5b1768a7fbfb4fa5/M1-android-after-settle.png).

| Before | After | Diff0 amplified | Diff16 |
|---|---|---|---|
| ![M1-android-before.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/4904adaa6292617b/M1-android-before.png)<br>SHA256: `c60c45fa956c30d308bfaad7c2232d6f1e52212cfd322c9963a7ed6b85323f47`<br>Source [d1c4b52b7c](https://github.com/pingdotgg/t3code/commit/d1c4b52b7c7c7e1b7637ec47e4c959ff0c2d8d99) | ![M1-android-after.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a8b6f110933532d0/M1-android-after.png)<br>SHA256: `62b23119dc3461e99e7941a680fe6d4de04c385e425177f6b6e5ed1ab9b22433`<br>Source [652e9c18ce](https://github.com/pingdotgg/t3code/commit/652e9c18cee800df7e255916365967ba211097ae) | ![M1-android-diff0.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ae7153909f41d0aa/M1-android-diff0.png)<br>SHA256: `0869d6cb13460aa65106cf3ffe1a44e4f97e339543e604110dabc8f3dcfe79dc`<br>Compared [d1c4b52b7c](https://github.com/pingdotgg/t3code/commit/d1c4b52b7c7c7e1b7637ec47e4c959ff0c2d8d99) → [652e9c18ce](https://github.com/pingdotgg/t3code/commit/652e9c18cee800df7e255916365967ba211097ae) | ![M1-android-diff16.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b042ee081cd14595/M1-android-diff16.png)<br>SHA256: `c1c7ce2dab638781e469d5186f5b8ca1007a9c34c878fdb3e725ece7336657aa`<br>Compared [d1c4b52b7c](https://github.com/pingdotgg/t3code/commit/d1c4b52b7c7c7e1b7637ec47e4c959ff0c2d8d99) → [652e9c18ce](https://github.com/pingdotgg/t3code/commit/652e9c18cee800df7e255916365967ba211097ae) |

Failure sentence physical rows 734–769 inclusive. Diff0 (>0/255, amplified categorical highlight): 7,872 pixels total, **0 outside the failure sentence**. Diff16 (>16/255): 7,136 pixels total, **0 outside the failure sentence** after the status-only exclusion. No prompt, timestamp, copy icon or other content was masked.

Recording script and observed timestamps, identical on both sides: 0–1 s idle failure; long-press provider-error row after 1 s; at 3 s “Copied” feedback and Android clipboard preview; at 5 s and 8 s preview remains visible. These are real native clipboard overlays; no composer paste is performed. Comparison clips retain the first 9 seconds, trimming only trailing idle, and mask only status rows 0–62. Full originals retain the complete recording. Extracted 1, 3, 5 and 8 s frames were opened, and full raw videos decoded and visually reviewed at 5 fps.

| Before recording | After recording |
|---|---|
| [M1-android-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/162ebeb1717ce04a/M1-android-before.mp4)<br>SHA256: `4d430c9bbeb0b9fcc99c28bf88be663e770c5b03a888aa62d4d003ec0d51b61d`<br>[d1c4b52b7c](https://github.com/pingdotgg/t3code/commit/d1c4b52b7c7c7e1b7637ec47e4c959ff0c2d8d99) | [M1-android-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/fc973e7d2a15d34a/M1-android-after.mp4)<br>SHA256: `fca727008960c66cc50b210de7c8dce286f9e472b98553bb02a0a0073626c29f`<br>[652e9c18ce](https://github.com/pingdotgg/t3code/commit/652e9c18cee800df7e255916365967ba211097ae) |

Full originals: [M1-android-before-raw.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5fd6d2776f0d7a5e/M1-android-before-raw.mp4); [M1-android-after-raw.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b52d735a9643410a/M1-android-after-raw.mp4). Command transcripts: [M1-android-before-steps.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/303d2cba3b592604/M1-android-before-steps.json); [M1-android-after-steps.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/dde559e35a31b4df/M1-android-after-steps.json). Synthetic persisted messages/errors: [M1-fixture-transcript.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5bc1c3b34ae1a575/M1-fixture-transcript.json).

What else changed: nothing outside the failure sentence in the new still pair at either threshold, excluding only the system status bar. Compared with the rejected old pair, both sides now use the same native top anchor and a newly submitted fixture thread; those fixture IDs differ from the old run but are not visible. Copy preview content changes with the copied failure. Other M1 evidence and disclosed iOS Diff0 one-level shadow/glass noise stand unchanged.

Scripts and full reproduction: [native-recapture-scripts.zip](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d41022aa81634564/native-recapture-scripts.zip); [reproduce-native-recapture.md](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/fd8512d908b5bc9f/reproduce-native-recapture.md). The ZIP contains all 24 capture, seed, pairing, clock, geometry, review, packaging and cleanup scripts written/adapted before packaging; make-replacement-sheets.py is uploaded separately with this sheet. Runtime metadata: [native-environment.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/35f146c6ca208ce0/native-environment.json). Pixel/settling verification: [checks.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/95ca5c3d13194478/checks.json). Artifact hashes: [SHA256SUMS.txt](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/846a741824d845bb/SHA256SUMS.txt).


Individual script uploads:

[make-replacement-sheets.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d166b222a24cbefc/make-replacement-sheets.py)
[capture-native.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/09223870ed011d75/capture-native.py)
[preload-sidebar.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/39b48bc3209314a4/preload-sidebar.py)
[seed-mobile-anchor.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5fac2dafacb74e0f/seed-mobile-anchor.mjs)
[build-replacement.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/be3cf975a19cbb6a/build-replacement.py)
