Skip to content

Share one UnivMon across distinct, L2 and entropy; document why those readouts stay uncertified - #596

Draft
zzylol wants to merge 1 commit into
stack/509-w7a-pass2-sizingfrom
stack/509-w7a-univmon-accuracy
Draft

zzylol wants to merge 1 commit into
stack/509-w7a-pass2-sizingfrom
stack/509-w7a-univmon-accuracy

Conversation

@zzylol

@zzylol zzylol commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Rebased on main d4869a7 (DF 54).

Wave 1 chain: #594 → #593 → #592 → #591 → #595 → #596 → #597 → #598 → #599 (on #589)

Part of #509 (Example 2), #580 item E (accuracy part).

Why

#509 Example 2 has one UnivMon serving a distinct count, an entropy and an L2 norm, sized for the strictest requirement. Two things blocked it: the summary-capability rule (#595) knew only quantiles, and UnivMon certified only its total, so Stage 3 rejected every other UnivMon estimate.

What

  • Capability rule: a new FrequencyMoments key. Cardinality over at most one column, FrequencyL2 and FrequencyEntropy over the same input, window, grouping and column share one UnivMon. All members of the key are re-sized for the strictest requirement (W5). UnivMon's shape does not depend on ε, so the three UnivMon alternatives are one state. The other summaries (for example the distinct count's HLL) are re-sized for the strictest ε.
  • Accuracy model: no new certification. I found no sound bound for the shipped kernel's distinct, L2 or entropy readouts, so they stay uncertified (as the task allowed), and accuracy/estimators/univmon.rs documents why:
    • Published bound. Liu et al. (SIGCOMM 2016) build on Braverman and Ostrovsky's recursive sketch. With O(log n) layers, each returning a (g, ε)-cover of its substream, the recursive G-sum is (1 ± ε) with probability 1 − δ. The layer size is only stated asymptotically (O(ε⁻² log 1/δ) per CountSketch, times polylog factors). No constants exist to invert into (heap_size, rows, cols, layers).
    • Kernel. asap_sketchlib::UnivMon::calc_g_sum_heuristic keeps a fixed top-heap_size heap per layer, read through that layer's CountSketch. For distinct counts it also drops items below L2/√heap_size. Nothing bounds the probability that a heap is a cover, so the theorem's premise does not hold. Even with complete heaps, a CountSketch estimate can be ≤ 0 for a present item, so the distinct count is not certified there either.
    • CountSketch levels. A layer's CountSketch gives a sound F₂ (AMS) bound, but calc_l2 reads the recursive sum, not that estimate.
    • Path to a sound bound. Either an L2 readout from layer 0's CountSketch, or a per-layer cover guarantee. Both are executor/sketchlib changes, outside this PR.
  • Sizing: estimators::size_params is unchanged, since it has no bound to invert (UnivMon keeps its fixed candidate shape). This is documented on univmon::size_params.

Before / After

distinct_over_time(src[1m]) at ε = 0.02, entropy_over_time(src[1m]) at ε = 0.05 and l2_over_time(src[1m]) at ε = 0.01, through e2e_plan (frequency_moments_share_one_univmon_in_the_stage_pipeline):

accuracy model on #595 this PR
synthetic evidence certifying UnivMon one shared UnivMon, through the identical-expression merge after composition, because UnivMon's shape is fixed one shared UnivMon; the capability variant also lists it, with the other summaries re-sized for ε = 0.01
built-in no UnivMon selected no UnivMon selected: Stage 3 has no sound guarantee, unchanged

So for PromQL the new key changes no selection today. I checked this: the new pipeline test also passes on #595's rule. The key matters when pre-ASAP CSE merges nothing (SQL's unkeyed scans, for example COUNT(DISTINCT) next to a future SQL entropy/L2), or once UnivMon is sized per ε. The test pins the shared outcome either way.

Tests

  • univmon::tests::only_the_total_is_certified pins that the total is certified and the three readouts are not.
  • summary_capability::tests::frequency_moments_share_one_univmon.
  • summary_sharing::frequency_moments_share_one_univmon_in_the_stage_pipeline is the 3-consumer case through plan_stages via the facade.

Gate

fmt and clippy (-D warnings) are clean. cargo test --workspace: 1,531 passed and 7 ignored, against 1,528 and 7 on #595 and 1,517 and 10 on #589. That is +3 new tests. The Example 1 fixture regenerates byte-identically.

Gaps

  • Distinct, L2 and entropy from UnivMon still need a kernel readout with a provable bound before the built-in model can select them.
  • Example 2's "pairs share, third independent" candidates are not listed, by W5.

🤖 Generated with Claude Code

…umers

The summary-capability rule gains a frequency-moments key: a distinct count
(one column), an L2 norm and an entropy over the same input and window
share one UnivMon (#509 Example 2). UnivMon's shape does not depend on the
requirement, so the three alternatives are the same state.

The UnivMon accuracy model still certifies only the exact total. The
published UnivMon bounds (Liu et al., SIGCOMM 2016, via Braverman and
Ostrovsky) are asymptotic. The shipped kernel's heuristic recurrence, a
fixed top-heap per layer with an L2/sqrt(heap) cut, does not meet their
per-layer cover premise. Distinct count, L2 and entropy therefore stay
uncertified. The reasoning is documented, and a test pins it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zzylol
zzylol force-pushed the stack/509-w7a-pass2-sizing branch from 3c07c2d to cf0df8a Compare October 5, 2026 06:21
@zzylol
zzylol force-pushed the stack/509-w7a-univmon-accuracy branch from aab5e7e to a6e5cda Compare October 5, 2026 06:21
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