718fb5320c6e444490ce6c523a8fe563cf8621f7
Scrolling up emptied the screen and only reopening the session brought it back. The guess for an unmeasured row's height was re-derived from a running average each time it was wanted, and that average moves as rows are measured -- so the height a spacer had been *built* at stopped matching the height the running totals were adding up, and the two drifted apart. Once they differed by more than the retain window every row failed the distance test at once, and a transcript of nothing but spacers has nothing left to measure and so nothing to correct itself with. Two changes, and the second is the one that matters. A guess is now made once per row and kept, so it cannot drift from what was built with it. And which rows stay built is decided as a *range* rather than by each row testing itself: the row nearest the viewport is in that range by construction, whatever the arithmetic says, so the worst a mistake here can do is build too few rows or too many. A blank transcript is no longer a state this can reach. That is the shape worth keeping from the bug. Every row answering independently meant one wrong number could stand all of them down together, and the failure was silent, self-sustaining, and looked exactly like the screen having nothing to show. Checked by scrolling sixty swipes to the oldest loaded end and back -- the content holds throughout. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Languages
Rust
54%
Kotlin
43.6%
Shell
2.4%