# Evidence-only proof matrix — pass 1

PR [#22226](https://git.cafe/pingdotgg/t3code/pulls/22226), mirrored as [#22226](https://github.com/pingdotgg/t3code/pull/22226). Author macodev00, branch `cursor/clone-file-manager-12647`, target `main`.

Before / actual merge-base: [4f651cb10d](https://git.cafe/pingdotgg/t3code/commit/4f651cb10d2a885be82748e22a280eeef591200f) (`4f651cb10d2a885be82748e22a280eeef591200f`). After: [6c0099b88e](https://git.cafe/pingdotgg/t3code/commit/6c0099b88ee0285f64aa73236f8b6a35422e2947) (`6c0099b88ee0285f64aa73236f8b6a35422e2947`). Worktree `/home/ubuntu/wt/pr-22226`. No capture performed in this pass; rows below are capture instructions, not completed evidence. No implementation review or merge verdict.

## Scope derived from the complete diff

Exactly three changed paths, 70 insertions:

- [apps/web/src/components/CommandPalette.tsx](https://git.cafe/pingdotgg/t3code/src/commit/6c0099b88ee0285f64aa73236f8b6a35422e2947/apps/web/src/components/CommandPalette.tsx): confirm-step native-picker result now submits clone; WSL UNC mapping rejects a destination environment mismatch.
- [packages/client-runtime/src/operations/projects.ts](https://git.cafe/pingdotgg/t3code/src/commit/6c0099b88ee0285f64aa73236f8b6a35422e2947/packages/client-runtime/src/operations/projects.ts): new full-picked-path helper reuses in-app folder-name rules.
- [packages/client-runtime/src/operations/projects.test.ts](https://git.cafe/pingdotgg/t3code/src/commit/6c0099b88ee0285f64aa73236f8b6a35422e2947/packages/client-runtime/src/operations/projects.test.ts): helper path examples.

Followed callers: Sidebar Add project → command palette; palette Git URL and source-provider repository lookup → same confirm step; file-manager footer → localApi → desktopBridge.pickFolder; ordinary and WSL results → submitAddProjectCloneFlow → tracked startProjectClone or legacy cloneRepository. In-app browsing uses getCloneDestinationBrowsePath. Mobile AddProjectDestinationScreen uses that existing browser helper, not the new native-picker helper. No contracts, provider adapters, server code, native mobile code or styles changed. Settings, scheduling and MCP have no new picker entry point in this diff; agent-runtime provider permutations are unnecessary. Source-control lookup providers share the confirm handler: use direct URL for primary proof and one configured lookup provider as an entry-point control.

## Minimum presentation coverage

| Surface | Minimum viewport and theme | Required evidence |
|---|---|---|
| Web with synthetic desktop bridge | 1440×900 CSS px, dark; repeat core destination/result in light | recording for core flow, paired stills optional |
| Plain web, no bridge | 1440×900 dark plus 390×844 light | recording of in-app clone; no native picker footer |
| Plain mobile | iOS static fixture, 393×852 logical points, light and dark | destination stills; any interaction/time claim requires recording |
| Windows/WSL | 1440×900 dark, synthetic routing first | recording; native-host confirmation separately labeled |

Do not cross every row with every theme. Repeat the core happy path in light, narrow plain-web control in light, and iOS destination in both appearances. Record actual viewport, pixel ratio, OS, theme, revision, fixture root and bridge/capability mode in each evidence manifest.

## Capture matrix

All interaction/time rows explicitly require **recording**. Preserve start, action, pending/error and settled outcome without edits that hide intermediate state. Pair before/after with identical fixtures but independent destination roots and isolated app homes.

| ID / priority | Fixture and branch | Exact action | Expected before → after / proof | Artifact |
|---|---|---|---|---|
| A1 / P0 | Linux primary, tracked cloning, picker returns fresh `<root>/picked` | Add project → Git URL → local fixture URL → Continue → Open in Files | Before adds empty picked as project; after dispatches clone to picked/repo, then project/thread opens; prove .git and README, no spurious picked project | recording + sanitized request/result and disk manifest |
| A2 / P0 | picker returns empty `<root>/repo` | Same flow | After uses repo itself (not repo/repo); returned path may have trailing slash | recording + disk manifest |
| A3 / P1 | Linux picker returns `<root>/Repo`, then `<root>/picked/` in separate fresh roots | Same flow twice | Case-sensitive Repo/repo; trailing slash picked/repo | recording + exact destination request |
| A4 / P1 | Windows-configured environment, `C:\Proof\Repo`, repository repo | Same flow with bridge fixture | Case-insensitive match uses Repo itself; parent `C:\Proof` produces Proof\repo | recording + request transcript; synthetic Windows, not native proof |
| A5 / P1 | Root `/` and Windows drive root in synthetic path fixture only | Resolve helper; do not perform disk clone at filesystem root | `/repo`, drive-root child repo; compare helper to in-app rules | textual helper output; if exercised through UI, recording |
| A6 / P0 | Both picker null and rejected promise | Click file-manager action, cancel/reject, then retry with valid fresh folder | No project/clone on cancel/reject; picker becomes available again and succeeds | recording + zero-mutation/request counts |
| A7 / P1 | Deferred picker result | Double-click picker action while promise unresolved; resolve once | One picker call; one clone dispatch | recording + call counts |
| A8 / P0 | WSL Ubuntu maps to same target environment; `\\wsl.localhost\Ubuntu\home\proof\picked` | Confirm clone → picker UNC result | After Linux `/home/proof/picked/repo` dispatched to matching environment; same-named repo stays repo; also parameterize `\\wsl$\Ubuntu\…` | recording + mapped environment/path transcript |
| A9 / P0 | UNC Ubuntu resolves to environment B, clone confirm belongs to A | Choose B folder from A clone flow | After error “Choose a folder in the environment the repository is cloned into.”; zero clone/project dispatch to either environment | recording + request counts |
| A10 / P1 | UNC distro has no matching running/configured backend | Choose UNC folder | Existing “Could not add WSL project” state; zero clone/project dispatch; retry after valid mapping | recording |
| A11 / P1 | WSL-only primary Linux with enabled=true, wslOnly=true, distro Ubuntu; then desktop-local secondary bootstrap | Open picker in each target | picker options targetEnvironmentId is `wsl:Ubuntu` or matching pool bootstrap id; selection still routes by catalog environment ID | recording + picker options and environment map |
| A12 / P0 | projectCloneTracking absent/false, fresh picked parent | A1 using legacy server fixture | Before adds folder; after waits for cloneRepository, then adds returned cwd; pending UI followed by success | recording + legacy request/result |
| A13 / P0 | Tracked clone accepted then asynchronous failure; separately legacy rejected clone and immediate start failure | Clone into nonempty folder or stub deterministic “fixture clone denied”; retry fresh path | Correct failure visible; no successful empty-folder substitution; recover and clone once | recording through failure/recovery + mutation transcript |
| A14 / P0 | Revoke source-control write or orchestration operate after entering confirm; separately mark environment disconnected | Return valid picker selection | Permission/unavailable toast, zero clone dispatch, no empty project added | recording + destination-environment scope snapshot |
| A15 / P1 | Ordinary Add local folder mode, confirm clone absent | Open file manager and choose picked; repeat valid WSL mapping | Existing add-folder behavior retained; no clone request | recording + project/request manifest |
| A16 / P1 | Plain web with bridge undefined | Add project → Git URL → in-app parent selection; repeat repo-name folder | In-app clone still works; native file-manager footer absent | recording, desktop dark and narrow light |
| A17 / P1 | One configured source-control lookup provider | Lookup repository → confirm → native-picker fresh folder | Same submit path as URL; lookup URL/name feed the helper correctly | recording; no need to repeat all source providers |
| M1 / P0 | Plain mobile iOS static fixture: connected environment, remoteUrl, repositoryName=repo, base dir `/proof/picked`, grants both scopes | Render AddProjectDestinationScreen through actual iOS components | Path `/proof/picked/repo`, Clone project action and folder browser visible; no desktop file-manager picker affordance | light/dark stills, explicitly static iOS fixture |
| M2 / P1 | Same iOS fixture with no grants; separate empty/disconnected environment | Render unavailable destination states | Cannot clone; appropriate permission/empty-environment presentation | static iOS stills; any change between states requires recording |
| M3 / P1 | Existing iOS-configured static behavioral test fixture | Invoke retained Clone project callback after revoking each scope | No clone directory and no project created | test log; this is static logic proof, not native UI or animation proof |

## Reproducible app seeding and bridge setup

Linked artifacts: [seed.sh](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/1d7243125d7da610/seed.sh) and [picker-stub.js](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f744020b6de6e396/picker-stub.js). Local copies are beside this matrix. They are external capture fixtures, never committed. This audit did not execute the seed script or start servers.

1. For a later authorized capture, run `bash /tmp/pr-22226-proof/seed.sh`. It prints FIXTURE_ROOT and a deterministic local `file://…/repo.git` URL (repository name repo), creates a one-commit bare repository, empty picked/repo/Repo folders and a nonempty failure folder. Run separately per before/after and per row that creates a destination. Git timestamps/SHA vary; contents and structure are deterministic. No network credentials needed. Native Windows needs its own local fixture or a reachable sanitized test remote; Linux file URLs are not portable to Windows/WSL hosts.
2. From the requested worktree, later launch `vp run dev --home-dir /tmp/pr-22226-capture-head-home` using a fresh home and retain its PID/session. Read actual ports from dev-runner. Do not set VITE_HTTP_URL/VITE_WS_URL. Before capture needs the exact merge-base in an independently prepared checkout; do not switch this worktree or mutate branches under this read-only authorization.
3. Pair only disposable clients to that server, keeping credentials out of output. Use fresh synthetic state, not copied live threads. Add the fixture source folder as an ordinary project through the app to provide meaningful sidebar context; optionally create one stopped empty thread with no provider turn. Configure the add-project base directory via Settings to `<FIXTURE_ROOT>/picked`, or type the destination explicitly. Seed via app commands so event history stays coherent. The clone URL and fixture README are public synthetic data.
4. For A1–A3, after app bootstrap install the linked picker stub, then set `window.__cloneProof.pickedPath` to the actual printed absolute folder. Open/reopen Add project so the bridge gate is recomputed. Its calls array proves picker arguments; cancel uses null, error uses reject=true. Reload restores plain web. Stub is a narrow post-bootstrap fixture, not a full desktop runtime or OS file-dialog test. If installed before bootstrap, a complete DesktopBridge implementation is needed; do not assume this narrow object supports startup.
5. WSL synthetic fixture: set wslState `{enabled:true,wslOnly:true,distro:'Ubuntu',distros:[{name:'Ubuntu',isDefault:true}]}` and provide bootstraps with correct real descriptor fields, matching httpBaseUrl and runningDistro. The stub alone cannot create environment registry entries. Supply actual desktop-local targets / connected server fixtures for A and B, matching pool backend IDs (`primary`, `wsl:Ubuntu`) and their catalog environment IDs. Then return UNC picked paths. For mismatch, map Ubuntu to B while confirm belongs to A. WSL-only-primary and secondary bootstrap are separate routing branches. Native desktop may already convert UNC to Linux paths: record which representation crosses the bridge.
6. Tracked/legacy/failure modes: capability `serverConfig.environment.capabilities.projectCloneTracking` controls dispatch. A faithful RPC fixture must implement discovery, browse/list-directory responses and connected environment config, plus clone/start responses and project projection updates. Current tracked flow calls startProjectClone with projectId,title,createdAt,remoteUrl,destinationPath, closes palette, waits for project projection, then opens a thread. Legacy cloneRepository returns `{cwd}` and only then adds project. Do not fake success with a toast alone. Capture request routing and project state, not just rendered labels. For synthetic delayed states, retain a deferred promise and explicitly release it; do not invent real timing measurements from a static mock.
7. Root/case/separator inputs can be checked as pure helper fixtures without starting a server. Never clone into `/` or a real Windows drive root. The committed helper test covers POSIX parent/trailing slash/same-name/case mismatch, Windows case-insensitive same-name/parent and POSIX root. Drive root is an additional matrix fixture.

## Exact static mobile possibilities and limits

Existing `apps/mobile/src/features/projects/AddProjectScreen.test.ts` explicitly stubs `Platform.OS` to `ios`, connected environment ID `environment`, server config platform linux, base directory from a temporary directory, capabilities `{}` (legacy), scopes from a mutable Set, navigation, native wrappers, cloneRepository and project creation. It directly invokes AddProjectDestinationScreen with remoteUrl `https://example.com/repo.git` and repositoryName `repo`; it is suitable for M3 logic, not a screenshot. Its clone stub mkdir is not a real git clone.

For M1/M2 visual evidence use an external iOS fixture entry that mounts the real AddProjectDestinationScreen inside its navigation, appearance and safe-area providers, with deterministic registry/entities/RPC state matching the preceding paragraph. Do not replace native components with string test doubles for a visual claim. Route is `add-project/destination` (Stack AddProjectDestination); props environmentId, remoteUrl, repositoryName (optional repositoryTitle/prompt). Full app alternative: pair an iOS client to the isolated server and navigate Add project → Git URL → destination. That is an integrated app recording, not a static fixture. No existing add-project showcase scene was found; mobile-showcase's existing scene automation is not a ready-made destination fixture. Any fixture entry/runner added later must live under `/tmp/pr-22226-proof`, be linked as an artifact, and must not be committed. No visual iOS verification occurred in this audit. Do not label static iOS evidence as Android verification.

## Sensitive-surface gate

This feature launches source-control writes and creates projects in selected environments. Accept evidence only if the destination environment has BOTH source-control write and orchestration operate scopes, and mismatch/revocation rows demonstrate zero cross-environment writes. Native picker selection does not itself grant permission. Restrict all destinations to disposable fixture roots; keep personal folder names, repository credentials, auth/pairing URLs, tokens and live project/thread data out of captures and public artifacts. Static bridge/Windows/WSL recordings prove application routing only; actual OS picker, filesystem casing and WSL transport need native-host evidence if claimed. No provider execution, publish, push, merge or external messages are needed.

## FRICTION

FRICTION: local `main` is stale and yielded a huge unrelated diff; resolved using PR observed base plus `origin/main` merge-base, both identifying 4f651cb10d. Do not use local main for before capture.

FRICTION: worktree was initially absent and appeared after a brief wait; no checkout/preparation was performed by this audit.

FRICTION: before captures require an independently prepared exact-base runtime; current worktree must remain at the requested head.

FRICTION: native desktop/Windows/WSL runtime is not established by a browser bridge stub. Label synthetic evidence and leave native claims pending.

FRICTION: iOS static behavior fixture exists; no ready-made static add-project visual fixture was found. M1/M2 need an external fixture runner or an authorized real iOS session. Android is outside this pass's verified evidence.

FRICTION: all captures, browser/device interactions, servers, fixture execution and app seeding are deferred to the capture operator; this pass is read-only except external report artifacts and focused diagnostic tests.

## Completed diagnostics

`vp test run packages/client-runtime/src/operations/projects.test.ts apps/mobile/src/features/projects/AddProjectScreen.test.ts`: 2 files passed, 10 tests passed, 2.70 s. The mobile test explicitly uses iOS static mocks; this verifies M3 permission logic, not visual/native rendering. Worktree `git status --short` remained empty after diagnostics. No screenshots, recordings, browser/device use, server launches, comments or watches.
