RenderTiming is the shell measuring itself, and until now nothing measured
it. The percentile index, the 256-sample bound and the eviction that keeps it
bounded had no test at all, which is a strange place for a codebase to have a
blind spot: this is the number the footer shows a user when they ask whether
the app is slow.
The eight tests state the decisions the code already made, so that changing
one is a choice rather than an accident. Percentiles are computed over sorted
samples, not arrival order. Ninety-nine good frames and one 40ms stall keep a
p50 of 100µs and the stall shows in the p95, which is the entire reason this
is a distribution and not the mean it would be so much easier to compute. A
full window of new frames retires every stale sample, and eviction is from the
front, so the figure describes the last four seconds rather than the session.
An unpaired build records nothing, because a duration with no start is not a
fast frame -- it is no data, and averaging a zero into the p50 would report
the shell as faster than it is. Two dispatches before one build is one sample
and it is the later one, since the earlier action's tree was never built.
The percentile tests build the buffer directly rather than going through the
clock. Driving them through mark_dispatch would make every assertion depend on
how loaded the machine running CI happens to be, which is how a timing test
becomes the flaky one everybody reruns.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SPYebLiN2w4TqnHUYGdECq