# Proof audit pass 1: minimal fixture matrix

Review target: [#22193](https://git.cafe/pingdotgg/t3code/pulls/22193), issue [#16444](https://git.cafe/pingdotgg/t3code/issues/16444).
Head: [8952d199](https://git.cafe/pingdotgg/t3code/commit/8952d199fffeadc11b34837d382affd26aa6f5f1). Actual base: [d2fb83a9](https://git.cafe/pingdotgg/t3code/commit/d2fb83a973b53edcca1ab0677f99dac7e2d302ce).

Status: derived from the supplied diff and source reads; NOT executed. No screenshots, recordings, servers, checkout edits, provider changes, or forge writes performed. This is a capture specification, not passing proof.

## Fixture and seed strategy

Use the real web app, which also supplies desktop's web surface. A 390px viewport proves responsive web, not native mobile. No native mobile, contracts, server, or provider-adapter code changed; do not multiply the matrix across those surfaces or all six drivers. Use Claude plus Codex as distinct instances with distinct model names, with at least two Claude models and a descriptor-backed effort option. For determinism, use catalog models actually returned by the isolated environment; the unit-test names are illustrative, not an installation requirement.

Prepare isolated T3 state only, never run against or modify ~/.t3/userdata. If real data is useful, migrate a read-only snapshot into isolated .t3 while the isolated server is stopped. Use a disposable project without t3.json default overrides. Through real Settings, save an explicit Claude model plus nondefault effort, and keep Codex runnable as the fallback/replacement. Save exact defaultModelSelection (instanceId, model, options) before each transition and inspect destination settings afterward; pixels alone cannot prove persistence.

Main entry: /settings/general, scope selector set to one connected environment (search uses machine=<environmentId>). The affected row is New threads → Model, not another default picker elsewhere in General Settings. Project entry: /settings/projects, selecting the disposable project through the scope controls (project=<resolved projectKey>, optionally machine and checkout=<physicalProjectKey>). Use the UI to generate keys rather than invent project IDs. Both mount ProjectDefaultsSettings; project category changes description and source/reset behavior. Source-control does not render this model row.

Set provider enabled through /settings/providers in the same isolated environment/scope. ModelSelection persists at server default or project override according to selected scope. Do not confuse provider-level availability with a missing model, auth failure, or a disconnected environment. Unavailable requires a snapshot with availability="unavailable"; missing requires the saved instanceId to be absent from the provider snapshot. Prefer genuine isolated environments that naturally produce these states. If their configuration cannot produce them deterministically, inject contract-valid provider snapshots at the real app's transport/state boundary, preserve real routing/settings persistence, and label that evidence synthetic. Do not claim a fake status field proves availability.

Only use a component harness when the real-app fixture cannot express a state: the settings-off/snapshot-still-enabled race and defensive saved/displayed-instance mismatch are appropriate examples. Mount the production component with real settings/scope contexts where feasible; pure helper tests cover the otherwise unreachable mismatch. A picker-only harness cannot prove scope fan-out, RPC rejection, persistence, or re-enable behavior. Record the specific failed prerequisite before substituting a harness; this audit has not established that any prerequisite is impossible.

## Static capture matrix

Every V row below requires 1440/light, 1440/dark, 390/light, 390/dark. Hold viewport height and zoom constant (suggest 900px, 100%). Capture the complete Model row, status, reset, picker, and enough scope/page context to identify the destination. Open states must include their popup. That is 9 states × 4 = 36 head stills, not a Cartesian product of providers × scopes × actions. For before/after proof, replay the same nine seeds at the actual base and capture the same 36 views; unchanged views may be presented once with an explicit unchanged result. Do not compare different persisted seeds.

| ID | Seed / visible state | Required oracle |
|---|---|---|
| V1 | Explicit saved Claude, enabled and available, nondefault effort | Claude model and effort control; reset present; no availability note. Also use as recovered/replaced endpoint where visuals match. |
| V2 | Same saved selection; Claude turned off; Codex runnable | Saved Claude model remains visible; exact note `Claude is turned off.`; effort control absent (not merely disabled); model picker and reset remain usable. Codex must not silently replace saved default. |
| V3 | Same saved selection; Claude enabled but availability unavailable | Saved model retained; `Claude is unavailable.`; no effort control. Distinct wording merits its own still despite shared interaction behavior with V2. |
| V4 | Same saved selection; Claude absent from this environment | Saved model identifier retained in a usable picker; `This provider is not available on this environment.`; no effort control or fabricated provider icon. Long note must wrap cleanly at 390. |
| V5 | defaultModelSelection=null; at least one runnable provider | Resolved automatic fallback model visible; `Automatic` at environment scope; no explicit-default reset. Effort editable if supported. Never mistake automatic display for a persisted explicit selection. |
| V6 | All environments selected; two connected writable targets have different saved defaults | `Mixed` trigger; no per-provider availability note; no effort control. Preserve settings scope context. |
| V7 | defaultModelSelection=null and no selectable providers on a connected environment | `No providers available`, no picker/effort. Distinguish this from V4, where saved selection means picker is still rendered. |
| V8 | V2 picker open; Codex has selectable alternatives | Popup fits viewport, saved identity is not silently changed, only runnable alternatives selectable. Inspect actual disabled-provider visibility; do not demand an unavailable Claude option if existing picker intentionally filters it out. |
| V9 | All environments scope; representative has a model that another selected environment lacks | Open picker shows blocked model with the destination-specific disabled explanation. Include its visible explanation/tooltip. No misleading selectable affordance or clipped popup. |

Project scope is a coverage overlay, not another seven-state matrix: use V4's four stills on /settings/projects with an explicit project override to cover the newly visible project-source availability note and project description. Run the missing-provider environment case behaviorally too. Use the other static rows on /settings/general. If a project wrapper exposes a different layout defect, expand only that failing visual state.

## Interaction proof — RECORDING REQUIRED

Record these sequences; screenshots alone do not prove them. One 1440/light recording may combine R1–R4 with clear seed resets; one 390/dark recording covers touch-sized popup, wrapping, dismissal and replacement. Record R5 with two real isolated environment targets or explicitly disclose synthetic transport targets. Do not repeat every action at four visual combinations.

| ID | Sequence | Observable and persisted assertions |
|---|---|---|
| R1 | Save Claude+effort → disable Claude in Providers → return to General → open/dismiss picker without selection → re-enable Claude → return → reload | Disable, navigation, and mere menu opening leave saved tuple unchanged. Off note and absent effort while off; same Claude model/options return after enable, note clears, effort reappears. Re-enable is not a default-model write. Include project-scoped enable override once if supported by that fixture. |
| R2 | From V2 choose a runnable Codex model intentionally → reopen/reload → re-enable Claude | One intentional choice persists Codex instance/model, clears stale Claude options, dismisses popup, and restores Codex traits where supported. Later Claude re-enable must not undo intentional replacement. Repeat only the choose/reload portion from V4 to prove picker works with no activeEntry. |
| R3 | From retained unusable saved Claude, use default-model reset → reload; separately start from null and change fallback effort | Reset persists null and shows automatic fallback, without resurrecting Claude. Automatic effort change intentionally pins displayed fallback instance/model with chosen options. If no providers are runnable, reset reaches V7. Do not expect a dedicated Automatic menu option: reset is the path in this component. |
| R4 | Enabled Claude with saved model hidden through model preferences → adjust visible same-provider model effort → reload; visit project override and reset it | Hidden saved model follows effective same-provider model; effort saves that displayed model/options, never another provider. Project source/reset semantics follow the real scoped settings implementation; inspect effective value and override storage rather than assume reset deletes the override. This is behavioral coverage of existing hidden-model resolution, not another full visual row. |
| R5a | All environments: same saved Claude tuple, usable in representative A but disabled/unavailable/missing in B; attempt candidate unavailable in B | Do not silently overwrite either default. Model selection blocked with explanation naming B. Inspect settings on BOTH targets. Representative-driven row can look like V1 even when B cannot run; document this limitation, do not claim aggregate availability. Reverse representative usability once (select B separately, then return to all) and observe actual representative choice. |
| R5b | All environments: differing defaults (V6) → choose a model available with same instanceId/driver/model on both → reload both; reset to Automatic on both | Mixed resolves to common explicit choice, then null on both after reset. A model present only on A stays blocked (V9). Same driver under a different instanceId on B does not satisfy availability. Inspect each persisted destination; a screenshot cannot prove fan-out. |
| R5c | All environments: same saved tuple but B unusable → attempt effort change if representative exposes it | Capture whether the common model guard rejects the write with `Default model not saved`, leaving both saved tuples unchanged. This is a decision probe: the new presentation uses representative entries, not aggregate readiness; do not promise traits are hidden across all environments. Missing/disconnected targets without provider snapshots are skipped by modelDisabledReason; separately disclose unavailable-target handling by scoped write planning rather than treating skipped validation as universal support. |
| R6 | Missing project provider (V4) → picker open → Escape/backdrop dismissal → select available replacement; narrow viewport open/scroll/dismiss | Project availability note remains visible before mutation; no mutation on dismissal; explicit replacement persists in that project's scope only. At 390 no horizontal overflow, inaccessible reset, offscreen alternatives, or trapped page scrolling after close. Check keyboard focus return and a keyboard-select path on desktop. |

For V3/V4 recovery, a short recording of availability restored/provider reintroduced plus reload should show the original tuple restored just like R1. These can append to R1; they need not duplicate replacement/reset sequences. Do not infer successful restoration solely from disabled-provider coverage.

## Decisions and collapse rationale

- Disabled, unavailable, missing: three stills because copy differs and missing has no activeEntry; one shared preservation/recovery story, plus the missing-entry replacement path. Keep snapshot.enabled=false distinct from local providerInstances enabled=false while snapshot is still true; helper tests cover that race without another static row.
- Automatic: cover both null with fallback and null with no providers; explicit unavailable saved selection must not be treated as automatic. Reset and effort pinning are separate recording assertions.
- Re-enable versus intentional replacement: preserve the old tuple in the first case, preserve the newly selected tuple in the second. Never auto-revert a deliberate replacement.
- All environments: cover uniform usable behavior using V1, uniform unusable using V2/V3/V4, mixed values with V6, and heterogeneous availability with V9/R5. Do not multiply every availability reason across every scope. The saved/displayed mismatch helper is a unit-level defensive proof, not an invitation to fabricate an impossible user journey.
- Providers and connection modes: Claude/Codex are enough to prove changed instance identity and effort ownership. A long custom display name may be substituted in V3 for wrapping stress without a new scenario. Local/remote use the same row; two environments in R5 prove destination-aware decisions. No new tunnel transport behavior is introduced.
- Evidence must distinguish actual result from expected result, and attach seed tuple, scope, dimensions/theme, base/head, persistence checks, and recording IDs. Existing helper tests are useful branch evidence but cannot replace interaction or layout proof. No tests were run in this audit.

## FRICTION

- No capture authorization in this pass: real-app setup, screenshots, recordings, server starts, and browser use are intentionally unexecuted. A later proof operator must have authorization and isolated state.
- Provider availability is a provider-snapshot field, not a general Settings toggle. Deterministic unavailable/missing/race fixtures may require isolated provider configuration or explicitly labeled transport injection; component harness evidence alone is insufficient for persistence and multi-environment behavior.
- All-environment presentation uses one representative's providers/settings, while selection validation loops selected targets and persistence runs through scoped planning. Availability heterogeneity can expose editable traits that reject on save. Record the behavior; escalate if the intended requirement is aggregate readiness.
- PR adds helper tests but no integrated rendering/interaction evidence. This matrix specifies remaining proof and does not assert the PR passes it.
- This pass reads the supplied diff and git objects only; no forge state, issue discussion, or CI state was fetched, and no PR registration/write was performed under the explicit no-forge-writes constraint.
