Skip to content

Point-window cache (T13) + resolvability gate (#225)#227

Merged
masenf merged 12 commits into
mainfrom
claude/point-caching-sampling-av37m7
Jul 24, 2026
Merged

Point-window cache (T13) + resolvability gate (#225)#227
masenf merged 12 commits into
mainfrom
claude/point-caching-sampling-av37m7

Conversation

@masenf

@masenf masenf commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements two interconnected LOD improvements: a per-trace LRU cache of retired exact point windows (T13) that eliminates re-requests on pan/zoom sequences, and a resolvability gate (#225) that prevents sample overlays from drawing above the direct point budget where they misrepresent the dataset.

Key Changes

Point-Window Cache (T13)

  • Added LOD_POINT_CACHE_WINDOWS = 3 constant to bound retired window memory
  • Introduced lodRetireDrill(), lodPromoteCachedDrill(), and supporting functions to manage the per-trace LRU cache of exact point windows
  • When a new points reply arrives for a different window, the previous exact window retires into the cache instead of being freed
  • Views covered by any cached window promote it back to the live drill with zero kernel round-trip
  • Cached windows obey geometry-only retirement (T11): once a view outgrows a window past the drill budget, its buffers free with no kernel reply
  • Extracted lodWindowServesView() as a shared containment check for both live drill and cached windows

Resolvability Gate (#225)

  • Added lodOverlayResolvable() function that gates sample overlay drawing on estimated in-view count
  • Sample overlays now draw only when overlay.sample.visible * (viewArea / windowArea) <= LOD_DIRECT_POINT_BUDGET
  • Above the budget, a fixed-size sample reads as individual data points at sub-pixel zoom, misrepresenting the dataset; the density surface stands alone
  • Interactive density_view replies no longer ship point samples at all (only the first-payload sample is retained for the standalone re-bin worker)
  • Updated lodSampleForView() to apply the gate before considering overlay candidates

Padded Aligned Windows (T13 support)

  • Drill windows now ship as padded ALIGNED superset of the view (within budget) to maximize cache reuse across pans
  • Consecutive pans resolve to the same aligned bounds, enabling client-side deduplication
  • Added aligned_window() and _padded_drill_window() to compute the widest aligned window that fits the budget
  • Span is capped relative to the view (DRILL_PAD_SPAN_CAP) to keep deep zooms inside the §16 re-encode ladder
  • Falls back to raw view window when padding would exceed budget

Drill Subset History

  • Added drill_history dict to Trace to remember recent shipped subsets (bounded by DRILL_HISTORY_KEEP)
  • Cached point windows outlive the kernel's current-tier choice; picks against them translate through the remembered subset
  • drill_history() returns the shipped subset for a given drill_seq, or None when expired (drops the pick)
  • clear_drill_history() forgets subsets after data changes

Identical-Request Suppression (T13)

  • Added _densityRequestDup() to detect when the same window at the same screen size is already in flight or answered
  • Prevents the "constantly re-requesting the same points" loop by keeping the original seq instead of arming a duplicate
  • Checked both at request scheduling and at send time

Client-Side Changes

Notable Implementation Details

  • The cache is per-trace (not global) to respect data independence
  • Window comparison uses relative tolerance (span * 1e-9 + 1e-300) to handle floating-point slop
  • Retired windows on drill death (zoom-out to density) are cached the same way as on new-window retirement, enabling zero-cost revive
  • The resolvability gate requires finite visible count on the sample metadata; overlays without recorded counts (hand-built/legacy specs) keep drawing
  • Padded windows snap to power-of-two grid over the trace extent, making them stable

https://claude.ai/code/session_01XQT3v7NdL4dmC6S3g8HjJt

masenf added 5 commits July 23, 2026 02:37
The Tier-2 density map colormapped the binned COUNT, ignoring the
points' own colors — a colored scatter's aggregate view matched neither
its marks nor its legend, and every density<->points zoom transition
visibly recolored the chart.

The surface now wears the data's colors (LOD doc §2): each cell carries
the alpha-weighted mean of its binned points' resolved colors — one law
for continuous, categorical, and direct-RGBA channels — averaged in
linear light through an integer-only pipeline (checked-in sRGB<->linear
u16 tables, u64 sums; bitwise deterministic across thread counts and
platforms). The log-tone-mapped count drives only the alpha channel:
more points, deeper color; fewer, lighter. Constant-color traces keep
the compact count-only wire and a client tint (the mean of a constant
is the constant).

- Rust core: bin_2d_mean_color kernel, with a fused cell accumulator
  that fans out under a points-per-cell gate (<=4 workers, exact
  integer merge — output identical to the serial scan); pyramid
  mean-color planes (build_color/compose_color; count grids
  bit-identical to the count-only compose; colored pyramids refuse
  appends and are invalidated + rebuilt lazily). C ABI v40.
- Python: channels.resolve_bin_colors maps every channel mode onto the
  kernel color source; initial emit + density_view (exact and pyramid
  paths) ship the RGBA plane as density.rgba with color_agg: "mean";
  color is no longer listed in dropped_channels; the windowed-exact
  spatial tier is gated to colorless traces (its index is
  position-only, §27 — the upsampled colored-pyramid grid stays
  instead); SVG/PNG exporters follow the same color law;
  continuous-channel density scatters render their colorbar again.
- Client: DENSITY_FS mean-color branch over a premultiplied RGBA8
  texture (count tone curve baked at upload so bilinear filtering
  weights color by coverage); exposure easing re-encodes color grids;
  the standalone to_html re-bin worker aggregates the sample's colors
  under the same law; the density-tier gradient legend swatch is
  removed (count is alpha, so a gradient would claim color == density;
  a named density trace falls through to the plain marker swatch,
  matching the static exporters).
- Handoff (§5): intensity-only. Hue is continuous by construction, so
  drilled points arrive in native colors, enter at their cell's
  count-alpha, and ease to native opacity; density_colormap left the
  points wire, and density_val (still u8 on the live wire, #221) now
  weights alpha instead of indexing a colormap LUT. The aggregate
  backdrop retires once a drill settles inside its window (T10
  amended: a mean-color wash under exact marks reads as data) and
  eases back fast when the view leaves the window, a refinement goes
  pending, or the drill dies — zoom-outs never blank and interleaved
  replies never flash.
- Spec: LOD doc §2 rules rewritten around the shipped mean-color law,
  pyramid §4 color planes and refused appends, T3/T10 amended, Phase
  1/3 progress; dossier §5 Tier-2, F5 verdict, and constants table;
  wire protocol records density.rgba/color_agg, the u8 unit-scalar
  encodings, and the slimmer points message; chart-kind contract
  covers the aggregate kernel pairing and the legend rule; rust-engine
  inventory row.
- Tests: kernel-vs-NumPy oracle suite (tests/test_density_mean_color,
  including a serial parallel-merge oracle and exporter pixel checks),
  wire and colorbar assertions, render-smoke probes for the mean-color
  surface (meancolor) and backdrop retirement (dretire). The pyramid
  color test asserts the direction the #153 area-weighted compose
  keeps invariant (nonzero count implies lit, unlit implies zero
  count) rather than exact mask equality, which boundary-bin count
  slivers can legitimately break.
The demo predated the kernel pyramid and carried two extra density
implementations to stay interactive at 100M points: a 6144^2
integral-image overview server-side and ~350 lines of page JS (browser
local re-bins, request parking/single-flight/timeout-retry, per-client
staleness maps, pending-status heuristics). Both were count-only, so
once density surfaces started wearing the mean point color, mid-zoom
windows flipped back to a count-colormapped green wash, flashing
old<->new across zoom levels. The engine has since absorbed every job
they existed to do: Figure.density_view serves wide windows from the
mean-color pyramid in O(visible cells) with drill bookkeeping and
recorded binning, and the render client debounces requests, seq-drops
stale replies, and keeps the best cached texture drawn while a reply is
in flight.

The module is now the pattern it demonstrates: build one figure
(pyramid warmed at startup), serve payload + bundled client as HTML,
and wire ChartView to a comm object that POSTs messages to one endpoint
dispatching density_view/pick under a lock. Page JS drops from ~400
lines to ~60 (fetch + status badge), and the HTML route reuses the
shared figure instead of regenerating 100M rows per GET.

Round-trips ship as XYBF binary frames (wire-protocol §7): the reply
message is the frame's compact JSON metadata and each numeric buffer
rides raw and 8-byte aligned, so the browser decodes one xy.decodeFrame
and hands the kernel zero-copy views with no base64 step on either side
(~33% smaller replies on the grids and point buffers that dominate a
drill). First paint still embeds its blob as base64 — inline HTML has
no binary channel (§6) — and malformed requests still return a JSON
error the client rejects on res.ok before decoding.

tests/test_drilldown_pan_alignment.py is removed with its subject: it
guarded the browser-local re-bin's window-clamp bug, and engine-served
grids always report exactly the window they binned, so that failure
mode is unreachable. The example test now decodes the XYBF frame and
asserts on its message and raw buffers.
Serve the fastapi example's live drilldown scatter — same seed-11
chunked columns, same mark config, same XY_LIVE_POINTS override — from
the reflex-xy adapter as one inline() token with zero transport code.
The fastapi app wires this chart through a custom HTTP transport (a
Starlette endpoint plus a comm bridge); the adapter's websocket
namespace and the kernel's density tiers replace all of it, so behavior
differences between the two hosts isolate what that custom code adds
versus what is fundamental to the engine (density tiers, pyramid
binning, drill-in).

- examples/reflex: §6 section + drilldown_chart()/drilldown_view(),
  README run notes (import-time build, memory, XY_LIVE_POINTS override)
- tests/test_example_apps.py: source markers for §6; the import test
  pins XY_LIVE_POINTS=50000 (same override the fastapi test uses) and
  asserts the inline token mints
- scripts/reflex_ws_smoke.py: count the seventh live source, wait for
  the drilldown payload, and pixel-check its density surface
- spec: reflex-integration §7 inventory + production-readiness example
  focus bullet name the deliberate cross-host overlap
Once a points reply has shipped its window exactly (reduction "none" —
the subset IS every point in the window), any view contained in that
window is already answered by the marks on the GPU: the smaller
window's points are a subset of the shipped ones. Drilling deeper
therefore no longer round-trips the kernel — _scheduleViewRequest skips
the trace's pending markers and its density_view message
(lodDrillServesView, re-checked at debounced send time), while still
bumping seq so an in-flight reply for an older, wider view dies stale
instead of yanking exact marks out from under a view it cannot improve.

Three conditions re-arm the request: leaving the window, a drill that
is dying or not exact (only reduction "none" arms the elision, recorded
as drill.exact), and depth — the shipped geometry is f32,
offset-encoded on the window midpoint (dossier §16), so once the view
span drops below 1/256 of the window span on either axis one request
goes out purely to re-center the encoding. Data changes cannot serve
stale marks through the elision: streaming append and full payload
updates rebuild the GPU trace, which drops the drill.

Recorded as invariant T12 in spec/design/lod-architecture.md §5, in the
wire protocol's density_view entry, and in dossier §16/§28; covered by
a headless-Chromium probe (tests/test_drill_zoomin_elides_request.py)
asserting the elision and each re-arm condition.
…dows

Fixes #225: zooming out from a drilled window brought fixed-rate "sampled
points" back over the density surface — individual marks at a zoom where
real points are sub-pixel, misrepresenting the dataset. Now:

- Interactive density_view replies ship no point sample at all. The
  mean-color density surface (LOD doc §2) stands alone above the drill
  budget; real points still arrive the moment a window fits it. The
  retained first-payload sample (the standalone re-bin worker's CPU
  source) draws only below a resolvable-count gate: estimated in-view
  count <= LOD_DIRECT_POINT_BUDGET (lodOverlayResolvable, T9). Datasets
  under the budget keep the hybrid look everywhere.

Point caching (LOD doc T13) so pan/zoom stops re-shipping the same points:

- Kernel: a points-tier reply ships the largest ALIGNED window around the
  view whose exact count fits the budget (lod.aligned_window: bounds snap
  outward to a power-of-two grid over the trace's extent, per dimension;
  DRILL_PAD_TARGETS ladder, pyramid-count-gated, exact-verified,
  DRILL_PAD_SPAN_CAP guards the §16 re-encode ladder). Consecutive pans
  resolve to the SAME window; lod_blend stays keyed on the view's own
  count. Nonlinear axes keep the exact view window.
- Client: a reply for a new window retires the previous exact drill into
  a bounded per-trace cache (lodRetireDrill/LOD_POINT_CACHE_WINDOWS)
  instead of overwriting its buffers — so does a drill dying outside its
  window — and any later view covered by a cached window promotes it back
  alpha-continuously with zero round-trips (lodPromoteCachedDrill).
  Outgrown windows free geometry-only (T11 rule, §27).
- Kernel keeps a bounded drill-subset history (Trace.drill_history,
  DRILL_HISTORY_KEEP) so picks against a promoted retired window still
  translate exactly; expired seqs drop the pick, data changes clear it.
- Client suppresses identical density_view requests (same window, screen,
  unchanged data) and accepts the suppressed duplicate's in-flight reply
  per-trace instead of killing it with the bumped seq — ending the
  re-request loop at gesture end.

Spec: lod-architecture T9 rewritten + new T13, wire-protocol
density_view/points/pick contracts, dossier constants table, CHANGELOG,
README representation labels, docs ladder table.

Tests: new test_drill_window_padding (alignment, budget, span cap,
nonlinear skip, history clear), test_density_sample_resolvability_gate
and test_drill_point_window_cache (headless-Chromium client probes),
elision test extended for duplicate suppression; drill tests updated to
the padded-window contract.
@masenf
masenf marked this pull request as draft July 23, 2026 12:50
@greptile-apps

greptile-apps Bot commented Jul 23, 2026

Copy link
Copy Markdown

Greptile Summary

This PR updates the LOD path for density and drill-down rendering. The main changes are:

  • Adds a per-trace cache for retired exact point windows.
  • Promotes cached point windows back to the live drill path when they cover the current view.
  • Adds padded aligned drill windows to improve reuse across pan and zoom changes.
  • Gates sample overlays so they only draw when the estimated in-view count is within the direct point budget.
  • Suppresses duplicate density requests for identical windows and screen sizes.
  • Adds drill subset history so picks against cached point windows can still resolve recent drill sequences.

Confidence Score: 5/5

This PR appears safe to merge.

The highest-risk paths are covered by targeted browser probes and server-side tests for cache promotion, request economy, padding, and overlay gating. No new verified blocking issues were found in this pass.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • Ran the targeted pytest suite and confirmed the run reported 57 passed and 4 skipped with EXIT_CODE 0.
  • Executed the TypeScript type-check step and confirmed it completed with EXIT_CODE 0.
  • Built the frontend project with the Vite build and confirmed it generated minified static bundles and exited with EXIT_CODE 0.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
js/src/45_lod.ts Adds client-side density resolvability gating, aggregate-step request planning helpers, physical-alpha texture uploads, and the retired point-window cache.
js/src/54_kernel.ts Reworks density request scheduling, duplicate suppression, reply currentness, and drill-cache promotion.
python/xy/interaction.py Implements padded aligned drill windows, no-sample interactive density replies, and drill-history lifecycle integration.
python/xy/lod.py Adds reusable aligned-window and drill-history utilities plus supporting LOD helpers.
python/xy/_trace.py Adds bounded drill subset history on traces so cached point-window picks can translate through recent drill sequences.
python/xy/config.py Introduces tuning constants for padded drill windows and drill history retention.
tests/test_density_request_economy.py Adds browser-level probes for aggregate standing, ladder-step requests, duplicate suppression, and one-texture drawing.
tests/test_drill_point_window_cache.py Adds browser probe coverage for retiring, promoting, bounding, and sweeping cached exact point windows.

Reviews (8): Last reviewed commit: "Merge origin/main into claude/point-cach..." | Re-trigger Greptile

Comment thread js/src/54_kernel.ts
Comment thread js/src/54_kernel.ts Outdated
…yered draw

Field HAR from the 100M live drilldown (PR #227 review): every pan/zoom
step at 200-450% zoom re-requested a ~2.7 MB full-screen density grid —
including back-to-back windows differing by sub-pixel amounts — and the
frame dropped to the blurriest cached texture whenever a pan left the
freshest window. Three fixes, all recorded under LOD doc T13:

- Kernel: pyramid-served grids are clamped to the source cells the finest
  level resolves under the window (interaction._pyramid_source_shape,
  ceil(base*frac)+1 per axis) — composing to full screen resolution just
  upsamples blocky cells the client's texture filtering reproduces from
  the source-resolution grid at a fraction of the bytes. The attainable
  per-axis cell size rides the reply as density.min_cell; exact and
  spatial grids (true full-detail bins) omit it. The HAR's 2.7 MB replies
  drop to ~0.5-1.4 MB in its zoom range and ~200 KB deeper.

- Client request elision (lodDensityCacheServes): a cached texture that
  contains the view and is as detailed as anything the kernel could
  return — one texel per screen pixel, or already at min_cell (zooming
  into a source-limited texture cannot sharpen it) — answers with no
  round-trip. Guarded so the kernel stays in charge where it can do
  better: estimated in-view count must exceed budget x
  LOD_DENSITY_ELIDE_EST_FACTOR, and the cached window may be at most
  LOD_DENSITY_ELIDE_MAX_AREA_RATIO x the view area (uniform-density
  estimates overshoot in sparse corners). Entries without recorded
  counts never elide; lodRememberDensity now supersedes an unpinned
  same-window twin so elision always reads current facts.

- Sub-texel request dedup: the identical-request memo compares windows
  numerically within half an output texel per edge (gesture-end and
  settle emit sub-pixel twins; a grid shifted below half a texel is the
  same picture) instead of exact string equality.

- Finer-detail layering (lodDensityDetailForView): when no fine cached
  window contains the view, the smallest cached texture overlapping >= 5%
  of it draws on top of the broad backdrop after every crossfade layer,
  so the already-fetched region stays sharp while the request for the
  rest is in flight — a resolution seam beats uniform blur.

Spec: lod-architecture T13 extended, wire-protocol density_view/density
contracts (min_cell, clamped grids, elision), dossier constants table,
CHANGELOG.

Tests: test_density_wire_economy (source-shape math, min_cell presence/
absence, 20M-point clamp integration), test_density_request_economy
(headless-Chromium probe: source-resolution elision + guards, sub-texel
dedup, fine-over-broad layering).
Comment thread js/src/54_kernel.ts
masenf added 5 commits July 23, 2026 18:18
Field feedback on PR #227 (100M live drilldown), superseding the previous
commit's adequacy-elision approach with a simpler rule: the density
texture already covering the view STANDS — however blurry — until the
view could plausibly resolve into real points. Intermediate-zoom blur is
an accepted, recorded cost; the kernel's sharper answers (exact re-bins,
drill-in) stay reachable because the points band still requests.

- Client gate (lodAggregateStands): a density_view goes out only when
  the estimated in-view count sits within LOD_POINTS_REQUEST_BAND (4x)
  of the direct budget. Two estimators, LOWER wins so an over-estimate
  can never strand a view in blur: the smallest cached density window
  containing the view (recorded count, area-scaled; seeded by the home
  texture's first-payload count) and the retained deterministic sample
  counted in-view and re-weighted (lodSampleViewCount) — the sample
  follows the data's actual distribution, so sparse tails reach their
  points where uniform-density area-scaling over-estimates by orders of
  magnitude. Traces with no recorded counts always request.

- Kernel-attached clients never draw the retained sample at ANY zoom
  (field capture: 8k arbitrary sample rows at full alpha over a view the
  kernel serves real points for): resolvable views get exact points, and
  the sample's kernel-mode job is now purely CPU-side estimation. The
  standalone client keeps drawing it below the resolvability gate — its
  only point representation.

- Reverted the fine-over-broad detail layer from the previous commit
  (field capture: a stale darker rectangle) — density textures
  alpha-composite, so the overlap double-counts opacity, and per-window
  normalization makes the seam a brightness step. Recorded in T13; the
  tier draws one texture per frame. Dropped the density.min_cell reply
  field with it (no reader remains); the source-resolution grid clamp
  and the sub-texel request dedup stay.

Spec: lod-architecture T9/T13 revised (never-refines rule, sample-based
estimator, recorded reversal), wire-protocol, dossier constants
(LOD_POINTS_REQUEST_BAND replaces the elision guards), config comment,
CHANGELOG, docs ladder table.

Tests: request-economy probe rewritten to the stands-rule (band
requests, sub-texel dedup, single-texture frames), resolvability-gate
probe gains kernel-mode assertions, wire-economy tests drop min_cell.
Field feedback on PR #227: the count->alpha tone curve made the surface's
lightness swing against the very points it aggregates — visibly at the
texture<->points boundary, and between windows (each reply normalized
against its own max). The §2 philosophy already defines a cell as the
physically downsampled image of its points; this applies that to ALPHA:

- A channel-bearing cell's displayed alpha is now the physical
  compositing of its own points, 1 - (1 - a_pt)^count, with a_pt =
  channel alpha x trace style opacity folded INSIDE the exponent — a
  one-point cell reads exactly like one point, dense cells saturate past
  the style opacity exactly like overplotted marks. No window
  normalization touches these textures (the upload is max-independent),
  so exposure easing (T4) no longer applies to them and the draw path
  passes only transition fades in u_opacity (count-only grids keep the
  log ramp + style opacity uniform — count is their only structure).

- Mean-color drills swap at native opacity with no intensity handoff:
  the texture composites like the marks replacing it, so density_val /
  lod_blend are ignored on such traces (still shipped; count-only drills
  keep the count-alpha ramp). The recorded cost: per-cell density beyond
  a few points no longer reads in the surface — exactly as saturated as
  the overplotted truth it downsamples; drill-in is where per-point
  structure returns.

Same law in the client texture upload (lodWriteGridTexture), the SVG and
native-raster exporters (shared _svg._physical_density_alpha), and the
standalone re-bin worker (shared upload path).

Spec: LOD doc §2 rules 1/2/5, T3/T4 scoping, tier table, Phase-1 notes,
dossier renderer notes, config/marks warning text, CHANGELOG.

Tests: new test_density_physical_alpha (headless-Chromium texture-byte
probe: law values, no norm anim, no handoff) and an exporter-law unit
test in test_density_mean_color; full suite green.
Field capture on PR #227 (screen recording): zooming around the points
band read as "jumping between zoom levels of the density map". Frame
analysis showed the drawn aggregate flipping between two texture
characters — the smooth standing surface (coarse, linear-upscaled) and
fresh transition-band exact grids (~16 points/cell), whose one-point
cells now draw at the points' own alpha (§2 physical compositing) and
so read as hard speckle. Every band probe repainted smooth -> speckle
-> smooth, one jump per crossing.

Completing the stands-rule (T13) on the display side: with a kernel
attached, an aggregate reply never REPLACES a texture that already
covers the view. The standing surface holds until real POINTS land; the
mid-band reply contributes a facts-only cache entry (window + exact
count, lodRememberDensityFacts) that recalibrates the points-band gate,
and the drill lifecycle proceeds as before (dying marks fade into the
standing surface). The picture changes only aggregate->points and back.
A reply for an UNCOVERED view (pan past every cached window) still
applies — silence never blanks a frame (T1) — and standalone clients
keep applying everything (their re-binned grids are their only
refinement). Facts entries are tex-less cache citizens: the draw path
skips them, the gate reads them, eviction guards their missing texture.

Spec: T13 display-side paragraph; CHANGELOG. Tests: the request-economy
probe now asserts the standing texture is byte-identical after a
covered mid-band reply, that its facts landed, and that an uncovered
reply still applies.
Field feedback on PR #227: the aggregate-to-points boundary now feels
smooth, but the standing texture reads soft at times — the home texture
can stretch ~10x by the time points land. Requested: one or two more
density texture steps before real points, stepwise, NOT per-window
(per-view textures were the recorded zoom/pan-jumping failure mode).

- While the aggregate stands (outside the points band), the one density
  request allowed is the next LADDER STEP window
  (lodAggregateStepWindow): the view snapped outward to a
  power-of-LOD_AGG_STEP_FACTOR (4) block grid over the data extent, per
  axis, at most LOD_AGG_STEP_MAX (2) steps below home, and only when
  every covering texture is coarser than the step by more than
  LOD_AGG_STEP_SLACK. Quantized windows are pan-stable and dedupable:
  every view in a region resolves to the SAME window, pans inside a step
  repaint nothing, revisits hit the cache, and a zoom sees at most two
  smooth-to-smooth swaps before points — worst-case softness bounded at
  ~4x stretch per axis instead of unbounded home-stretch.

- A step reply (matched against the marked request window,
  g._stepReqWin) is the ONE density reply that may repaint a covered
  view. Points-band probes keep requesting the RAW view — the kernel
  decides the tier with real counts — and their density replies stay
  facts-only, so the band's speckled exact grids still never repaint the
  smooth surface. Step windows are always >= the view, so their counts
  sit above the band and the kernel serves them from the pyramid:
  smooth by construction. A step window sparse enough to fit the budget
  comes back as points — applied as a (padded) drill, points early.

- Request routing unified in _densityRequestPlan: drill/point-cache
  service first, then band probe (raw view) or ladder step; the
  sub-texel dedup memo now keys on whichever window is actually sent.

Spec: T13 display-side rewritten around the ladder (+ recorded
trade-off: in-band the probe owns the single request slot), dossier
constants, CHANGELOG. Tests: the request-economy probe asserts the
step request is the aligned block window (never the raw view), that
its reply repaints while probe replies stay facts-only, that a covered
step elides further requests, and that band probes request raw views.
test_adaptive_drilldown_cycle pinned the drill reply's visible count to
the raw view window's population — a pre-T13 contract. Drills now ship
the widest ALIGNED window around the view that still fits the budget
(LOD doc T13), so the fixture derives the oracle from the warm-up
reply's shipped window instead: alignment is a pure function of the
extent and the view's span bucket, so every benchmark iteration
resolves to the same window and the same exact count. The cycle now
also asserts that window's determinism per iteration.
@codspeed-hq

codspeed-hq Bot commented Jul 23, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 18.81%

⚡ 1 improved benchmark
❌ 2 regressed benchmarks
✅ 99 untouched benchmarks
⏩ 1 skipped benchmark1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
test_density_view_exact_pan 13 ms 20.9 ms -37.89%
test_adaptive_drilldown_cycle 67.5 ms 107.2 ms -37.05%
test_select_lasso_message_1m 122.9 ms 89.8 ms +36.86%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing claude/point-caching-sampling-av37m7 (080857a) with main (991453d)

Open in CodSpeed

Footnotes

  1. 1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports.

@masenf
masenf marked this pull request as ready for review July 24, 2026 01:58
Base automatically changed from claude/density-mean-color to main July 24, 2026 01:59
Most conflicts were squash artifacts: main's #226 is the same mean-color
density work this branch already carries as commits (main's conflicted
spec/client/kernel/test files are byte-identical to this branch's
pre-work state), so those resolve to this branch's extended versions.
Real incoming changes kept from main:

- src/tiles.rs: separable area-weighted compose (#228) — taken wholesale
  (this branch made no tiles.rs changes beyond the shared #226 content);
  kernels.rs/lib.rs wasm panic-abort hardening (#200) auto-merged.
- README.md: the #230 adoption refresh replaced the inline benchmark
  table (this branch's only README edit) with links to the launch
  report, so main's version stands; the 0.1.0 launch-baseline report
  keeps its historical "density + sample" labels — it records what that
  release did.

Verified on the merged tree: cargo tests, ABI smoke, render smoke, and
the full pytest+benchmarks suite — the only failures are 21 doc-contract
tests (test_docs_examples/test_verify_local/pyplot perf guardrail) that
fail identically on pristine origin/main in this environment: the #230
README rewrite removed maintainer-shortcut text its guardrail tests
still assert. Pre-existing on main, not introduced here.
@masenf
masenf merged commit 3377a3f into main Jul 24, 2026
38 of 42 checks passed
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.

1 participant