fix-codex-chat-3

Fix: codex chat regression — animations not rendering, scrollback duplicates animation frames

Metadata

Statusdone
Assignedagent-1117
Agent identityf51439356729d112a6c404803d88015d5b44832c6c584c62b96732b63c2b0c7e
Created2026-04-29T15:18:09.049685662+00:00
Started2026-04-29T15:18:38.829164276+00:00
Completed2026-04-29T15:58:37.670968473+00:00
Tagspriority-high,bug,tui,pty,regression, eval-scheduled
Eval score0.79
└ blocking impact0.85
└ completeness0.80
└ constraint fidelity0.70
└ coordination overhead0.85
└ correctness0.80
└ downstream usability0.78
└ efficiency0.85
└ intent fidelity0.64
└ style adherence0.85

Description

Description

Regression report from user 2026-04-29 afternoon. Codex chat in wg TUI:

  1. Real-time animations don't render — spinners / 'thinking...' indicators that worked a few commits ago no longer animate
  2. Scrolling up repeats the animation text — scrollback contains stacked copies of what should have been transient cursor-overwrite frames

User quote: 'codex chat is shitting the bed. it was fine before but scrollback didn't work. now it doesn't really show realtime animations as it used to a few commits ago? ugh. and then scrolling up is repeating the animation text???'

Likely root cause

Both symptoms = the same bug. Codex emits transient spinners using cursor-overwrite sequences (\r, cursor-up + line-clear, sometimes alt-screen). A correct terminal renders these in-place — the same line gets repainted, the OLD content does NOT enter scrollback.

The current behavior suggests our PTY emulator is treating each animation frame as a NEW row and pushing prior frames into scrollback. Visible effects:

  • Live: instead of one animating spinner, you see nothing or a stale frame because subsequent frames go below into scrollback (off-screen if the row falls below the viewport)
  • Scrolling: every frame is preserved as a separate scrollback row

Likely culprit commits (regression candidates)

Bisect against:

  • ab96a82fd (fix-codex-agent) — explicitly touched codex stream-event parsing in chat tab. May have changed how cursor-overwrite sequences are interpreted.
  • e18de347c (fix-pty-scrollback) — initial-render duplication fix. May have changed the scrollback-append logic such that transient lines are no longer recognized.
  • 2e11648ab (fix-wg-tui) — CPU fix. May have changed render cadence / event-driven flow such that animation frames are batched into scrollback append.

git log --oneline -10 -- src/tui/ should narrow this. Use bisect if needed.

Repro

  1. pkill -f "wg tui" && wg tui (fresh process on current binary)
  2. Open or create a codex chat
  3. Send any prompt that triggers codex to show its 'thinking' spinner (e.g. ask it a substantive question)
  4. Observe: spinner doesn't animate visibly (Bug 1)
  5. Wait for response, then scroll up through the chat
  6. Observe: scrollback contains stacked frames of what should have been a single in-place spinner (Bug 2)

Compare against: codex invoked directly in a normal terminal (without wg TUI). Spinner animates in-place; scrollback is clean.

Investigation steps

  1. Confirm regression range with git bisect against the user's repro
  2. Identify the change in the suspect commit that broke cursor-overwrite handling
  3. Ground-truth check: does our PTY emulator correctly handle:
    • \r (carriage return without newline → return cursor to column 0, do NOT scroll)
    • \x1b[A (cursor up)
    • \x1b[2K (erase line)
    • DEC mode 2026 (codex's batched-render synchronization protocol)
  4. Compare with native codex CLI byte capture (the diagnose-scrollback-corruption task already produced /tmp/codex-tui-long.bin — reuse it)

Validation

  • Failing test written first (TDD): replay codex's spinner-emitting byte sequence into the chat-tab emulator; assert the rendered scrollback has ONE spinner line, not N=frames
  • Live smoke: open codex chat, ask a substantive question, observe spinner animates in-place; scroll back, observe scrollback contains the response (not stacked spinner frames)
  • No regression of fix-pty-scrollback / fix-tui-pty / fix-codex-agent original repros — verify those repros still pass
  • If git bisect points at one specific commit, the fix should preserve that commit's intent while restoring cursor-overwrite handling
  • cargo build + cargo test pass
  • Permanent smoke scenario added: replay a known cursor-overwrite byte stream, assert the resulting cell grid + scrollback are correct (no stacked frames)
  • cargo install --path . was run before claiming done

Process note

This is the FIFTH PTY-related fix in 24 hours (fix-tui-pty, fix-pty-scrollback, fix-codex-agent, fix-scrollback-reflow, and now this). The recurring pattern strongly suggests our home-rolled PTY emulator is fighting state it shouldn't be tracking by hand. If this regression turns out to be hard to isolate cleanly, escalate by reopening the architectural reset path (replace-custom-pty was abandoned earlier; reopen it) — switching to alacritty_terminal or wezterm-term solves this entire class of bugs once.

Depends on

Required by

Log