# Proof audit, pass 1

Findings first:

1. **Current proof is insufficient.** This is a gesture-routing change: stills cannot prove scrolling, sheet detents, refresh completion, hidden-pane touch exclusion, or selection/navigation. No new runtime capture was made in this audit. No confirmed implementation defect is asserted from source inspection.
2. **The affected scope is larger than the reported Files sheet.** Android `InspectorPanes` is used in both sheets and side columns; its Files, Git and route-supplied Files panes need regression coverage. `FileTreeBrowser` also appears directly in full-page root and directory browsers, including unsent drafts. iOS receives the sibling reorder and explicit list prop too.
3. **An iPhone alone does not cover the iOS column path.** The minimum complete production-path set is Pixel 9 portrait, Pixel Tablet in a sufficiently wide/tall window, iPhone 17 Pro portrait, and an iPad with native inspector columns. A Pixel 9 Pro Fold can replace the Android tablet only if its measured logical window, after the navigation rail, meets the inspector threshold. No extra foldable is required when the tablet covers that branch. The proposed phone/tablet/iPhone set leaves I02 missing without an iPad. A labelled native harness is useful but cannot certify UIKit column geometry.
4. **Existing Samsung videos retain limited value.** They cover historical H01 (dark Android phone, overflowing collapsed root folders, sheet at approximately 60% and expanded, list movement versus sheet movement, header expansion). They do not cover refresh completion, nested selection, Git scrolling, direct callers, empty/error/loading/search, light appearance, tablets or iOS. Their older SHA alone does not invalidate that historical observation when the patch is identical; it also does not prove the current merged main's header/inset/native integration. Keep them as provenance and capture F01 at the audited head. Sampled video frames support the observed row movement; exact gesture coordinates and build identity come from the PR's reported procedure, not embedded telemetry.
5. **Pin the revision.** Reviewed local `pr-33223` HEAD is the unpublished merge `00b5c8c1cf295cfe46a8e96bb16b09d118ac62ab`, against [4c361199f4](https://git.cafe/pingdotgg/t3code/commit/4c361199f47f6ea32a2c14835df392640d0f7c63), incorporating source [3cf0e37d4c](https://github.com/RadekManak/t3code/commit/3cf0e37d4ca76763ebcc5af4f6c0d199750f7e22). The three changed files are identical between that source commit and the local merge. The old filmed revision is not present as a local git object, so full old surrounding-code equality was not independently established. Forge view and status returned different head OIDs during the read; this report is intentionally pinned to the requested local merge, not a merge-readiness judgment about a later remote revision.

Scope: [#33223](https://git.cafe/pingdotgg/t3code/pull/33223), mirrored as [#33223](https://github.com/pingdotgg/t3code/pull/33223), fixes [#33224](https://git.cafe/pingdotgg/t3code/issues/33224). Worktree was read only. No server, Metro, device session, agent turn, tests, edits, pushes, comments or review submission were started.

## Render-path inventory

Source links below name the source revision whose changed files match the audited local merge.

### Android inspector host

[inspector-host.android.tsx](https://github.com/RadekManak/t3code/blob/3cf0e37d4ca76763ebcc5af4f6c0d199750f7e22/apps/mobile/src/features/layout/inspector-host.android.tsx#L34) has two direct production callers: `WorkspaceInspectorSheet` and `WorkspaceInspectorPane`. The former uses a native FormSheet with 0.6/0.95 detents, Android rounded corners, 12-unit top padding and a separate non-interactive grabber; the latter clips an animated, resizable side column. iOS resolves a different host file (Stack screens in a sheet; Split.Inspector in native columns), so the z-index edit is Android-only.

Inputs: `content` absent/present; `panes` empty/one/multiple; `active` matching a pane or not; each pane key/render/prewarm; `resetKeys` unchanged/changed; `onClose`. No theme or count-specific host layout is introduced. With absent content, no mounted panes render. An unmatched active key leaves only hidden panes, an invalid state normal callers do not supply.

[useMountedInspectorPanes](https://github.com/RadekManak/t3code/blob/3cf0e37d4ca76763ebcc5af4f6c0d199750f7e22/apps/mobile/src/features/layout/inspector-panes.ts#L24) initially mounts the active pane, then mounts all prewarm panes after 350 ms **only when the active pane itself is in the prewarm set**. Previously opened panes remain mounted in that host. Thus cold single-pane and warm overlapping-pane states are distinct. The active wrapper is opaque, interactive, focusable and accessible at zIndex 0; all hidden wrappers are opacity 0, pointerEvents none, accessibility-excluded, and now zIndex 1. Capture gestures after prewarm; a still showing only the active content proves nothing about native touch routing. A render exception uses the inspector error boundary; Retry or a reset-key change can recover it. See X02 for why this does not add a mandatory crash fixture.

All registrations were traced:

- `ThreadRouteScreen`: active `files` -> `ThreadFileNavigatorPane`; active `git` -> `GitOverviewSheet(presentation="inspector")`; both are prewarm panes. Active `route` -> the Files navigator supplied by wide `ThreadFilesTreeScreen`, with `files` and `git` also in its pane array. Active route alone does **not** start the 350 ms prewarm timer. Active `preview` -> thread/device preview, only conditionally included in the pane array.
- `ThreadFileScreen`: one `files` inspector pane, no prewarm flag, backed by `ThreadFileNavigatorPane` at either the workspace root or the currently viewed directory.
- `preview` has thread and device targets; normal `useOpenThreadInspector` is gated to **iOS plus fileInspector.supported**. Android cannot reach it through the ordinary Agents/linked-thread/device actions. Injecting `route.params.inspector` is a harness state, not a normal Android UI path. It needs no mandatory Android regression row (X01).
- Terminal, Browser, Review, Commit, Branches and Worktrees are separate navigation routes, not extra InspectorPanes. Git overview launches Review, Commit and Branches & worktrees after dismissing a compact inspector sheet. Check those transitions in P02; do not invent separate z-index pane rows for their untouched lists. Settings and command palette register no other changed inspector pane. The wide hardware Files command routes to ThreadFiles and is covered by C05.

### Thread file navigator

[thread-file-navigator-pane.tsx](https://github.com/RadekManak/t3code/blob/3cf0e37d4ca76763ebcc5af4f6c0d199750f7e22/apps/mobile/src/features/files/thread-file-navigator-pane.tsx#L16) has three call sites:

1. `ThreadRouteScreen.renderFilesInspector`: thread cwd, project title or fallback Files, selectedPath null; selection closes a compact sheet first, then opens ThreadFile, or navigates directly in a side column.
2. `ThreadFilesTreeScreen.renderInspector`: only a saved thread with a supported file inspector uses this route pane; selectedPath null. Threadless drafts always retain the direct full-page tree even on tablets. Selecting a file replaces the wide tree route with ThreadFile.
3. `ThreadFileScreen.renderInspector`: only with supported file inspector and valid environment/cwd; root cwd + project title + relative selected file for a file, or directory cwd + full directory path title + null selection for a directory. A directory page can therefore display **two trees**, one in the main page and another in the inspector.

Props: `cwd` and `environmentId` select the listing and key/remount FileTreeBrowser; `projectName` changes the subtitle (include a long name/path); `selectedPath` uses the explicit prop when non-null and otherwise the hook's selection; `onSelectFile` changes the route behavior above. A local search string controls the bar/list. Theme affects colors and file preloading, with no separate structural branch.

Filesystem access: catalog/session connecting or unavailable session can show pending with no error; session error, offline after catalog readiness, or a session lacking filesystem-read permission shows an error; allowed sessions query cwd. Errors/pending are passed into the same browser, not rendered as a different pane. The caller supplies Search and Refresh; Android has an inline bar, search icon -> search field/keyboard -> clear/close/hardware Back; Refresh is in its overflow menu. iOS registers native chrome and native search/toolbars, but its AppBar intentionally does not consume the refresh prop: pull-to-refresh is the available refresh gesture, with no Files header Refresh button to capture. The changed JSX puts ScreenContent before AppBar on both platforms; Android flex-col-reverse retains the visible bar-above-tree arrangement. `ScreenContent insetHorizontal` gives Android the rounded card with horizontal margin 4; on iOS it passes through the list. Close inspector uses the host context.

### File tree browser

[FileTreeBrowser.tsx](https://github.com/RadekManak/t3code/blob/3cf0e37d4ca76763ebcc5af4f6c0d199750f7e22/apps/mobile/src/features/files/FileTreeBrowser.tsx#L99) has exactly three production JSX sites: the navigator above; the direct tree in `ThreadFilesTreeScreen`; and the direct directory tree in `ThreadFileScreen`. The import/render in `useFileTreeEntries.test.tsx` is a test harness, not another product surface. No web or desktop client imports this mobile component.

Direct root caller: saved-thread ThreadFiles is full-page when fileInspector is unsupported, while supported saved-thread ThreadFiles uses the route inspector above. NewTaskFiles always uses the direct tree. Both direct root cases support press-in preload and file selection; a saved thread navigates ThreadFile, a draft navigates NewTaskFile. The header has Back, Search and Refresh. The direct directory caller is reached by file metadata kind=directory at ThreadFile/NewTaskFile, queries that directory as cwd, has no onPreviewFile callback, and pushes the corresponding file route on selection. iOS direct pages also draw FilesToolbarBottomFade; Android does not.

Input and render branches (collapsed into the fixtures below):

- `entries`: zero/nonzero and visible list underflow/overflow, independent of raw count. Each ProjectEntry has path and kind file/directory, optional ignored. Tree creation synthesizes ancestors from slash-separated paths, sorts directories before files with numeric/case-insensitive names, ignores empty path segments; nested depth adds 18 per level. Directory and file icons differ. Long names are one-line/truncated, not a new wrap layout.
- `expandedPaths`/`setExpandedPaths`: directory closed/right-chevron versus expanded/down-chevron; files have a spacer. `loadingDirectories` gives a spinner only on an expanded loading directory; empty expanded directories have no child rows. `onLoadDirectory` is called on expansion (retry allowed) and for expanded descendants. Include changing data while scrolling because the list recycles items and maintains visible position.
- `selectedPath`/`revealSelection`: null, selected leaf, and selected nested leaf whose ancestors are revealed. A selected file gets highlighted background/bold foreground; ignored unselected text is tertiary; ordinary unselected text is secondary. Selection wins over ignored styling. `onPreviewFile` is optional and runs at file press-in; `onSelectFile` runs at press. Optimistic selection is shown until the controlled selection changes or a 1,000 ms rollback timer clears it. X03 covers the artificial stalled-parent branch.
- `searchResultPaths`: null means ordinary expansion, empty set means no matches, nonempty set filters to matches plus ancestors and traverses descendants even when not manually expanded. `searchQuery.trim()` empty/nonempty chooses Workspace empty versus Try a different search text. The hook trims/slices query to 256 and debounces 200 ms. Do not infer a spinner merely from typing when old visible rows remain.
- `searchTruncated`: adds a list-header notice, independently of error. Search limit is 200. Root-list truncation has no dedicated visual notice and is not a separate layout row. A notice and error can coexist; their additive combination is covered by the constituent F06/F10 states, not a separate Cartesian fixture.
- `error && entries.length > 0`: alert above the list, even if search leaves zero visible nodes. With zero visible nodes: error plus raw entries.length=0 renders Files unavailable, alert and Try again; otherwise pending renders a spinner; otherwise No files found renders Workspace empty or Try a different search. Thus an error header can coexist with an empty-search message or an empty pending spinner when raw cached entries exist. Error takes precedence over pending in the zero-raw-entry failure view; `isPending` disables Try again. Record recovery, not just the error still.
- `isPending` is not a blocking full-list spinner while visible data exists. `isRefreshing` drives RefreshControl; refresh can start from pull-down, Android AppBar overflow, or Try again. Pull-refresh and sheet-collapse gestures compete at the top edge and need explicit motion proof.
- Geometry comes from NativeScrollView, flex:1, native iOS top/bottom content insets, padding 8, estimated row size 42/minimum height 42, automatic indicator insets, never automatic content-inset adjustment, keyboard dismiss on drag and handled taps. `nestedScrollEnabled=false` is shared by all callers; its native gesture effect is primarily Android. iOS always-bounce and native header/toolbar insets still need a regression capture.

Caller guards before a browser renders: missing environment or unresolved saved thread -> Opening files/file; pending read access -> Checking file access; denied access/missing cwd -> FilesUnavailable; invalid file path -> File unavailable; metadata pending -> Opening file; metadata file -> content preview/source, not a direct directory tree. The wide file route can still register its inspector around these guards. The preview formats do not change this tree or host layout: a plain text file is a sufficient neighbor. See X04 for guard coverage boundaries.

## Seed recipes and device constraints

These are capture instructions, not steps performed by this read-only audit. Use an isolated fresh backend (`T3CODE_DEV_SEED=0 vp run dev`) and the checkout's dev client (`vp run mobile:install`) through the pooled device workflow. Never point it at live userdata. Put synthetic data and any harness/driver files under the task scratch root. Use the real app's Add project -> local folder workflow, or authenticated typed RPC `projects.mutate` with a `project.create` mutation (unique commandId/projectId, title, workspaceRoot), followed by a stopped saved thread through `orchestration.dispatchCommand` with `thread.create` and the contract's required settings. Do not start a paid turn merely to make a thread. The draft flow needs no saved thread.

Seed S-long: disposable git repo with a committed README, 40 folders `scroll-fixture-01` through `scroll-fixture-40`, each containing at least one tracked file; make folder 20 contain deeper children and one long filename, folder 21 empty, and add an ignored folder/file via .gitignore. Add 240+ tracked files named `proofmatch-NNN.txt` distributed across the folders for truncation searches. Leave several tracked files dirty for Git UI. Use a long project title and directory path. Add a second small project to check target changes without touching the original repository. S-short: a separate folder with one file and one empty folder; S-empty: a genuinely empty directory (no seed README/.gitignore showing as files).

Routes are React Navigation paths under the dev scheme `t3code-dev://`: `threads/<environmentId>/<threadId>`; append `/files` for ThreadFiles or `/files/<relative-path>` for ThreadFile (a directory path must yield metadata kind=directory). Draft: `new/draft/files?environmentId=<id>&cwd=<encoded-absolute-root>&projectName=<encoded-name>`; append a path for NewTaskFile. Prefer app taps when available; deep links are real route entry, not harness captures. Draft folder icon in the new-thread header opens NewTaskFiles; saved-thread folder icon opens the inspector, so use the route deep link to reach the compact saved-thread full-page tree. No direct SQLite writes are necessary.

For F09/F10, use only the synthetic workspace: after registering it, move its directory aside and replace that exact path with a regular file to induce a non-missing-root error; restore it for recovery. A simply missing workspace has special cache-clearing behavior and is not an interchangeable stale-error fixture. Alternatively fail a newly expanded synthetic directory listing after loading root. If retained-data errors cannot be made stable with the real query layer, label a native component harness instead of claiming a real-app capture.

There is no persistent seed or normal setting that forces an indefinitely pending list, per-directory spinner or a stalled parent callback. Cold loading may expose them briefly; deterministic captures require a labelled native harness using the actual component and native list, controlled pending/loading props, the same pane/inset contexts and a deferred resolution. Do not claim the harness proves the real sheet's gesture integration. Permission-denied/offline can also be real app states through a disposable restricted connection; do not change the main connection's grants.

Logical size, not screenshot pixels, decides layout. Generic Android split view requires height >=600 and width >=600; expanded begins at 720. File inspector additionally needs effective width >=820 (after the persistent navigation rail, where present); it is constrained to 260..480 and reserves approximately 560 for main content, potentially hiding the primary sidebar. Use Pixel Tablet landscape with actual logical measurements recorded, resize its inspector from narrow to wide. A landscape phone whose height falls below 600 does not cover the column path. Use an iPad with native columns for I02; a stretched iPhone harness cannot substitute. No web 390/1440 matrix applies.

Choose explicit Light/Dark in Settings -> Appearance. No changed branch depends on a specific named palette, provider, git forge, local versus relay connection, or server contract. Cover both appearances on the primary Android and iPhone paths; do not multiply every state by every palette/provider/transport. Defaults for font/control scale are sufficient; include long names/path clipping in F03/C04. No typography scale change is in this patch.

## Fixture matrix

Status PENDING means no new capture exists. Every interaction/time row is **recording**; stills alone are insufficient. Required rows constitute the minimum set, with the cells listed in the device/theme column. Several rows can share one continuous video, but retain timestamps and row labels. Obtain matched origin/main and audited-head recordings for F01; capture P01/P02 on both revisions if a gesture difference is seen or attribution is uncertain. Other regression rows require the audited head and a baseline whenever a discrepancy needs attribution.

Abbreviations: A = Pixel 9 portrait; T = Pixel Tablet landscape meeting the threshold; I = iPhone 17 Pro portrait; IP = iPad with native columns. D/L = explicit dark/light. Diff reach: Z = Android pane z-index, O = navigator child order/flex direction, N = shared nested-scroll setting.

| ID / named fixture | Required data and visually distinct state | Diff reach / purpose | Minimum device × theme / evidence | Reach / seed / action and acceptance | Status |
|---|---|---|---|---|---|
| F01 Overflow root / both detents | S-long, 40 collapsed folders, first and far-later rows identifiable | Z+O+N; core fix | A × D; **recording**, matched before/after | Saved thread -> folder. At ~60%, swipe inside tree repeatedly up and down to final rows and back; header stays above card and sheet stays at its detent. Drag header to ~95%, repeat, then drag header down and dismiss via close/Back. Include first/last reachable rows and edge swipes. | PENDING; H01 historical support only |
| F02 Underflow root | S-short, fewer rows than available height | Z+O+N; no phantom overflow, alternate appearance | A × L; **recording** | Open Files; swipe body/top/bottom, drag header both directions, close. Short content, search/overflow/close stay reachable; header dragging still works. Do not demand scrolling where content fits. | PENDING |
| F03 Hierarchy / selection | S-long; collapsed/expanded/empty directory, depth >=3, long name, ignored ordinary and selected leaf, selected-path reveal | Z+O+N; dynamic row height/data and hit targets | A × D; **recording** | Expand/collapse while scrolled, show child spinner if observable (otherwise F08 harness), tap file after press-in, verify correct file opens after sheet dismissal, return and reopen. Select ignored leaf and nested leaf; reveal ancestors in wide C04. Do not require state persistence across a newly created sheet session. | PENDING |
| F04 Search results / keyboard | Nonempty searchResultPaths, nested matches with ancestors, both fitting and overflowing result phases | Z+O+N; search bar/body order | A × D; **recording** | Search files, type partial query, await debounce/results, drag list with keyboard visible, tap result, return; clear and close search (including hardware Back). Header remains at top; keyboard does not hide all content or steal taps. | PENDING |
| F05 Search no matches | Nonempty query, zero visible rows; root entries may remain cached | Z+O+N; distinct empty-search branch | A × D; **recording** | Search impossible token -> No files found / Try a different search, clear -> original list. Include query transition; a still cannot prove recovery. | PENDING |
| F06 Truncated search | >200 indexed proofmatch files, searchTruncated=true, many visible results | Z+O+N; header notice consumes list height | A × D; **recording** | Search proofmatch, show refinement notice and overflow scroll; refine to a small result set and confirm notice disappears. Do not assume 40 folders alone triggers this branch. | PENDING |
| F07 Empty workspace | S-empty; entries=[], pending=false, error=null, query blank | Z+O+N; empty-list sizing | A × L; still permitted | Register empty project, create/select stopped thread, open Files. Show header, rounded card and No files found / The workspace is empty. | PENDING |
| F08 Loading / directory loading | Empty visible list pending; also loaded root with expanded directory in loadingDirectories; completion supplies children | O+N plus host geometry; time-dependent spinners | A × D; **recording**, labelled HARNESS if controlled | A natural cold app load is valid if observable through completion. Otherwise actual native component harness, first entries=[]/isPending=true then populated; separately root entries plus expanded/loading directory, resolve it. These cannot be durably seeded via ordinary server records. | PENDING; deterministic harness needed if app transition is too short |
| F09 Empty fatal error / retry | entries=[], error text, pending=false then pending=true (retry disabled), then success | Z+O+N; empty-error action layout | A × D; **recording** | Register a synthetic project, induce non-directory root error before first Files open. Tap Try again; record disabled pending state where observable; restore root/retry to success. Restricted/offline session gives alternate error cause but same layout. Use labelled harness for deterministic pending/retry if necessary. | PENDING |
| F10 Retained-data error | entries nonempty plus error header; additionally no-match filtering leaves visibleNodes empty with cached raw entries | Z+O+N; alert/list/empty layout distinction | A × D; **recording** | Load root first, induce listing/child error, refresh; show alert with retained scrollable rows. Search no matches while error remains -> alert plus empty-search (or pending) content. Restore/retry -> error gone, rows usable. If real query retains no data, capture exact props in labelled harness. | PENDING |
| F11 Refresh completion | Loaded S-long; isRefreshing true -> false; root content changes | Z+O+N; pull gesture at top and bar action | A × D; **recording** | At list top pull to refresh; show spinner stop and a newly added synthetic file. Repeat via Files overflow -> Refresh files. Check no stuck spinner; header drag still changes sheet detent after refresh. At final row reverse-scroll to top before pulling. | PENDING |
| P01 Cold/warm Files and Git | Single active pane immediately; Files/Git prewarmed hidden sibling after 350 ms | Z; invisible siblings must not intercept gestures | A × D; **recording** | Open Files cold, then settled/warm, scroll/tap/close; from thread Git controls -> More open Git, let prewarm settle, interact and close. Reopen once. Phone sheets recreate their host per opening; same-host mode switching is covered by C05 on tablet. | PENDING |
| P02 Git overview and exit routes | Real git S-long, dirty files, long worktree path; enough overview content to overflow at 60% | Z only; other reachable inspector renderer uses nestedScrollEnabled=true | A × D; **recording** | Git controls -> More. Scroll both directions at both detents, pull/header refresh to completion, close. Open Branches & worktrees then return, open Commit then return, and Review changes then return; prove sheet dismissal/route interaction. No commits or pushes needed. If overview fits, add a synthetic long worktree path or other real supported content; do not claim overflow from a still. | PENDING |
| C01 Direct saved-thread root tree | S-long root, has threadId; unsupported inspector | N only; production caller outside sheet | A × D and I × D; **recording** | Deep link ThreadFiles (`threads/e/t/files`) on compact phone, scroll to bottom/back, search, pull-to-refresh (plus header overflow refresh on Android), open file then Back. On iOS show toolbar fade and safe first/last rows. This is not the folder-button sheet path. | PENDING |
| C02 Direct draft root tree | NewTaskFiles, no threadId, S-long and short results | N only; direct caller stays direct even when wide | A × L and T × D; **recording** | New draft for S-long -> folder. Scroll/search, open file -> NewTaskFile, Back. Confirm draft never becomes a missing saved-thread route. On tablet confirm full-page main tree rather than route inspector. | PENDING |
| C03 Direct directory tree / no preload | ThreadFile and NewTaskFile metadata kind=directory, directory has >40 children | N only; distinct direct caller lacks onPreviewFile | A × D and I × D; **recording** | Deep link both saved and draft file routes to a synthetic directory; scroll, expand, refresh, choose child (push), Back. Check directory-relative selection is correct; one sequence may cover both navigation identities. | PENDING |
| C04 Wide file inspector / dual trees | S-long; selected nested file, then a directory route; long path subtitle; one files pane | Z+O+N; ThreadFileScreen caller | T × D; **recording** | Wide ThreadFile for nested leaf -> inspector reveals selected ancestors. Toggle Hide/Show file navigator, scroll/select another file; open directory route, show main direct tree plus independent inspector tree, interact with both. Resize side pane narrow/wide and verify header/card order, clipping and touches. Change to small project's file target and verify cwd/key reset. | PENDING |
| C05 Wide route pane / retained modes | ThreadFiles route inspector active=route; files/git panes also defined, initially not prewarmed | Z+O+N; third navigator caller and same-host mode switching | T × D; **recording** | Open ThreadFiles via route (or hardware Files command), scroll; Git controls -> More switches to git and prewarms files/git; folder returns to route. Repeat in ordinary Thread route for files<->git. Check active pane receives input and scroll state survives while host remains mounted. Select file/Back and hide/show inspector. Sidebar may step aside as width is reduced. | PENDING |
| I01 iOS compact native bar | S-long plus S-short, sheet at 0.6/0.95, native search/header insets | O+N only; iOS host itself unchanged | I × L; **recording** | Saved thread folder opens Files. Verify native bar above content, first/last row not occluded, both-direction scrolling, expand/collapse/close, search/clear, directory expansion and file navigation, pull-to-refresh completion. Repeat short content phase. There is no iOS Files header Refresh control. C01/C03 supply dark appearance on direct callers. | PENDING |
| I02 iOS native inspector column | Native iPad split columns, root route inspector then selected file/directory inspector | O+N; different host and measured native insets | IP × D; **recording** | On a native-column iPad open ThreadFiles, search/scroll/refresh, open nested file and directory, toggle inspector and return. Verify native chrome and manual content insets after sibling reorder. iPhone 17 Pro cannot reach this production column path. Android tablet cannot replace UIKit proof. | PENDING; extra iPad device needed |
| H01 Historical physical Android | Samsung A54 Android 16, dark, 40 collapsed folders, lower/upper sheet detents | Historical Z+O+N core flow only | Physical Samsung × D; existing **recordings** | [Before](https://github.com/user-attachments/assets/40ae5983-304d-4f0a-a512-8054d5a66be3), [after](https://github.com/user-attachments/assets/34f2d998-9fa1-44ba-ba7c-cc4b4b7656bf). Root rows remain fixed while baseline sheet moves; after shows rows ~01 -> 07 -> 13 -> 08 and header expansion. Keep revision/device provenance; no credit for unrecorded states or current-head integration. | HISTORICAL ONLY; not a fresh F01 pass |

The 20 required named rows comprise 23 device/theme cells: F01..F11 (11), P01..P02 (2), C01 (2), C02 (2), C03 (2), C04..C05 (2), I01 (1), I02 (1) = **23 cells**. Only F07 may be a still; all other cells require recordings. Multiple states within a named row are phases of one fixture, not optional assertions. Use the same synthetic data across devices and record device/OS/logical size/theme, git revision, live Metro bundle identity, and timestamps for each covered row. Tokens and pairing URLs must stay out of uploads.

## Explicitly excluded or harness-only branches

| ID | Branch / reachability | Row decision and status |
|---|---|---|
| X01 | Android preview pane, target thread/device, route params injected despite normal iOS-wide-only opener gate | No mandatory Android row: UI-unreachable in the ordinary app. If explicitly forced, label HARNESS and use a recording for open/scroll/maximize/close; it does not replace reachable P01/P02/C05. iOS previews use the unchanged iOS host and do not render FileTreeBrowser, so no extra preview fixture for this diff. |
| X02 | RenderErrorBoundary failure/retry/resetKeys; content absent/empty; invalid unmatched active key | No deterministic real user seed for a thrown React render or invalid host registration. Optional labelled native HARNESS can throw/retry/change reset keys and record a stacked fallback receiving input. No required new crash fixture for an unchanged boundary. Absent/closed host is observed in F01/P01/C04, and one versus many mounted panes in C04/P01/C05. |
| X03 | Optimistic selection times out after 1,000 ms because parent never accepts selection; omitted preview callback | Stalled parent callback is HARNESS-only for these normal navigators, so no separate minimum row. Successful optimistic selection/controlled update and ancestor reveal are F03/C04; omitted preview is the real C03 caller. Any claimed rollback proof needs a recording past the deadline. |
| X04 | Outer missing environment/thread/cwd/path/access and metadata-loading guards; file preview/source formats | Direct tree not mounted in these guard branches, so no independent direct-tree fixture. Inner inspector access pending/denied/error maps to F08/F09/F10. Plain-text file neighbor in F03/C04 is enough: no need for every image/audio/video/markdown format, provider, transport, forge, or palette. |

FRICTION:
forge | `cafe pr view` reported a different head OID from revision-bound `cafe pr status` during the audit; the requested local head was intact | A single coherent revision snapshot for metadata/status would avoid ambiguity; this audit is pinned to the local SHA and does not claim latest-remote readiness.
other | The old filmed revision is absent from local git objects, so surrounding-code equality with the filmed build could not be independently verified read-only | Preserve the filmed build/source manifest with the recordings; the user-supplied identical-patch provenance supports historical H01 only.

VERDICT: INSUFFICIENT F01–F11, P01–P02, C01–C05, I01–I02 need current-head captures; I02 additionally needs an iPad
