fix(chat): recover transcript rendering through upward scroll and received folds

Merged
TE
5d ago
+971-146

Problem and behavior

Leo: "Sometimes it's literally impossible to scroll upwards because it keeps trying to re-render or strema or recalculate or whatever the f***" and "Like sometimes it just misses the f***ing render". He also reported gaps after a received card collapsed while streaming.

A stale queued scroll frame previously starved virtualization while the physical offset kept moving. Recovery now commits the live offset, preserves reader intent through the parent callback, and reads current intent in the RAF commit, including an upward release before the browser's default moves scrollTop. Fractional logical row coordinates and a bounded CSS origin preserve painted anchors when WebKit rounds physical writes. Rounded bottom-follow placement retains that residual even when no physical write is necessary. Row placement separates the integer CSS top from its fractional margin so WebKit does not lose subpixel precision at large transcript offsets.

Published history was merged, not rebased. The latest merge incorporates base 49bc1052b5c; current head is b2e7786e9aa25079df68e1a923925372bea9ed3b. The merge repair retains base's Add Credits action, composer Search chats/Search pages commands, and parked-reader input guard with its regression test. The receipts below explicitly identify their tested heads. The two App.tsx conflicts retain base's live-only turnsEnded state and viewerImages helper, including completed tool media. Base's unified scaled-row sizing, find placement, jump-button hysteresis, retry behavior, scroll-direction fallback and /btw reservation remain present. No new O(rows) work per token is introduced. The existing pacer cancels on unmount; the origin resets for explicit navigation/session/send/jump paths. Test frame callbacks stop after their bounded observations and pages close in finally.

The change stays together because reader intent, logical scroll coordinates, painted row placement and restoration share one scroll state machine. Most added lines exercise that behavior across browser and DOM fixtures; splitting those fixes would leave intermediate states with inconsistent coordinates.

A red/green remote comparison reproduces a 0.03125px seam on the old CSS placement at offset 636,244px, measures zero seam across the same 64 samples with the fix, and passes all six cases with the fix. A deterministic browser regression sweeps 64 measured fractional heights at row offsets above 500,000px and checks adjacent painted boxes before and during a real received-card expansion. The received-fold regression now uses the real disclosure selector and verifies all four painted expanded-state transitions. An earlier obsolete selector silently skipped the clicks; that earlier result is not fold evidence. The oracle keeps every observation, checks viewport coverage as well as adjacent row boxes, and retains the strict 1/64px drift/adjacency threshold.

Performance

The original harness from 40854836981 was rerun with only before_ref changed to merged base f08643f01708db3637bc9bd2b2ca0d606bf02264. Runs 41124967649, 41130554342, 41130579745 and 41131308024 compare that base with 89cfa2c9ff486120b6e22f16d4f9253b54ee5d77 sequentially on the same harness and runner class: WebKit 9,000 rows / 240 upward inputs / 264 painted observations, then Chromium's 10-second stream and CDP response probes.

MetricBeforeAfterDeltaHarness or run
WebKit blank frames / 26400+0Paired run
WebKit edge-band frames / 26400+0Paired run
Comparable upward frames264264+0Paired run
Maximum upward anchor drift42.5px0px-42.5pxPaired run
Chromium Runtime.evaluate p5033.846ms34.581ms+0.735msPaired run
Chromium Runtime.evaluate p95 (3-repeat mean; spread)41.986ms (39.853–45.602)45.139ms (38.571–50.732)+3.153msRuns 41130554342, 41130579745, 41131308024
Chromium Runtime.evaluate p9970.29ms72.726ms+2.436msPaired run
Chromium Runtime.evaluate maximum546.799ms545.703ms-1.096msPaired run
Responses >=100ms11+0Paired run
Stream detached frames00+0Paired run
Stream dropped frames (3-repeat mean; spread)165 (122–191)175 (124–221)+9Runs 41130554342, 41130579745, 41131308024

The after traces have zero upward drift and blank frames. The three-repeat p95 and dropped-frame results vary substantially run to run: p95 deltas were +5.130ms, -1.932ms and +6.260ms, while dropped-frame deltas were +30, +2 and -4. This spread does not establish a consistent regression. CDP maximum response still exceeds 100ms, and these probes do not establish input-to-paint or per-token commit latency. Native CEF proof remains tracked separately in #26809.

Verification and review

  • Current-head affected tests at b2e7786e9aa25079df68e1a923925372bea9ed3b: 45 passed, 0 failed across 11 isolated files, run 41140896641. Includes the restored parked-reader shrink regression, upward browser anchoring, received folds, follow, fling, parked streaming, restoration, scroll coordinate/pacer units, and access actions. The receipt's source tree a5f9f56950f3f319bcb4a66355663eaf3fd00069 exactly matches the pushed head; command exit code 0.

  • Current-head different-model delta review (b2e7786e9aa25079df68e1a923925372bea9ed3b, gpt-6-astra high): SHIP, visual PASS, verdict. The review found no blocking defect; its optional observation is that the streaming oracle could also report negative row gaps (overlap). The separate fractional-height oracle already checks absolute adjacency.

  • Historical affected tests at 89cfa2c9: 137 passing tests across 19 files. 41124952199 passed the first six files (45 tests), including tool media, snapshot saving, restoration and rails, then stopped at turn navigation. 41125622750 passed all 13 remaining files (92 tests), including turn navigation, upward anchoring, received folds, selection, follow, parked streaming and coordinate units. Both receipts match head tree b191a70ef2badb0722a48387736afd6a62f7ffa3.

  • The initial Previous Turn and Next Turn step the transcript through its prompts failure was expected 1 / received 0. The same test and error reproduced on merged base in run 41125622750; the head retry passed. A fixture-aligned bounded repeat in 41127102157 ran the identical current test three times on each tree: base failed 2/3 and passed 1/3; head failed 2/3 and passed 1/3 with the same error, classifying it as baseline intermittent. The follow suite includes base's repaired touch target without an exclusion. Each file runs in a fresh Bun process to avoid shared test globals.

  • Historical broad isolated transcript run 41102208952: 66 of 67 files passed. Its sole failure asserted raw physical restoration (1600 vs 1599); the corrected test checks exact logical placement, bounded residual and the actual CSS origin. It is included in the 89cfa2c9 run above. This historical run predates the base merge and is not an exact-head receipt.

  • Historical different-model delta review at 89cfa2c9: SHIP, verdict.

  • Surface spec: leo-workspace/design/chat-transcript.md. Received-card expansion, grouping and reader intent remain intact.

I viewed the before and after synthetic screenshots: the after transcript has continuous legible rows with no visible blank viewport band or overlap. Still images do not establish subpixel drift; the painted trace does.

Before
After

Agent session: agent session

Viewed after image: https://raw.githubusercontent.com/manaflow-ai/cmux/pr-media/27365/after-upward-89cfa.png