You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix: remote Codex scrolling replays duplicate frames when history capture misses tmux #13
/terminal?full=1 degrades to source=mux-visible and returns ~572KB containing 62 copies of collect_node_topology and 81 copies of the prior prompt.
The new remote scrollback helper invokes tmux without the shared remote PATH bootstrap. Direct execution of its exact generated command returns stderr zsh:1: command not found: tmux and just two NULs on stdout. This is logged misleadingly as no such remote tmux session. The actual session exists and is readable with the normal bootstrap.
Fix remote history command PATH parity and verify capture does not replay raw redraw history; restore observed-tracking Codex scroll routing using authentic isolated evidence and regression tests. Never send test prompts or scroll reports into the user's active session.
Confirmed RCA and implemented 9eaefed0 on local branch fix/13-remote-codex-replay (/tmp/codeman-13-remote-codex-replay).
Two causes combine:
The remote scrollback helper omitted withRemotePathBootstrap, unlike launch/frame capture. The exact production-generated command returned zsh:1: command not found: tmux and only its two NUL delimiters; the fallback log incorrectly read “no such remote tmux session”. The live session exists under the stored remote name on codeman-remote.
The deployed frontend excludes Codex from native wheel forwarding even with observed mouse tracking. Both the local SSH wrapper and remote Codex pane report alternate_on=1, mouse_any_flag=1, history_size=0; local scrolling therefore exposes retained repaint frames instead of the CLI's native transcript.
The fix uses the shared PATH bootstrap for remote history reads and admits measured tracked Codex through the shared primary/tile/touch forwarding gate. Inline/untracked Codex, Shift/local-history opt-outs and native xterm routing remain as before. Metadata and docs now describe the observed behavior. No text deduplication is applied.
Evidence/verification:
Before: /terminal?full=1 fell back to mux-visible and returned ~572KB containing 62 script-name and 81 old-prompt occurrences. Direct SSH confirmed tmux was absent from the non-interactive PATH.
Patched reader, pointed read-only at the exact live remote pane: succeeded, historyBytes=0, screenRows=34, no occurrences of those old prompt/script strings. No prompt, wheel input, resize or process restart was sent to w1-hdai.
The Mac mini and isolated local CLI are both Codex 0.163.0. Fresh authentic native measurement: flags 1/1, one SGR Up moved first marker 60 to 59, Down restored the identical frame. Wheel input over a real approval prompt left its selected option unchanged and did not execute the command. Evidence: /tmp/codeman-13-native-evidence.json.
294 focused tests + 237 route tests passed (531 total, 1 existing skip); 4 browser checks passed across primary routing, tiles and touch paging. The browser routing test exercises the installed capture listener with only cell hit-testing and transport stubbed.
Typecheck, lint, format, lockfile, public assets, frontend syntax, browser exclusions and CLI catalogue check passed.
Realistic isolated Claude/Codex/shell smoke: 112 pass, 0 failures, 1 explicit unconfigured remote-host skip. All temporary sessions were deleted and servers stopped. Artifact: /tmp/codeman-dev-smoke-artifacts-2026-10-21T21-52-07-137Z-p4098695-r6e6c60a5b5664d26be7247729bbe7691/summary.json.
The bundled smoke initially exposed fixture issues: its awk command emitted literal backslash-n sequences, and its assertions expected markers older than the configured tmux retention after intentionally generating more than that limit. A temporary copy corrected the newline escaping and raised only the isolated fixture's tmux retention before session creation; all assertions then passed. Installed skill files and production settings were not changed.
Not merged, pushed or deployed. Production checkout remains clean on local at 05252ccc; service lifecycle and the user's active session are unchanged.
Merged 9eaefed0 into local, pushed to origin/local, built successfully and deployed to codeman-web.
Fresh production evidence:
Service active/running, HTTP 200.
w1-hdai retains its existing session ID and reports cliMouseTracking=true.
/api/sessions/33d9a0f4-47f1-43b0-af67-bf0278b3f090/terminal?full=1 now returns source=mux-full-history, 5610 bytes at 170×33, with zero occurrences of the reported old prompt/script text. Before deployment it returned source=mux-visible and ~572KB of repaint data.
Deployed-browser native routing regression passed, with production writes and terminal WebSockets blocked in the test browser. No test prompts or wheel reports were sent to the user's session.
Upstream PR Ark0N#645 is updated at 242bbfcd with the remote-history PATH fix/regression, a reusable helper suitable for upstream, and the latest review's rounding/comment/doc follow-ups. That exact branch passed 290 focused tests, 5 browser tests, full pre-push static checks, and isolated realistic smoke (108 pass / 0 fail / 5 documented skips). Fresh GitHub CI is running; PR is mergeable. Review response: Ark0N#645 (comment)
Production source stays on local at 9eaefed0, matching origin/local. Upstream's PR-only gesture helper rounding changes are on its separate branch; the fork's existing per-event normalization already rounds isolated coarse wheel events.
Activity
johoja12 commentedon Oct 21, 2026
Confirmed RCA and implemented
9eaefed0on local branchfix/13-remote-codex-replay(/tmp/codeman-13-remote-codex-replay).Two causes combine:
withRemotePathBootstrap, unlike launch/frame capture. The exact production-generated command returnedzsh:1: command not found: tmuxand only its two NUL delimiters; the fallback log incorrectly read “no such remote tmux session”. The live session exists under the stored remote name oncodeman-remote.The fix uses the shared PATH bootstrap for remote history reads and admits measured tracked Codex through the shared primary/tile/touch forwarding gate. Inline/untracked Codex, Shift/local-history opt-outs and native xterm routing remain as before. Metadata and docs now describe the observed behavior. No text deduplication is applied.
Evidence/verification:
/terminal?full=1fell back to mux-visible and returned ~572KB containing 62 script-name and 81 old-prompt occurrences. Direct SSH confirmed tmux was absent from the non-interactive PATH./tmp/codeman-13-native-evidence.json./tmp/codeman-dev-smoke-artifacts-2026-10-21T21-52-07-137Z-p4098695-r6e6c60a5b5664d26be7247729bbe7691/summary.json.Not merged, pushed or deployed. Production checkout remains clean on
localat05252ccc; service lifecycle and the user's active session are unchanged.fix(terminal): capture remote history and route tracked Codex scrolli…
johoja12 commentedon Oct 21, 2026
Merged
9eaefed0intolocal, pushed to origin/local, built successfully and deployed tocodeman-web.Fresh production evidence:
w1-hdairetains its existing session ID and reports cliMouseTracking=true./api/sessions/33d9a0f4-47f1-43b0-af67-bf0278b3f090/terminal?full=1now returns source=mux-full-history, 5610 bytes at 170×33, with zero occurrences of the reported old prompt/script text. Before deployment it returned source=mux-visible and ~572KB of repaint data.Upstream PR Ark0N#645 is updated at
242bbfcdwith the remote-history PATH fix/regression, a reusable helper suitable for upstream, and the latest review's rounding/comment/doc follow-ups. That exact branch passed 290 focused tests, 5 browser tests, full pre-push static checks, and isolated realistic smoke (108 pass / 0 fail / 5 documented skips). Fresh GitHub CI is running; PR is mergeable. Review response: Ark0N#645 (comment)Production source stays on local at
9eaefed0, matching origin/local. Upstream's PR-only gesture helper rounding changes are on its separate branch; the fork's existing per-event normalization already rounds isolated coarse wheel events.test(terminal): rename the Codex wheel browser test after what it drives