# Dictation navigation proof

Run on Linux Chromium, 1280 × 800, light theme. Both app checkouts use their own fresh T3 home and synthetic git repository. The app server and web client are real. Replay (dev) supplies the agent responses. The microphone is a generated audio stream, and only the speech HTTP endpoints are stubbed with deterministic transcripts and a manually released response; no paid speech provider is required.

From each checkout, install dependencies with `vp i`, then start:

```sh
T3CODE_DEV_SEED=0 node scripts/scenarios/start-app.ts web "$PROOF_HOME" 127.0.0.1 "$WEB_PORT"
```

In another terminal, from the same checkout:

```sh
node seed.mjs "$PROOF_HOME"
node browser-driver.mjs "$PROOF_HOME" "http://127.0.0.1:$WEB_PORT" "$SIDE" "$OUTPUT_ROOT"
```

Keep `browser-driver.mjs` and `speech-fixture.js` in the same folder. `SIDE` is `base` or `head`. The driver creates a new timestamped output folder. Its observations JSON records exact message counts, the selected thread, B's draft, and focused element. Its video begins with browser pairing; trim it at the observations JSON's `safeStart` before sharing, to exclude pairing.

The driver uses Playwright's actual pointer and keyboard input. It never focuses Attach files. Voice configuration, cleanup consent, disabling voice input, and the destination change use Settings → Voice controls. The destination case selects OpenAI and saves a clearly synthetic API key in the isolated home; it makes no OpenAI request.

Each case starts with a separate pair of threads with identical seeded history on both commits. B receives `B draft — do not send`. In A the driver starts recording, confirms Send, waits for the held transcription or cleanup request, visits B, revisits A during processing, then returns to B before releasing the response. After completion it captures B, then A. Guard cases cancel in A, select Transcribe with → Off, turn off Clean up transcripts, or change Transcribe with from Scenario to OpenAI before release.
