# M3 — round 2 native: Sidebar selected ↔ unselected failure preview

Additional differences outside the changed error text: iPad native glass control/composer shadows and edges have low-level differences visible in Diff0, absent at Diff16. Android tablet differences are confined to the two preview sentences and the feed failure sentence.

Captured from before [d1c4b52b7c](https://github.com/pingdotgg/t3code/commit/d1c4b52b7c7c7e1b7637ec47e4c959ff0c2d8d99) and after [652e9c18ce](https://github.com/pingdotgg/t3code/commit/652e9c18cee800df7e255916365967ba211097ae) for [#26086](https://git.cafe/pingdotgg/t3code/pull/26086).

**Tablet alternative, explicitly labelled:** compact iPhone/Pixel layouts do not render `ThreadNavigationSidebar`; this is not a hidden phone drawer. [layout.ts](https://github.com/pingdotgg/t3code/blob/652e9c18cee800df7e255916365967ba211097ae/apps/mobile/src/lib/layout.ts#L9) requires width ≥720 and height ≥600 (or UIKit regular usable width ≥600). [AdaptiveWorkspaceLayout.tsx](https://github.com/pingdotgg/t3code/blob/652e9c18cee800df7e255916365967ba211097ae/apps/mobile/src/features/layout/AdaptiveWorkspaceLayout.tsx#L300) gates the primary sidebar on `usesSplitView`. The matrix permits tablet geometry for this same rendering branch. iPad light and Pixel Tablet dark cover selected/unselected plus hide/reopen, rather than mislabelling phone Back/Home as sidebar proof.

**Environment — light:** iPad Pro 13-inch (M5) simulator · iOS 27.2 · 1032×1376 logical · DPR 2 · font scale 1.0 (OS text-size large) · portrait · PNG 1032×1376, recording 2064×2752. Status-only mask: PNG rows **0–27**, recording rows **0–55** (inclusive).

**Environment — dark:** Pixel Tablet emulator · Android 16 / API 36 · 1280×800 logical · DPR 2 · font scale 1.0 (OS text-size large) · landscape · PNG/recording 2560×1600. Status-only mask: rows **0–47** (inclusive).

Real T3 native development client, JavaScript from each side’s own checkout and one Metro on port 8081 at a time. Separate fresh servers, created with `T3CODE_DEV_SEED=0`; data inserted through real app RPC, no copied database and no component harness. Claude’s real SDK runs the auth-free fixture executable, which emits a partial reply then terminates by SIGABRT or exit 7. The SDK/adapter/orchestrator create the actual persisted failures.

Both sides use identical capture-only Date instrumentation in `apps/mobile/index.ts` and a server Date preload: **2026-10-27T12:00:00.000Z**; real timers continue normally. This freezes app-relative dates without altering rendering components or injecting error payloads. No instrumentation was committed. The same cached native binary serves both sides: iOS fingerprint `e416a21c6a355b943ac5530d1cc2f8f2d446aa0e`; Android `f2adc10370e29967253ba5e4fa64d66a88ee3798`.

`--normalize-status-bar` exists, but simulator clock/battery pixels revert between commands and within recordings. Only the exact top status rows stated below are excluded from settle/diffs and blacked out in comparison recordings. No other region is masked or cropped. Stills retain their full original screen; raw recordings are linked too.

Before each submitted still, the driver takes two full screenshots with a 500 ms pause between screenshot commands and accepts them only if pixel-identical outside that status strip. The uploaded `*-settle.png` and `*-settled.json` preserve the second frame and check. All primary stills and both diffs were opened and inspected. Recordings were reviewed through frame contact sheets.

**Diff algorithm:** max absolute RGB-channel difference per pixel; Diff0 highlights every nonzero difference in saturated pink (including a one-level change). Diff16 highlights pixels with a channel difference **>16/255** in orange. Unchanged pixels are gray; excluded status rows dark gray. No registration, scaling, cropping, blur, or non-status exclusion is applied before comparison.

| Fixture | Before<br>[d1c4b52b7c](https://github.com/pingdotgg/t3code/commit/d1c4b52b7c7c7e1b7637ec47e4c959ff0c2d8d99) | After<br>[652e9c18ce](https://github.com/pingdotgg/t3code/commit/652e9c18cee800df7e255916365967ba211097ae) | Diff0<br>[d1c4b52b7c](https://github.com/pingdotgg/t3code/commit/d1c4b52b7c7c7e1b7637ec47e4c959ff0c2d8d99) → [652e9c18ce](https://github.com/pingdotgg/t3code/commit/652e9c18cee800df7e255916365967ba211097ae) | Diff16<br>[d1c4b52b7c](https://github.com/pingdotgg/t3code/commit/d1c4b52b7c7c7e1b7637ec47e4c959ff0c2d8d99) → [652e9c18ce](https://github.com/pingdotgg/t3code/commit/652e9c18cee800df7e255916365967ba211097ae) |
|---|---|---|---|---|
| M3 · iPad Pro · light · Signal selected/muted | ![M3-iospad-selected-before.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/cf240f14f423fc51/M3-iospad-selected-before.png) | ![M3-iospad-selected-after.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5b5913ca6ef76832/M3-iospad-selected-after.png) | ![M3-iospad-selected-diff0.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/234d017538b53f76/M3-iospad-selected-diff0.png) | ![M3-iospad-selected-diff16.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d8fa02c786a5dbe0/M3-iospad-selected-diff16.png) |
| M3 · iPad Pro · light · Signal unselected/red | ![M3-iospad-unselected-before.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/4a8b495101ca67c4/M3-iospad-unselected-before.png) | ![M3-iospad-unselected-after.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/6d6f07fea55af8a0/M3-iospad-unselected-after.png) | ![M3-iospad-unselected-diff0.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a25b7c8674c6a2ab/M3-iospad-unselected-diff0.png) | ![M3-iospad-unselected-diff16.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/56a470ce0bb8b22d/M3-iospad-unselected-diff16.png) |
| M3 · Pixel Tablet · dark · Signal selected/muted | ![M3-androidtab-selected-before.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d8a9a8541682018e/M3-androidtab-selected-before.png) | ![M3-androidtab-selected-after.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/10b287bc375dcc81/M3-androidtab-selected-after.png) | ![M3-androidtab-selected-diff0.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f47718b1fa0451bc/M3-androidtab-selected-diff0.png) | ![M3-androidtab-selected-diff16.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/0740e28b5ec3b048/M3-androidtab-selected-diff16.png) |
| M3 · Pixel Tablet · dark · Signal unselected/red | ![M3-androidtab-unselected-before.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f3649d39694fac58/M3-androidtab-unselected-before.png) | ![M3-androidtab-unselected-after.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/0628329b4035ddc4/M3-androidtab-unselected-after.png) | ![M3-androidtab-unselected-diff0.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b522edfc0385aa1e/M3-androidtab-unselected-diff0.png) | ![M3-androidtab-unselected-diff16.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/c7a235bed3bd098f/M3-androidtab-unselected-diff16.png) |

## M3 · iPad Pro · light · Signal selected/muted — recording steps

At 0 s Signal termination is selected and its preview is muted. The driver hides the primary column with **Maximize content**, reopens it with **Show thread sidebar** (iOS) / **Show sidebar** (Android), selects **Nonzero exit**, hides and reopens once more, then captures Signal termination unselected with danger-colored preview. Both failures remain visible in the primary column.

Command completion timestamps below are seconds from the driver’s recording-start return; device RPC/encoder latency means they are approximate video timestamps. The interaction order and explicit 1-second pauses are identical.

| Step | Before seconds | After seconds |
|---|---:|---:|
| press Maximize content | 3.73 | 3.85 |
| press Show thread sidebar | 6.99 | 6.79 |
| press Nonzero exit | 10.32 | 10.20 |
| press Maximize content | 14.27 | 13.99 |
| press Show thread sidebar | 17.01 | 16.65 |

| Before recording | After recording |
|---|---|
| [M3-iospad-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/18d468d57bb408c6/M3-iospad-before.mp4) | [M3-iospad-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/dd02876bafe736ce/M3-iospad-after.mp4) |

Raw, unmasked originals: [M3-iospad-before-raw.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f47d2432dd4845bc/M3-iospad-before-raw.mp4), [M3-iospad-after-raw.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9f23bff480292b2e/M3-iospad-after-raw.mp4).

## M3 · Pixel Tablet · dark · Signal selected/muted — recording steps

At 0 s Signal termination is selected and its preview is muted. The driver hides the primary column with **Maximize content**, reopens it with **Show thread sidebar** (iOS) / **Show sidebar** (Android), selects **Nonzero exit**, hides and reopens once more, then captures Signal termination unselected with danger-colored preview. Both failures remain visible in the primary column.

Command completion timestamps below are seconds from the driver’s recording-start return; device RPC/encoder latency means they are approximate video timestamps. The interaction order and explicit 1-second pauses are identical.

| Step | Before seconds | After seconds |
|---|---:|---:|
| press Maximize content | 4.28 | 4.14 |
| press Show sidebar | 8.16 | 8.01 |
| press Nonzero exit | 11.40 | 11.55 |
| press Maximize content | 15.05 | 15.79 |
| press Show sidebar | 18.70 | 19.66 |

| Before recording | After recording |
|---|---|
| [M3-androidtab-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5af39bfaa09f7bdc/M3-androidtab-before.mp4) | [M3-androidtab-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f3e2665e605b9feb/M3-androidtab-after.mp4) |

Raw, unmasked originals: [M3-androidtab-before-raw.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b9c3fa3bceb8a836/M3-androidtab-before-raw.mp4), [M3-androidtab-after-raw.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/da96974006d8ede4/M3-androidtab-after-raw.mp4).

## What else changed

- `Provider turn failed.` becomes `Claude Code process terminated by signal SIGABRT.` / `Claude Code process exited with code 7.`.
- Preview color follows selection on both sides: selected muted foreground; unselected danger foreground. The narrower iPad previews and Android signal preview truncate the longer message with an ellipsis. The open feed changes to the selected thread’s specific sentence.
- Additional differences outside the changed error text: iPad native glass control/composer shadows and edges have low-level differences visible in Diff0, absent at Diff16. Android tablet differences are confined to the two preview sentences and the feed failure sentence.
- Raw status clock/battery/network pixels vary; only the explicitly stated status strip is excluded. No claim that nothing else changed is made.

## Reproduction, drivers, and checks

[native-drivers-and-seeds.zip](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f1cef19f1de3dd23/native-drivers-and-seeds.zip)

[reproduce-round2-native.md](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/fc09bc3cda158e06/reproduce-round2-native.md)

Core scripts: [seed.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f1d2807703fa900d/seed.mjs), [rpc.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b446c9101836e3d6/rpc.mjs), [pair-native.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e1744a7ab6bf28b3/pair-native.mjs), [capture-native.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/16fb6df751bb938f/capture-native.py), [claude-exit-stub.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/0588a101aba1faea/claude-exit-stub.mjs), [frozen-clock.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bbb87d170f5688c6/frozen-clock.mjs), [install-native-clock.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ca8d2f1b2829c2b5/install-native-clock.py), [clean-native-list-v2.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/91c229fbd7ce4731/clean-native-list-v2.mjs), [start-servers-reviewed.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/abce3c80437a49e5/start-servers-reviewed.py), [build-delivery.py](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ad77de880f459f3d/build-delivery.py).

Actual app projection / environment telemetry: [fixture-transcript.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bfa2450ccbe5085b/fixture-transcript.json), [native-environments.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ba1ca8c293cdacd9/native-environments.json).

The transcript records one failed run and one error item per fixture, the retained partial answer, unsettled metadata, exact failure message/code, and absence of the nonsecret stderr sentinel in the failure. This supplements the captures; it does not replace them.

Settle partners, individual check results, and sanitized command logs:

- ![M3-iospad-selected-before-settle.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/8bae067f2dbcb1d4/M3-iospad-selected-before-settle.png) [M3-iospad-selected-before-settled.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/917bfa19c677df52/M3-iospad-selected-before-settled.json)
- ![M3-iospad-selected-after-settle.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e2b414d5b6791025/M3-iospad-selected-after-settle.png) [M3-iospad-selected-after-settled.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/c1407923b0050dc2/M3-iospad-selected-after-settled.json)
- ![M3-iospad-unselected-before-settle.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/4ace6550245bd31d/M3-iospad-unselected-before-settle.png) [M3-iospad-unselected-before-settled.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/33379d982cbb58af/M3-iospad-unselected-before-settled.json)
- ![M3-iospad-unselected-after-settle.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/183168df8df0fcc2/M3-iospad-unselected-after-settle.png) [M3-iospad-unselected-after-settled.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/09b643420e59f65a/M3-iospad-unselected-after-settled.json)
- ![M3-androidtab-selected-before-settle.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b67f6b48e204c5e9/M3-androidtab-selected-before-settle.png) [M3-androidtab-selected-before-settled.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/05921f219a75ca6a/M3-androidtab-selected-before-settled.json)
- ![M3-androidtab-selected-after-settle.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/14d7a1588c394cc4/M3-androidtab-selected-after-settle.png) [M3-androidtab-selected-after-settled.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/daaef0233a875e50/M3-androidtab-selected-after-settled.json)
- ![M3-androidtab-unselected-before-settle.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5a569470334320d3/M3-androidtab-unselected-before-settle.png) [M3-androidtab-unselected-before-settled.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3eeb28d2c2ad771f/M3-androidtab-unselected-before-settled.json)
- ![M3-androidtab-unselected-after-settle.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/549d180afbd8d27b/M3-androidtab-unselected-after-settle.png) [M3-androidtab-unselected-after-settled.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/58a48fc7e277cdd3/M3-androidtab-unselected-after-settled.json)
- [M3-iospad-before-steps.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/42420acc095ad19c/M3-iospad-before-steps.json)
- [M3-iospad-after-steps.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2f000593c68fa160/M3-iospad-after-steps.json)
- [M3-androidtab-before-steps.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/28c9d11787ab9386/M3-androidtab-before-steps.json)
- [M3-androidtab-after-steps.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/97e59a37cf47adce/M3-androidtab-after-steps.json)

**Unverified assigned variants:** none. This sheet covers M3 only; it makes no claim about the other capturer’s web/desktop or delegated-child rows.
