# Proof audit pass 1: initial Android draft header

PR [#22742](https://git.cafe/pingdotgg/t3code/pulls/22742). Reviewed head [268b1b0](https://git.cafe/pingdotgg/t3code/commit/268b1b075caeec41e6f778e98b65403d2890ed38), requested comparison [ea1c494](https://git.cafe/pingdotgg/t3code/commit/ea1c49419e742c688cc4951d63545046a06ac8c0). The checkout is clean and at that head; cafe metadata agrees. Local main currently has a different merge-base (07d38b8); this audit deliberately uses the supplied comparison pair, whose entire diff is one added option in Stack.tsx:479. No source changes, forge comments, pushes, runtime sessions, or test runs in this before-evidence pass.

## Findings and proof boundary

No confirmed code defect found in the requested one-line change. NewTaskSheetStack previously inherited headerShown:true through SHEET_GLASS_HEADER_OPTIONS/GLASS_HEADER_OPTIONS. NewTaskDraft now supplies headerShown: Platform.OS !== "android" statically. Android uses the standard native-stack export; parent NewTaskSheet already hides its own header. The ready and unresolved-project draft branches previously hid the child native header via mounted NativeStackScreenOptions. Branch preparation renders a separate centered loading view and does not mount those child hide options. Static route configuration covers all three first render paths, independently of data arrival. The existing DETAIL_HEADER_OPTIONS uses the same platform predicate; the user-supplied historical Thread precedent is not independently fetched in this single-PR audit.

Spec: the first Android draft layout must not reserve native-header space. The persistent-offset trigger remains unconfirmed. Source inspection supports the configuration intent, not a claim about measured native layout or a reproduced persistent-offset fix.

**Explicit Android exception:** Android cannot run on this VM (no emulator or EAS Android build). Every Android runtime row below is UNVERIFIED. Pixel captures do not apply. No iOS surrogate, source-text test, callback/wiring assertion, or invented native geometry test is required. Accepted replacement evidence is a final-head scoped mobile test run plus mobile typecheck and targeted lint, with runtime limits stated. This pass defines that evidence; it does not certify it already ran. iOS retains its initial visible-header option; web and desktop do not import this mobile stack.

## Changed path and callers

Only changed declaration: apps/mobile/src/Stack.tsx, NewTaskSheetStack.screens.NewTaskDraft. Render chain: root NewTaskSheet -> GuardedScreenLayout -> NewTaskFlowProvider -> NewTaskSheetStack -> NewTaskDraftRouteScreen -> preparation view OR NewTaskDraftScreen -> Android unresolved shell OR ready SheetHeader/ScreenContent/hero/composer. Error boundary is a parent fallback, not an additional changed component. Neither shared contracts nor providers change.

Caller inventory (all converge on that single declaration): HomeRouteScreen project action and new-on-branch action; usePendingTaskListActions for saved drafts/pending outbox tasks; CommandPalette active-project and project search actions; NewTaskRouteScreen project selection, scratch project creation, and incoming-share reserved destination resume; AddProjectScreen reset paths for existing/new/local/repository destinations, cloning and optional prompt-seeded draft; usePromptLinkResolver push with a populated draftId. Indirect entry: Home New Task buttons, keyboard command, palette New Task, incoming-share presentation in RootStackLayout -> NewTask picker -> draft. Linking is parent `new`, child `draft` (`/new/draft`); parameters can arrive through linking/restored navigation as well. Picker return to an existing draft updates flow and goes back rather than creating a separate render implementation.

Route data shape: optional environmentId/projectId/title/cloning/pendingTaskId/draftId/incomingShareId accept strings or string arrays (first element normalized); optional branch/worktreePath are nullable strings; cloning is normalized from "1". Child props are initialProjectRef {environmentId?,projectId?,branch?,worktreePath?,cloning?}, pendingTaskId?, draftId?, incomingShareId?. No prop or data shape changes. Branch preparation is required only for branch && !pendingTaskId && !draftId.

## Collapsed fixture matrix

A = affected Android route geometry. C = unchanged control. All fixture routes below are real app actions on isolated development data, not executed captures. No labelled harness is needed or proposed. Rows collapse equivalent callers and content variants to avoid multiplying this single route option into an unrelated composer audit.

| ID / named fixture | Affected path and data/layout shape | Real-app seed / route / interaction | Conditions and collapse rationale | Minimum capture / runtime status |
| --- | --- | --- | --- | --- |
| A1 Ready project draft | A: route -> ready draft; SheetHeader, flex ScreenContent, centered scroll hero, bottom KeyboardStickyView composer | Connect isolated environment with one existing project and model; Home project New thread, or picker select project, or palette project action -> NewTaskDraft with environmentId/projectId/title | Empty prompt, zero attachments, keyboard closed. Initial mount and settled state are the central geometry case. Push, navigate, reset and linked/restored route share the same static options; no separate implementation | Android runtime UNVERIFIED. Pixel capture waived; conceptual primary fixture only |
| A2 Unresolved project shell | A: route -> draft with selectedProject absent; AndroidScreenHeader and otherwise empty flex body | Open a saved draft/deep link while its project catalog is still loading, or with project unavailable | Zero projects versus catalog pending/connection error leads to unresolved body; header hidden statically before child options mount. No separate loading-count header policy | Android runtime UNVERIFIED. Pixel capture waived |
| A3 Branch preparation and completion | A: route preparation view centered “Switching branch...” -> ready draft | Home thread New thread on branch using existing environmentId/projectId/branch/worktreePath; let real checkout complete | waitingForProject, pending checkout count >0, and success. Loading view has no custom toolbar/child hide option; static false still removes native reservation. Guard prevents removal while checkout is pending | Android runtime UNVERIFIED. Pixel capture waived; no claimed ability to cancel during checkout |
| A4 Branch failure / exit | A: same preparation path -> failure alert and goBack; interrupted failure exits without alert | Isolated project with a branch checkout failure, reached through same branch action | No persistent failure page; alert/exit rather than a separate draft body. Collapsed failure and interruption at route boundary | Android runtime UNVERIFIED. Pixel capture waived |
| A5 Restored / shared / populated draft | A: ready layout with draftId OR pendingTaskId; incomingShareId and attachments optional | Save populated draft and reopen pending list; reopen queued task; share content -> picker -> draft; prompt link populates draftId | Prompt empty/nonempty, 0/1/many attachments, importing/uploading, queued edit lock and submitting alter dock content or enablement, not route header. Pending/draft IDs skip branch preparation. Share readiness may delay content | Android runtime UNVERIFIED. Pixel capture waived; collapse onto A1 geometry with populated-content stress |
| A6 Scratch / clone / unavailable controls | A: ready layout with scratch hero OR project hero, clone banner, permission/model messages | Picker start without project; Add Project clone/reset -> draft with cloning:"1"; use isolated disconnected or read-only environment/model unavailable | Scratch hero differs from project hero. Clone pending/running/failed/done, retry/remove, offline queueing, branch-loading label, worktree controls, model unavailable and permission message change content height only. Environment count <=1 versus >1 changes static control/chevron. All inherit static hidden header | Android runtime UNVERIFIED. Pixel capture waived; these content variants need no independent header proof |
| A7 Keyboard and navigation return | A: ready layout with keyboard offset and nested picker return | Focus prompt then dismiss; open project/environment/branch/settings/file/attachment routes and return; cancel draft or submit into Thread/outbox exit | Keyboard open/closed changes dock position; picker child headers are independent routes. Return must retain hidden draft option; repeat open/close should not reserve native-header space. Existing route guard and submit behavior unchanged | Android runtime UNVERIFIED. Pixel capture waived; conceptual interaction check only |
| A8 Theme / width stress | A: same route in light/dark, narrow/landscape/wide workspace, long project/environment titles and safe-area changes | Reuse A1/A5 with long labels, switch appearance/orientation/window size in a real Android client when available | Option has no theme/width/count dependency. Hero has max-width project label and environment-control widths; flex and absolute bottom dock are existing. No separate route branch or requested full cross-product | Android runtime UNVERIFIED. Pixel capture waived; fold stress into existing fixtures |
| C1 iOS native sheet | C: platform-specific iOS navigator; same route still headerShown:true | Optional future iOS picker -> draft and return | Existing sheet/transparent content/simple_push and ready SheetHeader path remain unchanged. No iOS capture can establish Android geometry | iOS runtime UNVERIFIED; no substitute evidence or minimum capture |
| C2 Web / desktop and other mobile routes | C: web/desktop use separate clients; sibling NewTask picker/environment/branch/files/settings and Thread route declarations untouched | Source boundary inspection only | No shared wire/schema/provider or desktop IPC changes; local/remote/relay/tunnel differ in data readiness but not Platform.OS route option. Existing Thread detail predicate is only a source precedent | Unaffected by diff; no runtime capture required |

## Minimum evidence set after pass 1

Minimum required pixel capture set: **empty**, by the explicit Android exception. A1-A8 are explicitly unverified runtime rows, not missing required captures. If native verification is done later on a supported machine, prioritize A1 first-mount/settled geometry and A3 loading-to-ready, then A7 return/keyboard; that is optional follow-up, not a condition of this pass.

Required accepted evidence for the implementation handoff: record exact final head and clean diff; run scoped existing mobile behavioral suites covering new-task selection/context/branch preparation and draft persistence/navigation as relevant, mobile typecheck, and lint scoped to Stack.tsx (plus any required mobile static check, reported distinctly). Report commands, exit codes, failures and test counts at that head. Baseline PR description's 74 tests is baseline evidence only, not a final-head pass. No new source-text/wiring surrogate tests requested. Tests/typecheck/lint do not prove native first-frame geometry.

Pass-1 sufficiency is completeness of this code-derived matrix and correct use of the exception; it is not native proof, CI completion, or a merge recommendation. No pass-1 source findings require extra fixture rows. Completed within the 60-minute budget; all changed render paths, callers, normalized prop shapes, loading/error/count/theme/width/platform/interaction dimensions covered.

FRICTION: tool: none; brief: explicit Android exception resolves capture requirements; runbook: none; infra: Android runtime unavailable as stipulated, all runtime rows unverified; forge: local main merge-base differs from supplied historical comparison, so scope pinned explicitly; policy: no comments or source writes; model: none; other: final-head checks are subsequent evidence, not performed in this before-evidence pass.

VERDICT: SUFFICIENT
