Skip to content

fix: pr-bug-scan validated finding from #6319#6376

Open
buf0-bot[bot] wants to merge 1 commit into
mainfrom
bot/pr-bug-scan-6319-1782415970
Open

fix: pr-bug-scan validated finding from #6319#6376
buf0-bot[bot] wants to merge 1 commit into
mainfrom
bot/pr-bug-scan-6319-1782415970

Conversation

@buf0-bot

@buf0-bot buf0-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Automated fix-PR from pr-bug-scan for parent #6319.

Fixer status: FIXED_WITH_CODE_PROOF
Summary: Gated pinned-viewport re-pin on output writes to only correct downward auto-follow drift, not chase a stale absolute target down after a scrollback-cap trim.
Blocked proof link: src/renderer/src/lib/pane-manager/terminal-scroll-intent.ts:220-221 (scrollToLine(X) on a trim-decremented viewport) is now blocked: enforceTerminalWriteScrollIntent skips the re-pin when fromOutputWrite and current.viewportY < targetY
Typecheck: skipped

Proof (from validator)

  • C1 — proof_type: code_analysis
    • trigger: User wheels up in a visible normal-buffer terminal (sets pinnedViewport via markTerminalPinnedViewport) and reads scrollback while sustained PTY output streams in after the scrollback buffer is full (at its line cap).
    • observable: While pinned reading scrollback under heavy streaming at the scrollback cap, the visible content drifts/jumps downward toward the live bottom on every write batch by the number of pruned lines, instead of remaining on the pinned content — eventually losing the user's reading position.
    • path:
      • src/renderer/src/lib/pane-manager/terminal-scroll-intent.ts:onWheel (deltaY<0) calls markTerminalPinnedViewport -> stored intent kind='pinnedViewport'
      • src/renderer/src/lib/pane-manager/pane-terminal-output-scheduler.ts:631 writeForegroundTerminalChunkWithIntent calls captureTerminalWriteScrollIntent(terminal) -> snapshot.viewportY = X (absolute ydisp before write), kind='pinnedViewport'
      • node_modules/@xterm/xterm/src/common/services/BufferService.ts:83 willBufferBeTrimmed = buffer.lines.isFull (true at cap); line 106-108: with isUserScrolling true, buffer.ydisp = Math.max(buffer.ydisp - 1, 0) per scrolled line while ybase stays at cap — keeps displayed content stable
      • src/renderer/src/lib/pane-manager/pane-terminal-output-scheduler.ts:635 onParsed -> enforceTerminalWriteScrollIntent(terminal, snapshot)
      • src/renderer/src/lib/pane-manager/terminal-scroll-intent.ts:219 targetY = clampViewportY(snapshot.viewportY=X, current.baseY=cap) = X; line 220-221 current.viewportY (X-N) !== X -> terminal.scrollToLine(X)
      • node_modules/@xterm/xterm/src/common/CoreTerminal.ts:218 scrollToLine issues scrollLines(+N), moving the viewport down by the pruned line count; positive disp keeps isUserScrolling true (BufferService.ts:141) so it repeats each batch

Reproduction

pnpm exec vitest run --config config/vitest.config.ts src/renderer/src/lib/pane-manager/terminal-scroll-intent.test.ts -t "does not chase a stale absolute viewport down"

  • before fix: scrollToLine called with the stale absolute line (viewport dragged toward live bottom)
  • after fix: scrollToLine not called; viewport stays on trim-stabilized pinned content

Generated by pr-bug-scan (proof-machine architecture). Human approval required before merge.

Gated pinned-viewport re-pin on output writes to only correct downward auto-follow drift, not chase a stale absolute target down after a scrollback-cap trim.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants