Final-head addendum: reviewed head is [7a5fcf45e1](https://git.cafe/pingdotgg/t3code/commit/7a5fcf45e1f6df8fd5b1b1c42545ed76c9135b2f), against [4619c0bca6](https://git.cafe/pingdotgg/t3code/commit/4619c0bca6a385e53f3479e4e52a9cdf2d12ff62). The final correction retries the guarded late-directory seed after repository lookup completes (success, error, or cancellation). N7 must include config arriving during lookup, with untouched and edited destinations. Both final code reviewers returned MERGE. Native N0–N9 remain unverified with zero captures/assertions: cannot-verify ios-swift. Earlier head references below are historical audit provenance; no native proof was delivered for either head.

# Issue 16507 — read-only proof audit, final pass 2

Issue: [#16507](https://git.cafe/pingdotgg/t3code/issues/16507).
Worktree: `/home/ubuntu/wt/issue-16507`; branch `fix/issue-16507`.
Before: [4619c0bca6](https://git.cafe/pingdotgg/t3code/commit/4619c0bca6), base `origin/t3code/rebuild-mobile-app-swift` (resolved full SHA `4619c0bca6a385e53f3479e4e52a9cdf2d12ff62`).
After: [d3be7b9378](https://git.cafe/pingdotgg/t3code/commit/d3be7b93785ccd1227374f6daf6f2222e8dcf896).
Budget ceiling: 60 minutes. This pass reads source and existing proof and publishes this matrix and a separate final audit. No source edits, captures, public comments, pushes, or PR creation.

## Scope and proof boundary

Full diff reviewed: four files, 51 additions / 5 deletions (both commits). It adds optional settings decoding, the FeatureEnvironment field and decoding, NativeFeatureClient's per-environment mapping, configured-path seeding in AddProjectView.resetEnvironmentState, and guarded same-ID late-config reseeding. Git diff whitespace check passed; no native compilation or tests ran. No server, RN, web, desktop, layout, or new-project-root implementation changed.

All native executable rows below are **UNVERIFIED — cannot-verify ios-swift**. This host is Linux; neither Swift nor Xcode is on PATH, and SwiftUI/iOS cannot run here. Static inspection establishes code intent, not successful decoding, compilation, native interaction, timing, or visual behavior. RN/web footage cannot substitute for Swift proof. The user's explicit instruction permits a PR against the Swift branch carrying this limitation; this pass does not create one and does not claim native acceptance.

Existing `/tmp/16507-runtime.log` is server-only proof, attributed by the operational brief to main [b5a226e49c](https://git.cafe/pingdotgg/t3code/commit/b5a226e49c). It shows:

- `getConfig.settings.addProjectBaseDirectory = /tmp/issue-16507-projects`
- browse `~/` returns parent `/home/ubuntu` and home entries.
- browse `/tmp/issue-16507-projects/` returns that directory as parent, with empty entries.

The log itself has no SHA/timestamp stamp. Attribution comes from the brief. It proves neither this Swift head nor automatic selection of the configured path, tilde-config resolution, clone behavior, switching, or delayed config. Empty configured-directory entries do not prove child navigation.

## Small fixture set and capture contract

Future fixture preparation only; no fixtures were created in this audit. Use isolated disposable environments, never live userdata. A (Alpha) and B (Beta) have distinct IDs, connected/enabled state, project-creation access and server-browser support. A home is `/home/proof-a`, B home `/home/proof-b`. A setting `~/projects`; B `/tmp/proof-beta`. Create each base plus `existing-repo` (a tiny local Git repo) and `nested`. Keep newProjectsRoot independently `/tmp/proof-new`. Use one disposable readable remote named `proof-repo.git`, plus `other-repo.git`; actual test transport is supplied by the authorized runner, with no credentials in recordings. Clone testing may stop before submission: this change concerns the destination, not network cloning.

Parameterize A's setting as `~/projects`, `/tmp/issue-16507-projects`, `  ~/projects/ \n`, absent key, JSON null, empty string, whitespace-only, and a nonexistent absolute directory. Do not multiply every parameter across every flow. Use absent/null/empty/whitespace in one fallback run; use trimmed/trailing-slash input in one configured run. B provides the absolute-path and environment-isolation run. Only two environments and two child directories are needed; no scale/load matrix.

Default surface V1: native Swift iPhone portrait, approximately 393×852 points, dark, default Dynamic Type. V2: compact native iPhone portrait, approximately 375×667 points, light, keyboard shown during edits. Record exact simulator/device, iOS, viewport, theme and build SHA. Run the main flow on V1 and only the specified V2 rows; no full theme/device cross-product. No iPad or RN/web/desktop acceptance footage is required because this patch changes only Swift data and path seeding, with no layout change. Remote A/B supplies environment behavior; tunnel-specific transport is unchanged.

Every interaction/time row is marked **recording**. Future before and after recordings must show identical fixtures and steps, build identity, selected environment, triggering action, path field and browser result through async completion. Keep enough continuous footage to prove ordering and retention. A screenshot, source excerpt, mocked web view, or static end state is never a substitute. Collect corresponding environment-tagged browse requests/results when possible, sanitized. No recording was made in this pass.

## Fixture matrix

| ID / diff coverage | Data and steps | Expected BEFORE → AFTER | Required evidence / minimum variants | Feasibility and status |
|---|---|---|---|---|
| S0 — server contract baseline | Read supplied runtime log; compare configured absolute browse and home browse. | Server semantics unchanged: config key exists; trailing slash browses directory contents rather than treating directory name as a prefix. | Existing text runtime proof; no interaction performed here. | **Feasible / reviewed**, limited to the three logged observations above on main, not native head. |
| N0 — settings decode/map | Feed minimal valid config with settings value, then absent key, null, empty and whitespace; map A and B; round-trip FeatureEnvironment including legacy object without new field. Assert configured value survives ServerSettingsSnapshot → NativeFeatureClient → FeatureEnvironment, legacy stays nil and no cross-environment leakage. | Before Swift discards key / field unavailable → after exact optional string retained per environment; missing/null decode nil without failure. Normalization belongs to view, not decoder. | Native executable assertions/log; non-interaction row, recording not required. Cover all three added data-layer files. | **UNVERIFIED — cannot-verify ios-swift**; no Swift toolchain; source mapping reviewed only. |
| N1 — configured Folder | On A with config already available, open Add project from sidebar, select Folder, inspect field/browser, enter `nested`, return and choose `existing-repo`. Repeat padded/trailing-slash setting once. | Before initial field/request `~/` → after `~/projects/` (trimmed, no duplicate slash); browser parent resolves A's projects. Navigation selects the actual chosen folder on A. | **recording**, V1; repeat path visibility/navigation on V2 light with keyboard. Include initial browse and final selection. | **UNVERIFIED — cannot-verify ios-swift**; native UI unavailable. |
| N2 — fallback | Open Folder and Clone separately with absent/null/empty/whitespace A setting; no repo text initially, then type `proof-repo` URL. | Before home defaults → after same `~/` fallback, no empty browse request; clone derives home/proof-repo. | **recording**, V1; parameter cases may share a labeled continuous run. | **UNVERIFIED — cannot-verify ios-swift**. |
| N3 — Clone, empty then edited repo | With A configured and config warm, open normal Add project, choose Clone; inspect empty destination, type proof-repo URL, replace with other-repo URL, navigate base to nested. Optionally resolve one ready provider's owner/repo input in same run. | Before home-based destination → after initial projects base then projects/proof-repo, projects/other-repo, nested/other-repo. Repository resolution preserves configured/current browse base. | **recording**, V1, include typing, resolution if used, and async browse completion; inspect destination without starting clone. | **UNVERIFIED — cannot-verify ios-swift**. One ready provider sufficient; no adapter cross-product. |
| N4 — existing repository input at presentation | Use native clonePrompt route for A with proof-repo remote already seeded; open sheet directly in Clone. | Before home/proof-repo → after projects/proof-repo from reset even though no repositoryInput edit occurs after appearance. Correct A selected rather than alphabetical fallback. | **recording**, V1, start before prompt-route trigger; show seeded input and destination. | **UNVERIFIED — cannot-verify ios-swift**. Covers initializer initialRemoteURL and initialEnvironmentID. |
| N5 — edited-path retention | A/Clone: edit destination to `/tmp/proof-manual/custom`; then change repo text, change ready source/resolve, browse nested, allow same-ID config refresh. A/Folder: edit localPath manually and allow non-selection initial browse/refresh to finish. | Before manual destination retained → after retained on same environment; didEditDestination guards suggestions, initial load updateSelection=false must not overwrite folder edit. Explicit folder selection may change localPath. | **recording**, V1; V2 keyboard/path visibility repeat of manual destination and repo edit only. Keep async completion in clip. | **UNVERIFIED — cannot-verify ios-swift**. No inference of retention from static fields. |
| N6 — switch and stale result | Begin A browse with a controlled delayed response; enter repo URL and manual destination; switch to B before A returns, release A response, switch back to A. Repeat Folder briefly within same run. | Before both hosts reset home → after B fields/browser reset to `/tmp/proof-beta/`, clone suffix retained from existing repo input, manual edit intentionally reset; return A restores projects defaults. Late A result cannot populate B. Source/discovery resets remain consistent. | **recording**, V1; capture switch, request order, late completion and final host/path. | **UNVERIFIED — cannot-verify ios-swift**. Requires controlled native/client response ordering, no arbitrary sleep acceptance. |
| N7 — cold config, unedited and edited | Clear disposable client cache; hold config while connected A is exposed; open Folder/Clone, release config with `~/projects` while keeping A ID. Repeat editing a path before release; dismiss/reopen as diagnostic. Also run normal cold startup where config precedes connected snapshot. | Before stays home → desired after unedited cold sheet uses configured base when available; edited path survives late config. If app guarantees config before connected exposure, prove that ordering and mark late-exposure variant unreachable. Reopen may use configured path but is not proof of current-sheet repair. | **recording**, V1, continuous startup/open/config arrival/settlement plus event order; include normal startup. | **UNVERIFIED — cannot-verify ios-swift; SOURCE CORRECTION REVIEWED**. Final head observes the normalized base and reseeds only for matching seed/environment, unchanged localPath, unedited destination and no submission/clone state. Explicit selection clears the seed. Old no-same-ID-reseed concern is superseded, but no native timing/retention proof exists. Also exercise config arrival during provider lookup: isSubmitting suppresses reseed and lookup completion does not explicitly retry it. |
| N8 — caller parity | With same warm A config, exercise sidebar Add project; NewTask onCreateProject callback; command palette Add Project; New task with zero projects (button/keyboard routed to same destination); clonePrompt covered by N4. Close/reopen between triggers. | Before every caller inherits home seed → after all reach same configured path in shared sheet; new-task fallback opens New when supported, switch Folder to inspect base. No stale prompt seed after closing. | **recording**, V1, a single labeled run for equivalent callers; N4 separate seed variant. | **UNVERIFIED — cannot-verify ios-swift**. One actual AddProjectView construction found, WorkspaceView line 158; trigger paths lines 721, 916, 960, 1029 and palette line 777. |
| N9 — missing directory/error and New boundary | A setting points to nonexistent `/tmp/proof-missing`; open Folder, observe error, manually enter known existing directory and browse. Separately choose New with root `/tmp/proof-new`, enter name without submit. | Before home browse succeeds → after configured missing path is attempted and existing error/direct-entry recovery works, no silent home success. New preview still derives from newProjectsRoot, independent of addProjectBaseDirectory. | **recording**, V1; show error then recovery and New root. | **UNVERIFIED — cannot-verify ios-swift**. Error behavior unchanged; changed initial path newly exposes it. |

## Source basis and audit conclusion

All source links below pin the audited head:

- [ServerConfigModels.swift](https://git.cafe/pingdotgg/t3code/blob/d3be7b93785ccd1227374f6daf6f2222e8dcf896/apps/swift-ios/Core/ServerConfigModels.swift): optional property, CodingKeys and decodeIfPresent.
- [FeatureModels.swift](https://git.cafe/pingdotgg/t3code/blob/d3be7b93785ccd1227374f6daf6f2222e8dcf896/apps/swift-ios/Features/Shared/FeatureModels.swift): optional environment field and legacy-compatible decoding.
- [NativeFeatureClient.swift](https://git.cafe/pingdotgg/t3code/blob/d3be7b93785ccd1227374f6daf6f2222e8dcf896/apps/swift-ios/App/NativeFeatureClient.swift): line 6713 maps environment-specific settings; setServerConfig stores configs.
- [AddProjectView.swift](https://git.cafe/pingdotgg/t3code/blob/d3be7b93785ccd1227374f6daf6f2222e8dcf896/apps/swift-ios/Features/Workspace/AddProjectView.swift): initial paths remain home until selected-ID task resets; reset normalizes configured base; same-ID normalized-base changes trigger guarded reseeding; initial browse does not update selection; manual clone edits guard suggestions; switching clears edit guard.
- [WorkspaceView.swift](https://git.cafe/pingdotgg/t3code/blob/d3be7b93785ccd1227374f6daf6f2222e8dcf896/apps/swift-ios/Features/Workspace/WorkspaceView.swift): shared sheet plus ordinary, empty-project, palette and prompt-clone triggers.
- [ProjectCreationModels.swift](https://git.cafe/pingdotgg/t3code/blob/d3be7b93785ccd1227374f6daf6f2222e8dcf896/apps/swift-ios/Features/Workspace/ProjectCreationModels.swift): existing directoryBrowsePath trims and appends slash (Windows separator branch too), preserving browsing-directory semantics.

Windows paths are a conditional extension, not minimum iPhone proof: if supported remote Windows hosts are claimed for acceptance, parameterize N0/N1/N3 with `C:\\proof-projects` and validate separator/browse behavior against an actual Windows environment. Not exercised or proven by this Linux server log. Settings authoring UI, provider execution, desktop, web and RN remain outside the changed native implementation; upstream settings are controlled fixture inputs rather than substitute client proof.

Feasible completed: full diff/caller/helper/lifecycle inspection and S0 existing-log review. Native executable rows N0–N9 all remain unverified. No new tests or UI proof were run. N7's old absent-reseed concern is corrected in source. Timing, guard behavior and request ordering remain unexecuted; lookup-in-flight config arrival has a source-visible skipped-reseed path described in the final audit, not a native reproduction. Do not report visual/native pass or native compilation success. Acceptance under the explicit Swift-platform exception must retain `cannot-verify ios-swift` and these affected rows.

## FRICTION

| category | happened | prevention |
|---|---|---|
| platform | Linux has no Swift/Xcode; no native execution or recording possible here. | Run N0–N9 on authorized macOS/iOS infrastructure later; retain cannot-verify ios-swift meanwhile. |
| operational brief | Requested `/home/ubuntu/t3code-ops/docs/EVIDENCE.md` is absent. | Used the explicit task brief as authority; no fabricated policy or replacement file. |
| proof provenance | Existing runtime log is from main per brief and contains no embedded SHA; it covers only config key and two browse results. | Label it server-only and stamp revision/environment in future runtime evidence. |
| inspection noise | Pass 2 initially treated the concatenated branch/SHA in the brief as one ref; a broad read exceeded output limits. | Resolved branch and SHA separately and reread focused source sections; full four-file diff was not truncated. |
| timing coverage | Final head adds guarded same-ID reseed, but no native timing/retention run exists; lookup-in-flight config changes can be skipped without retry. | Keep N7 unverified; capture normal arrival, edit retention, stale browse and lookup-order variants on native Swift. |

## Final pass 2 evidence accounting

Native captures: **0**. Native executable assertions: **0**. N0–N9 are all missing execution proof; interaction rows N1–N9 are also missing continuous native before/after recordings, device/iOS/build metadata and the specified V1/V2 variants. No measured visual or pixel delta exists. Fixtures are plans only; no A/B seeding execution was supplied. S0 is partial server-only evidence, not a complete native pass.

The supplied native-check log says exactly `[swift-ios-ci] error: missing required command: xcodebuild`; it is a prerequisite failure, not a Swift compiler failure or success. Linux availability was reconfirmed without launching a build. The explicit user Swift-base exception permits Julius to carry `cannot-verify ios-swift` on a PR against the Swift branch; it neither fills these rows nor authorizes PR writes in this audit.

Final-head late-config source correction is consistent with the supplied evidence index. The old matrix head and N7 no-observer description were stale artifacts, not contradictions proving the final head fails. Server-main provenance, zero native proof and missing native fixtures remain limitations.


## Concurrent worktree advance

The initial HEAD and full diff were the requested [d3be7b9378](https://git.cafe/pingdotgg/t3code/commit/d3be7b93785ccd1227374f6daf6f2222e8dcf896). Final read-only status found a clean worktree now at externally created [7a5fcf45e1](https://git.cafe/pingdotgg/t3code/commit/7a5fcf45e1f6df8fd5b1b1c42545ed76c9135b2f). Its only diff adds a guarded reseed retry after repository lookup clears isSubmitting, addressing the requested head's static lookup-overlap concern in source. This report remains pinned to the explicitly requested d3be7b9378; it does not audit or certify native behavior of the later head. No native evidence was added by that source correction. No source or git mutation was performed by this audit.

VERDICT INSUFFICIENT
Missing rows: N0, N1, N2, N3, N4, N5, N6, N7, N8, N9. S0 supports only its three logged server observations. Eligible for the explicit platform exception; native proof remains insufficient.
