# Read-only audit, round 1 — [#15091](https://github.com/pingdotgg/t3code/pull/15091)

**Handoff: unfinished; do not publish the replacement yet.** Original head [aec2d97e389f](https://github.com/pingdotgg/t3code/commit/aec2d97e389f40a9041f7fa0398feaccb456ad92), `pingdotgg/t3code:t3code/fix-browser-focus-stealing`, author bmdavis419, targets `main`. Local replacement `terminal-preview-21/tab-focus` is `bd08c54d0280` (unpublished) over `origin/main` [ab6be13d438a](https://github.com/pingdotgg/t3code/commit/ab6be13d438abeace7617e8d789d59cf2e880f42). Its entire diff is 17 test lines; no production fix. Original CI is green for its old head, which predates the current desktop route. Fresh feedback file and historical inline comments were read; the unresolved cross-tab comment is a design lead, not proof of a current bug.

## Confirmed source findings

1. **Blocking, replacement:** [GuestInput.ts](/home/ubuntu/wt/terminal-preview-21/apps/desktop/src/preview/GuestInput.ts:125) sends unfocused guest Tab/Shift+Tab as raw native `webContents.sendInputEvent` after a same-site focus probe. [DesktopBrowserHost.ts](/home/ubuntu/wt/terminal-preview-21/apps/desktop/src/preview/DesktopBrowserHost.ts:92) routes the page session there; child sessions bypass it. Neither the `Runtime.evaluate` reply nor the current renderer path is a focus guard or native traversal completion acknowledgment. The removed `PreviewAutomationHosts` press handler from the original PR cannot be transplanted as-is. This confirms *absence of the proposed protection*, not that the current native route reproduces the old boundary escape. The later direct-input change addresses focus-routed text going to the host; whether it also contains Tab at guest boundaries is unverified.

2. **Blocking if reusing original helper:** [original `previewTabFocus.ts` lines 91–106 and 133–146](https://github.com/pingdotgg/t3code/blob/aec2d97e389f40a9041f7fa0398feaccb456ad92/apps/web/src/components/preview/previewTabFocus.ts#L91-L146) releases when `press()` settles with `pendingTraversal=false`. Thus a first `focusout` *and* destination focus arriving after the reply are unguarded. If `focusout` arrives before reply, the guard remains and covers a later destination; the implementation report's broader “late focus after reply not covered” statement is too broad. The original tests create a synchronous `composer.blur()` before the late focus, so they do not cover the first sequence. This is a deterministic control-flow gap under that event order, not a demonstrated Electron occurrence on the current branch.

3. **Tests are handoff markers only:** [GuestInput.test.ts lines 55–70](/home/ubuntu/wt/terminal-preview-21/apps/desktop/src/preview/GuestInput.test.ts:55) rejects raw native Tab and CDP fallback but never asserts page traversal. Dropping Tab entirely satisfies both cases. They usefully pin the unprotected route, but are too conservative to act as acceptance or to prescribe that `sendInputEvent` must be removed. The focused run recorded by the implementation agent has 115 existing passes and these 2 expected failures; I did not rerun it because neither source nor tests changed in this review.

## Design recommendation

First characterize the *current* desktop route in native Electron before declaring a new native containment primitive mandatory. Replay first/last Tab and Shift+Tab with the host composer focused, record guest and host focus events relative to the command reply, and check whether the direct guest `sendInputEvent` actually escapes. If current main already contains the boundary, retire this takeover and its red guards. If it escapes, place the smallest fix at the authoritative `DesktopBrowserHost`/`GuestInput` boundary, scoped to the attached guest and raw Tab dispatch. A pre-dispatch renderer acknowledgment plus a lifetime that handles a first late transition is a plausible small port to evaluate; a post-dispatch DOM refocus is not automatically disqualified, but it must pass native typing/caret/IME evidence. Avoid source-only claims that DOM refocus necessarily destroys IME, or that a native Electron hook is required. Likewise, `PickPreload.ts` reports trusted guest keydown as human and `Manager.ts` publishes `controller=human`, but whether injected `sendInputEvent` produces that trusted signal was not tested; do not use it as unambiguous physical provenance without checking. `HostedBrowserWebview.tsx` synthesizes pointerdown on guest focus, which must not count as physical takeover.

Acceptance for any rebuild: real Tab/Shift+Tab traverse guest controls and frames, including both page boundaries and a first focus event after the command reply; the host composer keeps text, caret/selection and active IME composition through repeated presses; host navigation and actual guest click/key takeover work; a different guest and hidden cross-chat preview cannot steal focus; cleanup follows navigation, remount, close and failure. Preserve explicit cross-site refusal for unsupported child-frame input. Use one or two behavior-focused tests at an observable dispatch/guard seam plus native acceptance, not the discarded 36-case helper suite or these two negative mocks alone. No headless DOM fixture or screenshot can establish native focus or IME behavior.

## Limits and state

I read both skills, AGENTS.md, the whole original diff, replacement diff, current caller/contract paths, fresh metadata and historical inline feedback, and the public PR page. No browser automation, native app, server, edits to the worktree, commit, checkout, push, PR body/comment or delegated work. Electron behavior and IME preservation remain unverified. Native display is unavailable in this environment, and the previous original PR's replay describes its old path, not this replacement. The original branch remains untouched; the replacement is local and incomplete.
