# Issue 15974 — read-only proof audit, pass 1

Compared base `3de45c6254` with head `1dd0ed554202da054664a06968f0a038e5cc6717` in `/home/ubuntu/t3code`. HEAD matches requested head. One file changed, 60 additions: `apps/mobile/src/features/threads/NewTaskDraftScreen.tsx` (imports plus lines 422–476). No web code changed. This is a proof plan and source audit, not a runtime pass or merge-readiness verdict.

## Actual behavior and source paths

- `NewTaskDraftScreen.tsx:422`: after persisted composer hydration, once per mounted screen, a plain new-thread flow with a resolved intended project and draft key may open another draft. Current draft content wins. Explicit `draftId`, `pendingTaskId`, `incomingShareId`, truthy initial branch, and cloning bypass auto-resume.
- `state/use-composer-drafts.ts:1888`: candidates are new-task keys stamped with the exact environment AND project. Order is descending `project.createdAt`, NOT last edit time. Equal timestamps have no explicit secondary comparator; do not invent a tie-order requirement.
- `state/pending-new-tasks-model.ts:38`: nonempty means trimmed text OR any attachment. Whitespace/settings alone are empty. Existing thread composers and queued messages are not candidate new-task keys.
- `features/threads/new-task-flow-provider.tsx:700`: `openDraft` selects the existing key/environment/project, requires the stamped project loaded, and does not submit. `setProject` retargets the active draft; verify no unintended content replacement after changing project.
- `features/threads/NewTaskDraftRouteScreen.tsx:35,52,194`: resets flow, normalizes route params, passes all exclusion flags to the screen; branch checkout has its own preparation path.
- `features/layout/AdaptiveWorkspaceLayout.tsx:515,547,850,912,935`: shared new-task handler feeds Android FAB/navigation, workspace controls, hardware command. `features/keyboard/CommandPalette.tsx:271` invokes the same newTask command. `features/threads/new-task-project-selection.ts:106` chooses current thread/draft project, otherwise first project; no projects leads to picker.
- `features/threads/NewTaskRouteScreen.tsx:226–246`: project picker either updates an existing draft route or enters a draft route for the selected project. `features/projects/AddProjectScreen.tsx:1347` supplies cloning exclusion. Explicit pending/draft list navigation remains a separate control, not plain new thread.

## Runtime and fixture boundaries

Target supplied by maintainer: pooled Android Pixel, 1080×2424, pool session `issue-15974`; isolated runtime `http://fs-17.tail131df4.ts.net:13773`, Metro 8081. These are supplied context, not connectivity/build verification. Do not use live userdata or seed the server DB expecting device-local composer drafts to appear. Fixtures must exist in this app installation's composer persistence and have known project stamps/timestamps. Use synthetic text/attachments and normal supported UI where possible. If multiple drafts, alternate environments, delayed hydration, or route flags cannot be produced in the real app, retain the relevant row as UNVERIFIED and name the missing fixture. No fabricated screenshots or unit-test substitutes for interaction proof.

Use E1/P1 as target, E1/P2 as another project, E2/P1 as same project id on another environment if available. Give drafts unique visible markers and strictly ordered creation timestamps: A older text, B newer text, C newest whitespace-only. Add a newer foreign-project/environment decoy. Editing A last must not change the expected winner B. Do not send prompts or run providers to prove restoration.

## Minimal fixture matrix

All runtime rows below are UNVERIFIED in this pass: device interaction/capture was explicitly prohibited. Source-derived expectations are not observed results. Theme is orthogonal to selection logic: repeat the principal interaction in light/dark; run the remaining controls in one theme, not a Cartesian product.

| ID | Fixture and entry/action | Required observable result | Evidence / status |
|---|---|---|---|
| M1 | E1/P1 has A, B, C and foreign decoys; leave to an existing P1 thread, invoke Android plain New thread. | B resumes, despite C being newer but empty and A edited last; correct project/environment, text intact, no send. Back out and repeat; B remains reachable, no duplicate content or destructive clear. | Core interaction video + terminal frame, light AND dark. UNVERIFIED. |
| M2 | Same project has no eligible text draft; newest eligible draft has attachment only, with a newer whitespace-only draft. | Attachment-only draft resumes with the actual attachment accessible; whitespace/settings do not outrank it. | One-theme continuation in control video. UNVERIFIED; attachment fixture required. |
| M3 | E1/P2 has only empty/whitespace/settings drafts; other project/environment has nonempty drafts. Invoke New thread for P2. | Empty P2 composer; no foreign content. Covers empty set and negative scope. | One-theme control video. UNVERIFIED; E2 decoy subcase remains explicitly UNVERIFIED if a second environment cannot be seeded. |
| M4 | Open picker path to P1 with no explicit initial project; separately invoke plain New thread while a different project's thread is selected. | Picker selection resumes intended P1; direct entry resumes the current thread's exact project, not transient/fallback selection. Existing content typed before hydration must survive. | One-theme control video. UNVERIFIED; cold/delayed hydration and pre-hydration input subcase unverified unless reproducible in app. |
| M5 | B resumed; type an extra marker, change project using existing picker, return/navigate back. | User's active content is preserved through existing retarget behavior; no second auto-resume replaces it during this mount. | One-theme control video. UNVERIFIED. |
| C1 | Explicitly open older A from draft list while B exists; separately edit an existing queued task. | Requested draft/task opens, not B; task remains queued and editing semantics unchanged. | Two short segments in control video. UNVERIFIED; queued fixture required. |
| C2 | Enter incoming share with content; separately start from a selected branch; separately enter clone flow, with B available. | Share payload/selected branch/clone context retained; B does not hijack these flows. | Three one-theme segments if fixtures available. UNVERIFIED; do not mutate a real repository just to seed branch/clone proof. |
| C3 | Invoke command palette New thread and hardware newTask from same P1 context. | Same intended-project behavior as Android button; no independent UI redesign required. | One-theme smoke segments; shared handler proven by source, runtime UNVERIFIED if keyboard unavailable. |

No provider-by-provider, web/desktop, tablet/split-view, iOS, network-mode, or theme×fixture sweep is justified by this single mobile selection effect. Mobile iOS shares the changed screen but is outside the requested Android device proof. Server/contract/MCP/scheduled-task paths are unchanged; scheduled-task creation is a different feature, not this composer entry. Do not infer other clients were tested.

## Minimum captures and acceptance gate

Existing baseline artifacts (files verified present; videos probed, not visually reviewed):

- Light: `/tmp/issue-15974-before-light-valid.mp4` (1080×2424, ~15.58s), `/tmp/issue-15974-before-light-valid.png`.
- Dark: `/tmp/issue-15974-before-dark.mp4` (1080×2424, ~13.33s), `/tmp/issue-15974-before-dark.png`.
- Corresponding `.gesture-telemetry.json` files each contain two taps using 1080×2424 reference coordinates. This confirms metadata exists, not that the baseline demonstrates the required behavior. Do not substitute the earlier non-valid light recording.

Minimum NEW evidence package: three interaction recordings and two stills. Planned paths (not created):

1. `/tmp/issue-15974-after-light.mp4` — M1, visibly show starting context, New thread action, restored B, back/re-entry; end on restored composer.
2. `/tmp/issue-15974-after-dark.mp4` — same principal interaction in dark.
3. `/tmp/issue-15974-controls.mp4` — one-theme, clearly separated M2–M5/C1–C3 segments that can actually be seeded; attach a timestamp-to-row index after capture. Any absent segment leaves its row unverified, never implicitly passed.
4. `/tmp/issue-15974-after-light.png` and `/tmp/issue-15974-after-dark.png` — terminal frames paired with supplied before stills. Stills supplement, not replace, the interaction recordings.

Keep native 1080×2424 framing with action and result visible; include tap indicators/gesture telemetry where available. Verify tested bundle/head provenance separately before labeling videos “after head.” Do not claim existing baseline proves multi-draft ordering unless the fixture contents/timestamps are independently known. If baseline and M1 fixtures differ, label that mismatch and capture a matched before later rather than inventing equivalence. A single happy-path clip proves visible resume, not newest/scope/exclusion semantics.

## FRICTION

- Device drive, capture, server launch, subagents, checkouts, repo/forge edits, merge, and watch were prohibited. None performed. No automated checks run; this pass is read-only source/evidence planning.
- App runtime, installed bundle revision, actual seeded drafts, theme, session ownership, attachment access, and baseline visual validity remain unverified. Existing file presence/dimensions are the only baseline checks performed.
- Hydration race/current-content protection and exact environment collision need device-local fixtures; source inspection alone cannot close them. If normal UI cannot create them, report UNVERIFIED rather than silently shrinking the coverage claim.
- “Newest” is creation order, not edit recency. Confirm that product meaning before treating a last-edited expectation as a defect. The one-shot ref is per screen mount, so project changes after initial evaluation are a focused interaction risk covered by M4/M5, not a reason to expand to every navigation permutation.
- Upload scope is this synthetic matrix only. No recordings, auth/pairing URLs, device data, or forge state are uploaded or changed.
