# Issue 19530 — proof audit pass 1 capture matrix

Scope: [issue #19530](https://github.com/pingdotgg/t3code/issues/19530), [GitCafe PR #19553](https://git.cafe/pingdotgg/t3code/pulls/19553). Read-only source audit of the COMPLETE diff from `bb7783e295` to `367e9dfb3c8239ed40d4f92f4fbeaf835cab3e5f`, not just the contributor revision. The remote PR still reports contributor head `2171c5a5d0262f5d47f3a51cea1182473e4866d2`; the audited local implementation is not that remote head. Pass 1 defines proof requirements; it does not certify captures or merge readiness. No app/browser/server was launched and no capture was made.

## Capture contract

Every AFFECTED row below needs matched BEFORE `bb7783e295` / AFTER `367e9dfb3c` evidence at all FOUR combinations: 1440px light, 1440px dark, 390px light, 390px dark. Suggested fixed heights: 900px at 1440 and 844px at 390; use identical height, device scale, zoom, browser, sidebar/panel arrangement, fixture bytes, refs, settings, initial state and action sequence within each before/after pair. Capture full client context, selected base, whitespace toggle and totals; crop only as an additional aid. At 390px the thread-details popover may close when the diff opens: record the row, open comparison, then reopen details to show the matching result. Do not manufacture simultaneous visibility.

RECORDING means a still is insufficient. A single paired recording may cover several rows, provided an index gives timestamps for each row and settled endpoint; no need to duplicate footage. Endpoint stills can be extracted from recordings. A transition expected to fail on BEFORE must remain visible and labeled as the defect. Do not skip a before sequence because it fails. Record actual observed values, including unexpected ones, instead of editing them to the expected result. No evidence from the contributor head can substitute for the audited AFTER.

## Minimal fixture matrix

| ID | Affected render path / fixture | Required observation and AFTER oracle | Evidence |
|---|---|---|---|
| A1 | AFFECTED Changes row + branch panel: feature vs Automatic/main, saved default hide-whitespace=true, fresh session | Row +1/-0 and panel +1/-0; whitespace-only replacement hidden, added line visible. BEFORE row is +2/-1 while panel is +1/-0. Include loading-to-settled opening, not only endpoint. | RECORDING; four pairs |
| A2 | AFFECTED branch selector + remembered base: Automatic → alternate at HEAD → main/Automatic | alternate row +0/-0 and panel no net changes; main hidden +1/-0; revert works. Show selecting an actual alternate ref, not only a mocked HEAD query. | RECORDING; four pairs |
| A3 | AFFECTED session whitespace toggle on main: hidden → shown → hidden | Row and panel change together +1/-0 → +2/-1 → +1/-0; no saved-default change. | RECORDING; four pairs |
| A4 | AFFECTED reopen/navigation: choose alternate, close panel, open another right-panel surface, reopen via Changes row; navigate away/back | Remembered alternate survives; row +0/-0 before opening, branch comparison opens alternate +0/-0. Also repeat from Uncommitted selection: row represents remembered BRANCH base, never working-tree totals merely because Uncommitted was selected. | RECORDING; four pairs |
| A5 | AFFECTED saved-settings fallback and reload: fresh session with saved false, change saved true before any panel-toggle override; then toggle shown, change saved true, close/reopen, reload | With session null both follow saved setting (false +2/-1, true +1/-0). After explicit session shown, both stay +2/-1 despite saved true and panel remount; full reload clears only session override and follows saved true +1/-0. Existing base persistence remains. | RECORDING; four pairs |
| A6 | AFFECTED cross-thread/session scope: second idle thread on same fixture; different remembered bases per thread | Base is per environment/thread; whitespace override is shared for this browser session, including when switching threads/panel instances. Set first main and second alternate; shown whitespace yields first +2/-1, second +0/-0. Never start a provider just to create the second thread. | RECORDING; four pairs |
| A7 | AFFECTED mounted row freshness: panel closed; edit sample.txt externally, then return/focus; also status-identical workspace mutation against custom base | Show stale→fresh row and reopen matching panel. Restore exact fixture after each run. A completed-operation mutation must be a real operation that emits workspaceMutationId; external file write alone is not proof of that signal. Expected totals must be computed from the selected base and actual new file bytes. Cover mutation received while preview pending; see seeding limitations below. | RECORDING; four pairs |
| A8 | AFFECTED initial loading and no-data error fallback, then successful retry | With preview unresolved/no data row uses status (+2/-1 here), then +1/-0 on hidden-whitespace success. With no-data preview error, row keeps status; panel displays its real error/no-patch state. Retry restores agreement. No new row spinner/error is implemented. | RECORDING; four pairs |
| A9 | AFFECTED stale-data refresh/error | After a successful hidden +1/-0 preview, pending refresh and failed refresh may retain cached comparison totals. Show actual cache behavior and panel error treatment; do not assert no-data fallback for stale-data cases. Recover to matching fresh comparison. | RECORDING; four pairs |
| A10 | AFFECTED file-access pending/denied/regrant | Preview gated off; row uses status +2/-1, panel shows checking access or denied-file-access state. Regrant permits preview and row/panel settle +1/-0. Use isolated non-admin connection access; do not modify live credentials. | RECORDING; four pairs |
| A11 | AFFECTED DiffPanel Uncommitted whitespace path | Use a disposable working-tree edit with both whitespace-only and real changes; switch Branch↔Uncommitted, toggle whitespace and back. Uncommitted panel filters its own patch, row continues remembered BRANCH comparison. Do not require row to equal Uncommitted totals. Same shared session toggle must apply. | RECORDING; four pairs |
| A12 | AFFECTED DiffPanel completed-turn whitespace path and remembered branch reopen | With a genuine completed checkpoint containing whitespace + real change, select turn, toggle whitespace, close, click Changes. Turn patch filters correctly; row still uses remembered branch; clicking Changes opens remembered branch, not turn. Existing fixture has NO completed turn, so this row requires additional real seed or explicitly labeled harness evidence. | RECORDING; four pairs |
| A13 | AFFECTED complete file-stat vs older-server patch fallback | Current server files array totals; same valid diff with files omitted must produce identical row/panel totals. Empty files array is authoritative +0/-0; missing branch-range source falls back to status. Truncated preview with complete file stats must use full totals, not visible patch subset. Harness required for response shapes not emitted by current server; label each case. | STILL for settled response shapes; RECORDING if switching/resolving responses; four pairs |
| G1 | Guard: non-repository, missing gitCwd/project, toolbar/menu callers, draft with no open action | Changes row absent for non-repo or outer missing-cwd/project gate; a rendered row with no onOpenChanges is disabled. Toolbar/menu have no new row/query component. Not a new visual feature; source/unit proof is enough unless capture reveals regression. | No additional capture minimum |
| G2 | Guard: full/compact/essential density, inline/popover | Row markup is shared across all densities; height affects surrounding controls. Four-width/theme pairs cover inline and popover if actually reached. If 1440 layout falls back to popover, add one actual wide inline case; if height causes compact/essential, include those affected row presentations once, with same before/after dimensions. Resizing/opening is temporal. | RECORDING for extra presentation transitions; both themes for added affected presentation |

## Real application seeding and provenance

Reuse the EXISTING isolated worktree `.t3`, never `~/.t3/userdata`. Supplied seed: project `/tmp/issue-19530-repo`, project id `68f7d29e-2dd8-4b60-aad0-bcea734e762e`, thread `issue-19530-fixture`, environment `350a2b77-762e-4937-b14d-5d2d51ecab94`. Lead reports thread was created by the real `thread.create` command with no provider turn; audit did not independently query its DB. Server is stopped. The capturer, not this auditor, starts its isolated server under separately granted authorization.

Fixture source of truth: main sample.txt is `hello world\n`; feature sample.txt is `hello    world\nadded line\n`; alternate points at feature HEAD; working tree starts clean. Verify refs and bytes before EACH pair. Use the real UI comparison selector for main/alternate/Automatic, DiffPanel whitespace toggle for session override, existing Settings “Hide whitespace changes by default” for saved setting, and actual panel/thread navigation. Do not seed these by fabricating screenshots or inserting component markup. A clean browser session clears the new non-persisted whitespace override; preserve or intentionally clear existing per-thread base state according to the row being tested. Reuse stable auth privately; do not publish pairing tokens or local storage dumps.

For A6, create another idle thread through the existing app new-thread workflow or real orchestration `thread.create` command with the same project/model/runtime fields, no turn start. For A11, change only the disposable repository working tree using normal filesystem/git operations and record exact content and restore. For A12, a real checkpoint requires an actual completed turn/checkpoint via the normal orchestration path, or a copied stopped real thread with its checkpoint refs/repository available in isolated state. Merely inserting a turn record or calling create-thread does not produce this fixture. No provider turn is authorized by this audit request. If no real fixture exists, use a labeled component/query harness and report the integrated-app coverage gap.

For A7 status-identical mutation/in-flight ordering, A8/A9 deterministic pending/error, A10 grant changes and A13 old-server/source-omission shapes: prefer genuine app/server/access controls when available. If a query response is delayed/replaced, a store setter is called directly, or a mock adapter injects completion/mutation state, label it “HARNESS / INJECTED RESPONSE”, state exactly which boundary is simulated, and keep it separate from real-app proof. A browser network-offline toggle does not automatically prove the WebSocket query error path. Do not claim a harness validates transport, server event emission or real completed-operation sequencing. If deterministic real seeding is unavailable, the minimum matrix remains explicitly incomplete until the lead accepts the documented harness substitution.

## Source derivation / scope exclusions

- `ChatView.tsx` passes workspaceMutationId → `ThreadDetailsPanel.tsx` → panel-mode `GitActionsControl` → new `ThreadChangesControl`. No new row in toolbar/menu. Row props/DOM styling are unchanged; totals/query source changes.
- `selectThreadDiffPanelBaseRef` uses current branch base, otherwise remembered branch base. `useRightPanelActions.addDiffSurface` calls selectGitScope(branch), which restores that remembered base. Hence A4/A12 must compare the branch the row OPENS, not the currently selected turn/Uncommitted scope.
- `DiffPanel.tsx` and row resolve session ignoreWhitespace ?? saved diffIgnoreWhitespace. Session store is not persisted. DiffPanel applies it to branch previews, working-tree previews, lazy file patches and checkpoint queries. Saved default is true. A5/A6 cover the wider shared lifetime introduced by this diff.
- `resolveChangesTotals` chooses branch-range files statistics (including empty arrays), otherwise parsed patch, otherwise branchChanges ?? workingTree. Query data can remain cached on refresh/error; no explicit new row loading/error UI. A8–A10 distinguish these paths.
- Four width/theme variants cover changed colored numeric totals, patch differences, responsive popover and inline placement. Unified/split and word-wrap have no changed layout implementation; one existing default suffices, with a spot check if a captured layout obscures totals. Binary/large-count typography is unchanged, so no extra binary/999+ fixture beyond truncated complete-stat fallback.
- Web local and remotely connected web use this same component/query contract. Electron reuses web; include a desktop smoke only if claiming Electron verification (shell chrome itself is unchanged). No changed mobile native row, server, contract or provider adapter; iOS/Android and six-provider Cartesian captures are out of scope. 390px WEB is not native-mobile verification. OS light/dark system preference is adequately covered by explicit light/dark rendering; no changed platform branch warrants macOS/Windows duplicates.
- No new settings, storage key, migration, docs or persistence requirement is part of this issue. Existing base persistence remains; whitespace is session-only.

## Existing evidence and pass-2 gate

Lead-supplied main reproduction images are prior BEFORE evidence, not audited pairs for this matrix:
[main reproduction 1](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a46671eea4b95777/browser-screenshot-localhost-mvmb36uf-d3acc02a.png), [main reproduction 2](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/12f1bd9270f28710/browser-screenshot-localhost-mvmb395j-e32bdadd.png).

Pass 2 must inspect actual image/video outputs, commit/data provenance and timestamp index, and mark every affected row covered, substituted-by-labeled-harness, or missing. Existing stills cannot establish base selection, toggle, reopen, refresh, settings precedence or loading/error ordering. No visual PASS is issued at pass 1.

## FRICTION

- No captures were requested from this auditor and none were made; all visual results remain unverified.
- The seeded idle thread cannot exercise completed-turn diffs; A12 requires additional fixture provenance or a disclosed harness gap.
- Current-server UI does not offer an older-server response-shape selector; A13 fallback cases require labeled harness/compatible server evidence.
- Deterministic in-flight mutation, pending/error, and permission transitions cannot be inferred from endpoint stills; A7–A10 need recordings and explicit real-vs-injected provenance.
- The remote PR description/head covers an older base-only implementation and explicitly excludes session whitespace; it must not be used as the description/evidence of this audited local head.
- Read-only audit ran `git diff --check` successfully. No test suite was run: this is the requested proof-plan audit, not a replacement for the lead's regression verification.
