## M12 — iPad split columns, remembered PR tab, light

**VERIFIED in the real app** for [#27798](https://git.cafe/pingdotgg/t3code/pull/27798). Real iPad Pro 13-inch (M5) simulator, iPadOS 27.2, 1032×1376 points, DPR2; full 2064×2752 captures, medium text, light, default native motion/transparency. App Date fixed to 2026-11-03T00:00Z; native clock remains real. No emulation, crop, fake summary, or synthetic navigation harness.

Both SHAs run their own fresh databases with T3CODE_DEV_SEED=0. The identical synthetic stopped thread links public TypeScript [#65017](https://github.com/microsoft/TypeScript/pull/65017); its summary comes from the server's actual public read. Both project fixtures use TypeScript [042e0fb957](https://github.com/microsoft/TypeScript/commit/042e0fb9574980bd67964165df295e629f834fe3). No real PR is mutated and no provider turn is run.

Cold sequence: remove the disposable app connection to clear persisted query data, re-pair, open the synthetic thread, open PRs and the [#65017](https://github.com/microsoft/TypeScript/pull/65017) deep link with its first detail replies held, switch to Chats, then return to PRs. The return has a remembered selection and **no existing matching route** (old routes are Home/Thread). Before rebuilds an identity-only route and displays the full detail-column spinner. After rebuilds it with the already-held real summary as `initialSummary`, immediately painting the overview's title, author, status and branches while detail-only fields remain pending. Neither side has received a detail answer before that return. The gate preserves actual payloads and releases after the same configured 10,000ms interval on both sides (measured 10.001s / 10.000s at the controller). This is a visibility test with an artificial reply delay, not a latency benchmark.

Narrated steps, **UTC on 2026-11-03** (native movie PTS compresses some elapsed command intervals, so use these timestamps rather than the clip as a stopwatch):

| Step | Before | After |
| --- | --- | --- |
| Recording begins on the stopped thread | 04:06:20.403 | 04:07:16.715 |
| First cold detail still: spinner on both | 04:06:24.913 | 04:07:20.842 |
| Switch to Chats; PR route removed | 04:06:26.365 | 04:07:22.436 |
| PR tab callback rebuilds remembered detail | 04:06:28.318 | 04:07:24.876 |
| Held still: spinner / seeded overview | 04:06:28.574 | 04:07:25.121 |
| Common ten-second gate releases | 04:06:38.319 | 04:07:34.877 |
| First detail callback delivered | 04:06:38.411 | 04:07:35.276 |

Before recording: [M12-final-before.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/430f7742722a4bc6/M12-final-before.mp4) · After recording: [M12-final-after.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ad03eb265637dec1/M12-final-after.mp4). Before is an unmodified 24.890s copy; after is a stream-copy trim requested with `-t 25` (18.173s export due to native timestamps/edit lists), retaining the initial spinner, Chats return, seeded overview and detail release. Only its long post-release wait tail is omitted. Raw untrimmed sources and the edit manifest are archived. Recording OS minutes differ (8:06 / 8:07); settled stills below share one natural 8:02 minute.

| Before | After | Diff0 | DiffT >8/255 |
| --- | --- | --- | --- |
| [d8a829e5ec](https://git.cafe/pingdotgg/t3code/commit/d8a829e5ecd6626f8fdee23ef20ca9758e056251) | [cffa192a07](https://git.cafe/pingdotgg/t3code/commit/cffa192a07c19b904aea4c22a5f16276159cb56a) | [d8a829e5ec](https://git.cafe/pingdotgg/t3code/commit/d8a829e5ecd6626f8fdee23ef20ca9758e056251) → [cffa192a07](https://git.cafe/pingdotgg/t3code/commit/cffa192a07c19b904aea4c22a5f16276159cb56a) | [d8a829e5ec](https://git.cafe/pingdotgg/t3code/commit/d8a829e5ecd6626f8fdee23ef20ca9758e056251) → [cffa192a07](https://git.cafe/pingdotgg/t3code/commit/cffa192a07c19b904aea4c22a5f16276159cb56a) |
| ![M12 before, settled overview](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/818d574f57503079/M12-before-settled-1.png) | ![M12 after, settled overview](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9ea170d37c28f9c6/M12-after-settled-1.png) | ![M12 Diff0, amplified nonzero channels](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ce6fd6e3434a6917/M12-Diff0.png) | ![M12 DiffT, channel differences above 8/255](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/cc9f6e521409de61/M12-DiffT.png) |

Settled stills reopen the actual fully loaded [#65017](https://github.com/microsoft/TypeScript/pull/65017) destination with the gate released, rather than accepting a skeleton as settled. Each side matches a second full RGB capture at least 700ms later (actual starts: before 04:02:02.093 / 04:02:05.253, after 04:02:32.380 / 04:02:34.545). **32 nonzero native edge pixels, maximum 1/255; zero pixels >8/255.** No content, layout or control difference. [Pixel counts](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9e0a512e224fec38/M12-pixels.json).

![M12 settled comparison sheet, before / after / Diff0 / DiffT](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/7b1ac02a9dcb2fbb/M12-settled-sheet.png)

Held-reply proof stills: [Before spinner](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f004194110321c1c/M12-timed-before-held.png) · [After seeded overview](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5fbeaba38f017077/M12-timed-after-held.png). Route/read traces: [Before](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/1367432394794ed4/M12-before-trace.json) · [After](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a6c6808e0f91c012/M12-after-trace.json) · [Branch and cold-read assertions](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bbb8752f812892be/M12-proof.json).

[Driver and capture patches](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/df5d2378c9b26ee7/M12-driver.tar.gz) · [Raw recordings, repeats and diagnostics](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a596259f86384dc0/M12-raw-captures.tar.gz). The raw archive labels preliminary manual-gate captures as superseded. No product edits were committed or pushed. The lead worktree was not used or changed.

FRICTION:
- runbook | Idle TTL does not guarantee a cold detail because the query also persists on disk. | Clear only the disposable app connection's cached data, then remember the selection through a pending read in one live app session.
- tooling | Hermes CDP closed its socket; some startup AX reads stayed on SplashScreen after the app had become visible. | Use the identical HTTP timing/trace driver and re-open foreground before relying on stale AX state.
- capture | Preliminary manual gates had unequal hold lengths; the final destination-label wait timed out on after. | Superseded manual clips with the common timed gate; retained raw recovery recording and trimmed only its post-release tail. The repeat driver now waits for description content.

M12 VERIFIED; device and owned servers stopped; isolated worktrees and scratch removed after upload.
