Skip to content

fix: correct EWMA decay formula and reject sample count of 0#27

Open
costela wants to merge 1 commit into
test/deterministic-ewma-seedfrom
fix/ewma-decay-formula
Open

fix: correct EWMA decay formula and reject sample count of 0#27
costela wants to merge 1 commit into
test/deterministic-ewma-seedfrom
fix/ewma-decay-formula

Conversation

@costela

@costela costela commented Jun 26, 2026

Copy link
Copy Markdown
Member

Stacked on #26 (deterministic EWMA seed) — review/merge that first. The base will retarget to main automatically once #26 merges.

What

Corrects the EWMA smoothing factor and rejects sampleCount == 0.

Why

The decay was 2/(N/2+1) — the span formula with N halved:

  • sampleCount == 1 → decay 1.333 (> 1), giving the previous rate a negative weight, so the failure rate can go <0 or >1. Mathematically broken.
  • It also contradicts the doc "a value of 1 causes a single sample to be considered" — that (decay == 1) actually happened at sampleCount == 2.

Anyone who read the doc and passed sampleCount=1 is running a breaker with a broken update rule.

How

  • Use the canonical span factor 2/(N+1): exactly 1 at N==1 (matches the docs), and in (0,1] for all N≥1.
  • Only N==0 is left out of range (decay 2) → apply rejects it with a clear error.
  • Zero-value breaker (decay 0) stays allowed and never opens, as documented.

Notes

⚠️ Behavior change: alters convergence speed for existing sample counts. Belongs on the same breaking line as the recent feat! type-parameter change.

🤖 Generated with Claude Code

The smoothing factor was computed as 2/(N/2+1), which is the span formula
with N halved. For sampleCount == 1 this yields decay == 1.333 - a smoothing
factor greater than 1, giving the previous failure rate a negative weight so
the rate can go below 0 or above 1. It also contradicted the documented
"a value of 1 causes a single sample to be considered": that single-sample
behavior (decay == 1) actually only occurred at sampleCount == 2.

Use the canonical span-based factor 2/(N+1) (the Wikipedia exponential-
smoothing link in the code): it equals exactly 1 at N == 1 (matching the
docs) and stays in (0,1] for every N >= 1. Only N == 0 remains out of range
(decay == 2), so apply now rejects it. The zero-value breaker (decay == 0)
stays allowed and never opens, as documented.

This changes convergence speed for existing sample counts, so it is a
behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@costela costela marked this pull request as ready for review June 26, 2026 19:28
@costela costela requested a review from Copilot June 26, 2026 19:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes the EWMA breaker’s smoothing/decay factor to use the canonical span-based formula and ensures invalid configuration (sampleCount == 0) is rejected during circuit construction, preventing out-of-range EWMA weights.

Changes:

  • Update EWMA decay formula to 2/(N+1) so N==1 yields decay 1 and all N>=1 stay within (0,1].
  • Add validation in EWMABreaker.apply to reject configurations that produce decay > 1 (i.e., sampleCount == 0).
  • Add tests covering the sampleCount == 1 decay behavior and sampleCount == 0 rejection via NewCircuit.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
breaker.go Corrects EWMA decay computation and adds sampleCount==0 rejection via apply() validation.
breaker_test.go Adds regression tests for decay correctness at sampleCount==1 and rejection at sampleCount==0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants