Context
Found during the 2026-08-22 TUI vertical-jitter forensics (follow-up to #1064; the primary status-dock fix ships separately). This is an independent vertical-motion path for resumed / post-compaction transcripts, NOT the cause of the captured turn-boundary jitter.
Mechanism (HEAD 98234d1)
12d771dbc (perf(coding-agent): render resumed transcripts progressively) introduced progressive transcript hydration:
packages/coding-agent/src/modes/interactive/components/progressive-transcript-container.ts:76-96 renders from hydratedFrom to the tail.
:142-176 warms a head chunk per setImmediate and moves hydratedFrom BACKWARD after every chunk.
- Any unrelated assistant/tool render between chunks calls
render() and exposes the newly lowered watermark, inserting a warmed batch ABOVE already-painted tail content -> painted content moves vertically in multiple geometry-changing batches while the user watches.
Affects resumed sessions and compaction rebuilds whose history exceeds the tail budget.
Proposed fix (preserves the perf intent)
Split warming state from visible state:
- Keep
warmedFrom for background cache population (Markdown work stays spread across bounded macrotasks).
- Keep
visibleFrom fixed at the initial tail boundary while warming is incomplete; unrelated live renders keep painting visibleFrom..total including appended live children.
- When
warmedFrom reaches zero, atomically set visibleFrom = 0 and issue the existing single completion render (one atomic height increase).
Failing-first proof
Deterministic case for packages/coding-agent/test/suite/progressive-transcript-container.test.ts:
- Populate more children than
tailBudget.
- Render once; record the first visible component index.
- Await exactly ONE
setImmediate (one warm chunk completes, hydration unfinished).
- Append one live component; render again.
- Assert the first visible index is unchanged and the live component is at the tail.
Current HEAD fails: warmNextChunk() has already lowered hydratedFrom, so the second render starts one chunk earlier. No sleeps needed.
Risk notes
Medium: the final full-history reveal remains one atomic height increase and may still trigger one main-screen scrollback replay; verify resume, compaction rebuild, append-during-hydration, clear/dispose cancellation, and full transcript output.
Context
Found during the 2026-08-22 TUI vertical-jitter forensics (follow-up to #1064; the primary status-dock fix ships separately). This is an independent vertical-motion path for resumed / post-compaction transcripts, NOT the cause of the captured turn-boundary jitter.
Mechanism (HEAD 98234d1)
12d771dbc(perf(coding-agent): render resumed transcripts progressively) introduced progressive transcript hydration:packages/coding-agent/src/modes/interactive/components/progressive-transcript-container.ts:76-96renders fromhydratedFromto the tail.:142-176warms a head chunk persetImmediateand moveshydratedFromBACKWARD after every chunk.render()and exposes the newly lowered watermark, inserting a warmed batch ABOVE already-painted tail content -> painted content moves vertically in multiple geometry-changing batches while the user watches.Affects resumed sessions and compaction rebuilds whose history exceeds the tail budget.
Proposed fix (preserves the perf intent)
Split warming state from visible state:
warmedFromfor background cache population (Markdown work stays spread across bounded macrotasks).visibleFromfixed at the initial tail boundary while warming is incomplete; unrelated live renders keep paintingvisibleFrom..totalincluding appended live children.warmedFromreaches zero, atomically setvisibleFrom = 0and issue the existing single completion render (one atomic height increase).Failing-first proof
Deterministic case for
packages/coding-agent/test/suite/progressive-transcript-container.test.ts:tailBudget.setImmediate(one warm chunk completes, hydration unfinished).Current HEAD fails:
warmNextChunk()has already loweredhydratedFrom, so the second render starts one chunk earlier. No sleeps needed.Risk notes
Medium: the final full-history reveal remains one atomic height increase and may still trigger one main-screen scrollback replay; verify resume, compaction rebuild, append-during-hydration, clear/dispose cancellation, and full transcript output.