Summary
tests/bench/vendor/hybrid_bench.js (the benchmark's hybrid arm — warm-band detach over cold-tail eviction) under-reports the height of unrendered history in its top spacer. Scrolling up, scrollTop reaches 0 while ~1470 messages are still unrendered, so a scroll excursion terminates far short of its target.
Measured at n=2000, excursion target 200 messages:
| arm |
messages actually traversed |
| naive |
201 |
| evict |
200 |
| hybrid |
114 (stalls, scrollTop hits 0 with lo=1470) |
Impact — contained, but real
The benchmark's completeness guard catches this: upBy() reports complete: moved >= k, and run_cell nulls the cell rather than publishing a number from a short excursion. So no false number is published — hybrid's deep-scroll-back timing cells are blank in the artifact, by design.
Unaffected, and explicitly still trusted:
hybrid's memory numbers (USS, retained nodes): sampled at the top after the full bottom-to-top sweep, which does reach lo == 0.
tests/test_chat_history_hybrid_bench_js.py asserts lo == 0 after the sweep and a bounded window throughout — both still pass.
The benchmark's conclusion does not rest on the affected numbers. Eviction dominates the hybrid on memory structurally (detach-preserve retains a superset of what eviction retains over the same window), not by measurement.
Suspected cause
Hybrid.prototype._spacerHeights estimates unmeasured message heights as heights[i] || avgH, where avgH is seeded from the initial WINDOW_SIZE render. Suspects, in order:
avgH under-estimates the true corpus mean (the initial window is the newest 50 messages, not a representative sample), so the top spacer is systematically short by a factor that grows with lo.
- The scroll-anchor
box.scrollTop += box.scrollHeight - before in _pageOlder may compound a per-page error rather than correcting it.
A ~10% avgH error accounts for only ~25k px of the ~220k px shortfall observed, so (1) alone does not explain it. Read the geometry before changing code.
Scope
This is a proof-of-concept benchmark arm, not shipping code, and the hypothesis it was built to test (that a warm detach band adds value over eviction alone) was refuted on other grounds. Fixing it is worthwhile only to make the withheld timing cells publishable, which would strengthen the artifact but change no conclusion.
Deliberately not fixed under the run that found it: the harness must not be edited while a measurement run is in flight.
Repro
venv/bin/python -c "
import sys; sys.path.insert(0,'tests/bench')
from playwright.sync_api import sync_playwright
import chat_history_bench as B
with sync_playwright() as pw:
ctx = pw.chromium.launch_persistent_context('/tmp/hb', headless=True, args=B.LAUNCH_ARGS, viewport=B.VIEWPORT)
page = ctx.new_page(); page.set_content(B._HARNESS_HTML)
B.load_arm(page, 'hybrid', 2000)
page.evaluate(B._deepback_probe_js())
print(page.evaluate('()=>window.hybridBench.stats()'))
print('scrollTop', page.evaluate(\"()=>document.getElementById('chat-history').scrollTop\"))
ctx.close()
"
Expect lo well above 0 with scrollTop at ~0.
Summary
tests/bench/vendor/hybrid_bench.js(the benchmark'shybridarm — warm-band detach over cold-tail eviction) under-reports the height of unrendered history in its top spacer. Scrolling up,scrollTopreaches 0 while ~1470 messages are still unrendered, so a scroll excursion terminates far short of its target.Measured at n=2000, excursion target 200 messages:
scrollTophits 0 withlo=1470)Impact — contained, but real
The benchmark's completeness guard catches this:
upBy()reportscomplete: moved >= k, andrun_cellnulls the cell rather than publishing a number from a short excursion. So no false number is published —hybrid's deep-scroll-back timing cells are blank in the artifact, by design.Unaffected, and explicitly still trusted:
hybrid's memory numbers (USS, retained nodes): sampled at the top after the full bottom-to-top sweep, which does reachlo == 0.tests/test_chat_history_hybrid_bench_js.pyassertslo == 0after the sweep and a bounded window throughout — both still pass.The benchmark's conclusion does not rest on the affected numbers. Eviction dominates the hybrid on memory structurally (detach-preserve retains a superset of what eviction retains over the same window), not by measurement.
Suspected cause
Hybrid.prototype._spacerHeightsestimates unmeasured message heights asheights[i] || avgH, whereavgHis seeded from the initialWINDOW_SIZErender. Suspects, in order:avgHunder-estimates the true corpus mean (the initial window is the newest 50 messages, not a representative sample), so the top spacer is systematically short by a factor that grows withlo.box.scrollTop += box.scrollHeight - beforein_pageOldermay compound a per-page error rather than correcting it.A ~10%
avgHerror accounts for only ~25k px of the ~220k px shortfall observed, so (1) alone does not explain it. Read the geometry before changing code.Scope
This is a proof-of-concept benchmark arm, not shipping code, and the hypothesis it was built to test (that a warm detach band adds value over eviction alone) was refuted on other grounds. Fixing it is worthwhile only to make the withheld timing cells publishable, which would strengthen the artifact but change no conclusion.
Deliberately not fixed under the run that found it: the harness must not be edited while a measurement run is in flight.
Repro
Expect
lowell above 0 withscrollTopat ~0.