Files
brain-of-reese/.agent/phases/todo/43_thinking_scroll_back/00_phase.md
T
ducoterra 02c76ad328 chore(agent): phase roadmap from TODO.md — 8 phases (40–47), 24 tasks
Converts the 9 TODO items into an executable phase roadmap (Protocol B,
appended after phase 39):

- 40 tuning toggle anonymous flash (TODO L3)
- 41 sync fail-fast + modal when a model is down (TODO L4)
- 42 no reply autoscroll (TODO L5)
- 43 thinking scroll back — user scroll + gated autoscroll (TODO L7)
- 44 markdown tables (TODO L6)
- 45 agent unlimited tool calls behind BOR_AGENT_MAX_ROUNDS (TODO L8)
- 46 mobile hamburger nav (TODO L9)
- 47 quadlet + jinja import formats, A9 revision (TODO L10–L11)

Each phase carries a user story, a dedicated Playwright E2E suite plan,
and owner-locked decisions (R1 A9 format extension, R2 phase-37 budget
revision, A1–A5 scope decisions) confirmed 2026-08-27.

Also records the completed phases 30–39 todo/ -> complete/ moves that
were pending in the working tree. TODO.md is cleared (items now live in
.agent/phases/todo/).
2026-08-27 18:25:53 -04:00

3.8 KiB

Phase 43 — Thinking scroll back (user scroll + generate-time autoscroll)

Source: TODO.md L7 — "Add scrolling back to the thinking block, but have it autoscroll while thinking content is generating." Story: .agent/user_stories/thinking-scroll-back.md Context: Phase 17 streams reasoning into the collapsible .thinking block with a per-chunk bottom-pin (textEl.scrollTop = textEl.scrollHeight in the thinking SSE handler). Phase 21 (owner choice 2026-08-24) made .thinking-text a no-scroll live tail: overflow-y: hidden (the JS pin is the sole scroller). The owner now reverses phase 21: the window is user-scrollable again, and the pin becomes gated — follow the tail only while the user is pinned near the window's bottom. This is the window-level successor of the phase-18 pattern (the page-level one is removed in phase 42, which runs first and touches the same thinking handler line — order matters).

Objective

The Thinking block follows its live tail while reasoning is generating and the user is at the bottom; a scrolled-up user is never yanked down, and returning to the bottom resumes following.

Dependencies

  • 42_no_reply_autoscroll (todo) — must run first: it strips the page-level scroll from the same thinking handler; this phase then reworks the window pin in the cleaned-up handler.
  • 17_thinking_display (complete) — the block, the pin, the auto-collapse on first delta.
  • 21_thinking_no_scroll (complete) — the overflow-y: hidden + 320px window being reversed (the 320px clip is kept).

Tasks

  1. 01_window_user_scrollable.md — CSS: overflow-y: auto back, comment replaced (owner direction 2026-08-27).
  2. 02_gated_bottom_pin.md — app.js: THINKING_NEAR_BOTTOM_PX = 32 + gated pin; unit pin rewritten (phase-21 file replaced).
  3. 03_thinking_scroll_e2e_and_commit.md — replace the phase-21 E2E with the new-contract suite + regressions + commit.

Testing & Quality

  • Unit: tests/unit/test_thinking_no_scroll.py deleted, replaced by tests/unit/test_thinking_scroll.py — pins: overflow-y: auto + max-height: 320px in the .thinking-text rule; the 2026-08-27 owner-direction comment; export const THINKING_NEAR_BOTTOM_PX = 32; the pin is gated on isThinkingNearBottom(textEl) (no unconditional pin).
  • Coverage: frontend-only — app/ TOTAL unchanged, >90%.
  • E2E (mandatory, A16): tests/e2e/test_thinking_scroll.py, run in isolation. tests/e2e/test_thinking_no_scroll.py is deleted (behavior intentionally reversed).

Completion Criteria

  • Wheel/drag/keyboard move .thinking-text (frozen-tail state); computed overflow-y: auto, max-height: 320px.
  • While pinned at the window bottom: each chunk re-pins to the tail (±1px). Scrolled up: no re-pin across chunks. Return to bottom: following resumes.
  • Auto-collapse on first delta, reduced-motion stillness, answer-bubble scroll (phase 11), restored-collapsed block (phase 17) all unchanged.
  • uv run pytest green; coverage TOTAL unchanged.
  • uv run pytest tests/e2e/test_thinking_scroll.py -v --no-cov green in isolation (DB up).
  • Regression E2E suites green in isolation: test_thinking_display.py, test_chat_persistence.py, test_no_reply_autoscroll.py, test_smoke.py.
  • uv run ruff check . && uv run pyright clean.
  • One --no-gpg-sign commit; phase dir moved to .agent/phases/complete/.

Locked decisions

  • Owner direction (2026-08-27, roadmap A2) reverses the phase-21 owner choice (2026-08-24): the window is user-scrollable again; autoscroll only while pinned near the bottom (32px band). The 320px clip is kept (owner-confirmed).
  • A15 unchanged — SSE contract untouched; pure client-side.
  • A16/A17 honoured — one story E2E suite (replacing the removed one), one atomic commit.