# Desktop SSH update proof

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

This is a real Linux x64 packaged Electron/AppImage update, recorded under
`headless-desktop`. No unit tests or mocked desktop services are used as proof.
The viewport is 1100 x 780, light theme, with a fresh T3 home on each side.
The observation band is added by the driver and reports measured OS process
and HTTP state. A local CLI filesystem path is masked in the first five seconds
of each recording. No other app behavior is edited in the captures.

The base is [b68aedfdb7](https://github.com/pingdotgg/t3code/commit/b68aedfdb71534bfdfbe55771ef2e686742faa8e),
the merge-base with main. The head is [043c040f3d](https://github.com/pingdotgg/t3code/commit/043c040f3d8c016586aaf972b61c19b5c9e5b830).

## Setup

1. Install dependencies in each checkout with `vp i`.
2. Build each commit as version 0.1.10:
   `node scripts/build-desktop-artifact.ts --platform linux --target AppImage --arch x64 --build-version 0.1.10 --mock-updates --output-dir <side-artifacts>`.
3. Build the head again as version 0.1.11 into a separate update directory.
4. Run `seed-local-ssh.py <scratch>` under an isolated account with no existing SSH
   config. Start `/usr/sbin/sshd -D -f <scratch>/sshd_config`.
5. Serve a local HTTP endpoint on 127.0.0.1:19468. Serve the newer AppImage and its
   generated `latest-linux.yml` on 127.0.0.1:19369.
6. Run each side with:
   `headless-desktop node prove-desktop.mjs <checkout> <side-AppImage> <new-run-directory> <commit>`.

The fixture uses a real OpenSSH server and real SSH local port forwards. The
server's forced command supplies synthetic remote-discovery output and an HTTP
server stands in for the remote T3 port, matching the triage reproduction.
Remote T3 installation, authentication, and pairing are outside this proof.
The saved connection has synthetic identity/credential data so the relaunched
client restores its SSH tunnel; the stand-in does not provide a working T3 session.

The local update feed is the repository's supported mock-feed configuration.
The actual Electron updater checks, downloads, installs, quits, and relaunches.
Linux AppImage updates do not need the signed production feed that blocked the
previous triage attempt. Both old applications update to the same head-built
0.1.11 payload.

## Interaction

The driver finishes onboarding without importing history, opens Settings/About,
and calls the real desktop SSH bridge. It observes the SSH child PID without
replacing the spawner, saves the synthetic connection through the desktop
connection-catalog IPC, and checks/downloads the update. It calls `installUpdate`
through the real preload IPC, the same handler used by the Install control.
It records the original desktop exit, SSH PID/parent changes, listeners, HTTP
responses, and the new forward created by the automatically relaunched app.
The app and fixture processes are stopped after capture.

## Observed

Base: original SSH PID 89147 was reparented from desktop PID 87696 to subreaper
1276 and kept forwarding on local port 45809 (HTTP 200). The relaunched desktop
PID 89273 created SSH PID 89605 on port 34485 (HTTP 200): two working forwards.

Head: original SSH PID 100590 on port 41151 was absent when desktop PID 99027
exited. The relaunched desktop PID 100691 created SSH PID 100985 on port 44149
(HTTP 200): one working forward.

`before-observations.json` and `after-observations.json` contain the measured
transcripts. Final stills use two identical screenshots taken 500 ms apart,
with a readable summary of those measurements appended below the app.
