Evidence setup and reproduction

AI-assisted; verified with the tests and tools listed above.

Each side was built in its own detached worktree. Base: [d290c1f1b6](https://git.cafe/pingdotgg/t3code/commit/d290c1f1b6c93416dfda6c9f7cd15d928a9aeb4c). Head: [1c913c74b4](https://git.cafe/pingdotgg/t3code/commit/1c913c74b4b3051855d830f01297230169f1cc47).

Linux x64, Electron 44.10.1, production-mode desktop bundle version 0.1.8, headless-desktop, light theme, 1280x900 application viewport. A 42px evidence caption is added above the captured viewport. Both databases started fresh with T3CODE_DEV_SEED=0; no live database was copied, no history was imported, and no agent turns were run.

Build with vp i and T3CODE_DEV_SEED=0 vp run build:desktop, then node apps/desktop/node_modules/electron/install.js. The first side additionally needed libsecret-1-dev installed and the desktop pack and helper generation rerun after the initial helper build failed.

assemble.cjs stages the built application with the Electron runtime, a production application manifest, a generic update feed configuration, and links to that checkout's built assets and runtime dependencies. It does not replace application logic or the desktop bridge. Launch the staged runtime/t3code under headless-desktop with --no-sandbox --disable-gpu --remote-debugging-port=19202 for base or 19201 for head. Give each side its own T3CODE_HOME and XDG_CONFIG_HOME and set APPIMAGE to its staged executable. These are production-mode source assemblies, not downloaded signed releases or an installer build. A separate real server is launched from each side's own apps/server/dist/bin.mjs serve with its own --base-dir, on ports 18202 and 18201 respectively.

In each desktop, skip importing existing history. Open Settings > Environments, turn Local environment off, and choose Restart and turn off. Pair the separately managed server through Add environment using a fresh token minted by the real pair command. pair-driver.cjs performs that pairing UI interaction without publishing its token. Linux keyring prompts were resolved before evidence capture.

Recording begins with Settings > Environments showing Local environment turned off and the separate server Connected. driver.cjs then opens About, opens Update track, selects Nightly, and waits for the confirmation plan. It performs the same UI actions on both sides. Each still was accepted only after two screenshots 500ms apart were byte-identical. The driver reads the real confirmation button's enabled state, in addition to capturing it.

Observed: base confirmation is disabled and shows "This app cannot switch: its server is not connected, so its database cannot be checked." Head confirmation is enabled and that warning is absent. Both selected the same release, 0.1.9-nightly.20261110.4478, and both retained the separately managed server's skipped row.

No update download or installation was attempted. The generic updater's automatic startup check encountered ERR_CERT_DATE_INVALID. The registry lookup in the track-switch flow succeeded through the real connected server on both sides. Other remote database compatibility outcomes and additional hosted-server configurations were not exercised.

process.cjs redacts the environment's private machine label and the unrelated launcher path, adds captions, and encodes the captured JPEG frames into MP4 with their original timing. Redaction rectangles are derived from the actual UI. During the confirmation dialog, only the exposed background portion is masked; the warning and button are unchanged. Every still and decoded recording was visually reviewed before upload.
