Skip to content

feat(gos): Sum insert-time delta gate (T=ε·|sum|/k, degenerate 1-cell case) - #526

Merged
zzylol merged 1 commit into
mainfrom
split/pr-gos-sum
Jul 17, 2026
Merged

zzylol merged 1 commit into
mainfrom
split/pr-gos-sum

Conversation

@zzylol

@zzylol zzylol commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Part of the GOS per-family stack (base: CountSketch split/pr-gos-countsketch / #524). Sum is the degenerate one-cell case (design §11 / derivations §8.1): T=ε·|sum|/k. No sketchlib-go change (Sum is a pure scalar in asap-precompute-go).

SumWrapper tracks two tiers: gosSinceCrossSum/Count (amount since last crossing, tested against T every Update, zeroed on crossing) and gosReadySum/Count (captured-but-undrained, staged until ComputeDeltaAgainst drains them, ignoring prev). Wire payload shape unchanged (16-byte {sum,count}); GOS just ships the drained amount directly rather than diffing two totals.

Subtlety handled: Snapshot() subtracts the staged gosReadySum when GOS is active, so the SnapshotCache prev==nil first-emit fallback (which calls Snapshot() directly, bypassing ComputeDeltaAgainst) doesn't double-report anything already captured. No-op / byte-identical when GOS off. w.sum itself is not reduced by captures, so N stays a real running total.

AggKindSum GOS-bypass cases in subWindowShouldEmit/subWindowMarkEmitted; factory primes SetGosMode; gos_delta_epsilon accepted for family=sum. Sum has no sampling path, so no #518 interaction.

Test plan

  • wrapper: empty-drain→nil, wake-fires-once (and doesn't re-arm on a small follow-up once the total has grown), telescoping reconstruction.
  • processor: TestGOSSumInsertWakesFlush (SubWindowInterval unset, WindowDuration 1h, ConsumeMetrics-only flush).
  • build/vet/test clean in both locations.

Note (documented, deferred): monitor.Engine's FunctionalSum alerting reads Sum() directly, which under GOS returns a residual — the same "local read corrupted under GOS" trade-off the design doc's Retirements section defers to the Discipline-B split PR.

🤖 Generated with Claude Code

Implements the insert-time GOS mechanism for Sum, the degenerate 1-cell
case: on every Update, check the accumulated-since-last-crossing
magnitude against T=ε·|sum|/k (SumIsotropicThreshold); on crossing,
capture it into a pending-drain accumulator, zero the since-crossing
tracker in place, and arm the wake signal so the flush loop runs
immediately instead of waiting for a periodic tick.

- asap-precompute-go/sketches/sum.go: SetGosMode, Update's insert-time
  threshold check, ConsumeWakeSignal, drainGosDelta (drained by
  ComputeDeltaAgainst when GOS is active, ignoring prev entirely).
  Snapshot() excludes any amount already staged for drain so the
  first-ever full snapshot and a later drained delta never overlap
  (avoids double-counting under the additive backend reconstruction
  model) — the one wire-format wrinkle GOS introduces; the 16-byte
  {sum,count} payload shape itself is unchanged, and the non-GOS path
  (gosEpsilon<=0) is byte-identical to before.
- asap-precompute-go/sketches/gos_threshold.go: SumIsotropicThreshold
  (T=ε·N/k, the linear-f case with no √(d·w) term).
- asap-precompute-go/precompute.go: subWindowShouldEmit/
  subWindowMarkEmitted bypass the old periodic divergence gate for
  AggKindSum when GosDeltaEpsilon>0, mirroring the existing
  Count-Sketch bypass. applyGosMode already worked generically via its
  structural SetGosMode interface assert, so it needed no change.
- opentelemetry-collector-contrib-patch/processor/asapedgeprocessor:
  prime SetGosMode at Sum series creation (warm_sketch.go); extend
  config_validate.go's gos_delta_epsilon check to accept family=sum
  alongside family=countsketch.

Tests: sum_gos_test.go covers empty-drain-returns-nil, wake fires once
and clears (and doesn't re-arm for a small follow-up insert once the
threshold has grown), and a telescoping reconstruction test applying
every drained delta onto a fresh target and confirming the
reconstructed total (plus the known, bounded sub-threshold residual)
matches the true cumulative sum. gos_sum_test.go is the processor-level
end-to-end proof (SubWindowInterval unset, WindowDuration long) that
ConsumeMetrics alone — no manual wakeSubWindow() — produces a flush.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@zzylol
zzylol force-pushed the split/pr-gos-sum branch from 1f561d0 to 91b4ff6 Compare July 17, 2026 02:39
@zzylol
zzylol changed the base branch from split/pr-gos-countsketch to split/pr-gos-ddsketch July 17, 2026 02:39
@zzylol
zzylol changed the base branch from split/pr-gos-ddsketch to main July 17, 2026 15:47
@zzylol
zzylol merged commit 4686937 into main Jul 17, 2026
@zzylol
zzylol deleted the split/pr-gos-sum branch July 17, 2026 15:52
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