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
The v0.4.7 [launch-dims] instrumentation caught the production launch-resume corruption in the act, and it is not a width-estimate bug. The resume forks were correct — resume-on-launch fork: … size=199x59 source=caller-supplied — and the whole 0038 dims pipeline worked as designed. What destroys the terminal afterwards is a storm of cols-gate ring purges: for claude-code every cols change purges the entire output ring (runtime_clears_on_resize, no coalescing), and post-launch geometry churn produces dozens of cols changes in seconds. Each purge drops everything — including the resume transcript claude just repainted — and after the storm claude's SIGWINCH repaint restores only its recent frame. Net effect: a resumed claude-code pane with no scrollback and, mid-storm, visibly wrong rendering.
From ~/Library/Logs/com.wycstudios.runner/runner.log, one restart at 08:59–09:00 (2026-07-29), ~50 purges in 90 seconds across three claude-code sessions:
No coalescing on the purge. The smooth up-then-down sweeps (174→…→209→…→174) are live-drag geometry; every intermediate width purges the full ring and forces a claude repaint. A single sidebar/window/gutter drag obliterates scrollback dozens of times, and the final width often equals the starting width — the entire storm was for nothing.
A transient garbage fit gets pushed. Session 01KXHY1Q… (steady-state ~209 cols) got a first-fit of 78×23 from a not-yet-settled container, and that measurement was pushed to the PTY — purging the ring (205 → 78) and making claude repaint mis-wrapped at 78 cols before geometry corrected.
Why this always read as "production-only": it is layout-churn-dependent, not build-dependent. The dev profile's smaller tab/split/window state produces one clean fit and at most one purge at launch; the production profile's restored multi-tab layout produces transitional containers and churn. Five prior fixes (0027, 0035, 0037, 0038, #365) targeted the fork width, which this log shows was already correct.
Supersedes the mechanism theory in #366 (its estimate-mixing claim was already disproven in the comment thread; the estimate path is now verified working by this log). Related: #313 (defect 3 is the same class), #306 / impl 0020 (why the purge exists at all).
Expected behavior
A continuous drag (window edge, sidebar, chat panel, split gutter) results in one purge and one repaint at the final width — not one per intermediate width.
A measurement from an unsettled or transitional container is never pushed to the PTY.
Exactly one surface — the visible owning pane — pushes sizes for a session; a background/hidden mount never fights it.
After a launch with auto-resume, a claude-code pane retains the transcript its resume repaint produced.
Steps to reproduce
Production profile with several chat tabs (including splits) and running claude-code sessions; quit and relaunch with auto-resume on.
Watch ~/Library/Logs/com.wycstudios.runner/runner.log: cols-gate purge storms fire during launch settling without any user input.
Or, at steady state: drag the sidebar or a split gutter across a claude-code pane — one purge per intermediate width; scrollback gone at the end of the drag.
Relevant code
src-tauri/src/session/manager/output.rs:538-546 — the cols-gate: compares last_pty_cols, purges immediately per change; no quiescence.
src-tauri/src/session/manager/output.rs:796 — runtime_clears_on_resize (claude-code, codex, qoder, trae all affected; claude-code hurts most because its repaint restores only the recent frame).
src/components/ChatPaneGroup.tsx — hidden-pool wrappers whose geometry sync is the likely source of transitional boxes and the second writer.
docs/impls/archive/0024-resume-scrollback-preservation.md decision 5 — accepted resize-purge behavior on the assumption resizes are rare and user-driven; the log falsifies that assumption at launch.
Suggested fix
Fix the churn, not the purge semantics — given genuinely stale-width bytes, purging remains correct (impl 0020 / #306).
Trailing-debounce the PTY resize push (~150–200ms quiescence, frontend or backend): a drag collapses to one ioctl, one purge, one repaint. Skip the purge entirely when the settled cols equal the ring's current cols (round-trip drags become free).
Settle-gate the first fit: do not push a measurement taken while the pane's container is transitional (mid-hydration, hidden-pool geometry not yet synced); the existing windowSettle/layout-hydration signals mark when a box is trustworthy.
Description
The v0.4.7
[launch-dims]instrumentation caught the production launch-resume corruption in the act, and it is not a width-estimate bug. The resume forks were correct —resume-on-launch fork: … size=199x59 source=caller-supplied— and the whole 0038 dims pipeline worked as designed. What destroys the terminal afterwards is a storm of cols-gate ring purges: for claude-code every cols change purges the entire output ring (runtime_clears_on_resize, no coalescing), and post-launch geometry churn produces dozens of cols changes in seconds. Each purge drops everything — including the resume transcript claude just repainted — and after the storm claude's SIGWINCH repaint restores only its recent frame. Net effect: a resumed claude-code pane with no scrollback and, mid-storm, visibly wrong rendering.From
~/Library/Logs/com.wycstudios.runner/runner.log, one restart at 08:59–09:00 (2026-07-29), ~50 purges in 90 seconds across three claude-code sessions:Three distinct defects are visible:
174→…→209→…→174) are live-drag geometry; every intermediate width purges the full ring and forces a claude repaint. A single sidebar/window/gutter drag obliterates scrollback dozens of times, and the final width often equals the starting width — the entire storm was for nothing.01KXHY1Q…(steady-state ~209 cols) got a first-fit of 78×23 from a not-yet-settled container, and that measurement was pushed to the PTY — purging the ring (205 → 78) and making claude repaint mis-wrapped at 78 cols before geometry corrected.76 → 209 → 76 → 210oscillation is two surfaces alternately pushing different sizes for the same session, each flip purging again — the bug: two windows on the same chat — terminal size state desyncs across primary flips (stale lastPushed dedupe, dual-primary push race, wrong-cols replay) #313 desync class appearing in a single-window launch.Why this always read as "production-only": it is layout-churn-dependent, not build-dependent. The dev profile's smaller tab/split/window state produces one clean fit and at most one purge at launch; the production profile's restored multi-tab layout produces transitional containers and churn. Five prior fixes (0027, 0035, 0037, 0038, #365) targeted the fork width, which this log shows was already correct.
Supersedes the mechanism theory in #366 (its estimate-mixing claim was already disproven in the comment thread; the estimate path is now verified working by this log). Related: #313 (defect 3 is the same class), #306 / impl 0020 (why the purge exists at all).
Expected behavior
Steps to reproduce
~/Library/Logs/com.wycstudios.runner/runner.log:cols-gate purgestorms fire during launch settling without any user input.Relevant code
src-tauri/src/session/manager/output.rs:538-546— the cols-gate: compareslast_pty_cols, purges immediately per change; no quiescence.src-tauri/src/session/manager/output.rs:796—runtime_clears_on_resize(claude-code, codex, qoder, trae all affected; claude-code hurts most because its repaint restores only the recent frame).src/components/RunnerTerminal.tsx—pushSize/ ResizeObserver path that forwards every fit, including the transient 78×23 one; first-fit logging added in fix(mission): size backend-started forks and log launch widths #372 marks the push site.src/components/ChatPaneGroup.tsx— hidden-pool wrappers whose geometry sync is the likely source of transitional boxes and the second writer.docs/impls/archive/0024-resume-scrollback-preservation.mddecision 5 — accepted resize-purge behavior on the assumption resizes are rare and user-driven; the log falsifies that assumption at launch.Suggested fix
Fix the churn, not the purge semantics — given genuinely stale-width bytes, purging remains correct (impl 0020 / #306).
Environment