Skip to content

tools(sentry): grade the noise gate against install-base uptake, not raw volume - #175

Merged
dzianisv merged 1 commit into
mainfrom
age-105-uptake-normalized-verdict
Aug 14, 2026
Merged

tools(sentry): grade the noise gate against install-base uptake, not raw volume#175
dzianisv merged 1 commit into
mainfrom
age-105-uptake-normalized-verdict

Conversation

@dzianisv

@dzianisv dzianisv commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Replaces #173, which GitHub auto-closed when its base branch age-105-sentry-volume-report was deleted on the #172 squash-merge. Same branch, rebased onto main, no content change.


Stacked on #172 (needs its --json/--by-reason volume report). Refs AGE-105.

The bug this fixes is in the measurement, not the code

The noise gate ships inside the app binary. It only runs on devices that installed v0.4.14 (Play versionCode 150/151, production 2026-08-14 14:22 UTC). So the scheduled re-reads on 08-17 / 08-21 / 09-05 are about to compare a raw event count against a target that assumes 100% install share — which Play reaches slowly and never fully.

Both readings of that mistake are wrong in a way that costs a heartbeat:

  • still ~2,200/mo at 33% uptake reads as "the gate failed" — it is in fact exactly what the model predicts, i.e. the gate working;
  • a dip because it was a quiet weekend reads as efficacy.

What it does

scripts/noise-gate-report.mjs grades against the uptake-adjusted expectation:

expected_post = baseline x (1 - gated_share x 0.969)
  • 0.969 is measured, not guessed — the 90d replay of this project's real events in src/lib/sentry-noise.test.ts. It counts only the transport drop-list, ignoring dedup/rate-cap, so it is deliberately conservative.
  • gated_share = share of active users on versionCode >= 150, from Play vitals (play-version-share.mjs). Sentry cannot answer this: while the org is over quota nothing is stored, so release tags stop.
  • The 100%-uptake projection is reported separately, so "on track today" and "clears the 3,500/mo org gate" stop being the same question.
  • It inverts the model and prints the implied on-device efficacy, so 96.9% is checked against reality instead of trusted.
  • It refuses to grade windows that look like results but aren't: client_discard/before_send == 0 (nothing ran the gate) or 0% Play share → UNGRADED. Absence of evidence is neither pass nor fail.
  • Org outlook takes the background rate from the longer window — the other projects emit ~0.7 events/h, so a short window contains zero of them and would flatter the org total.

Why a workflow

Neither credential exists outside GitHub Secrets. An agent picking up the 08-21 read on a laptop is stuck (I was). .github/workflows/sentry-noise-gate-report.yml runs it on dispatch and weekly, tests the grading model in the same job that publishes the number, and writes the table to the run summary.

gh workflow run "Sentry noise-gate report" -f post=2026-08-21T00:00:00Z..now

Verification

  • 10 unit tests on the grading model, incl. the two symmetrical mistakes above, a real regression at low uptake (still OFF_TRACK), and a gate that does nothing at 90% uptake (implied efficacy 0).
  • Run against the live org 1.2h after rollout: UNGRADED, before_send=0, 4.95/h vs 4.71/h baseline — correct, no device has the build yet.
  • npm test 291 pass.

…raw volume

The gate ships inside the app binary, so it only runs on devices that took
v0.4.14. Grading it on a raw event count is a measurement error in both
directions: a still-high number at 30% uptake is the gate WORKING (~70% of
baseline is the model's own prediction), and a dip from a quiet weekend is not
efficacy. The scheduled re-reads on 08-17 / 08-21 / 09-05 would have hit the
first one first.

noise-gate-report.mjs folds Play's version share into the comparison

    expected_post = baseline x (1 - gated_share x 0.969)

where 0.969 is measured, not guessed (90d replay in sentry-noise.test.ts), and
grades the measured rate against that instead of against the 100%-uptake
endpoint. It reports the endpoint separately, so 'is it on track today' and
'will it clear the 3,500/mo org gate' stop being the same question, and it
inverts the model to print the IMPLIED on-device efficacy so the constant is
checked rather than trusted.

It refuses to grade two windows that look like results but are not: no
client_discard/before_send (nothing ran the gate) and 0% Play share. Absence of
evidence gets its own verdict, UNGRADED.

Runs in CI because neither credential (Sentry org token, Play service account)
exists outside GitHub Secrets — an agent picking up the 08-21 read locally is
stuck otherwise. Weekly cron records the trend regardless.

Verified against the live org: 1.2h after the production rollout it reads
UNGRADED, before_send=0, 4.95/h vs a 4.71/h baseline — which is exactly right,
no device has the build yet.

Refs AGE-105
@dzianisv
dzianisv merged commit d31afc0 into main Aug 14, 2026
7 checks passed
@dzianisv
dzianisv deleted the age-105-uptake-normalized-verdict branch August 14, 2026 16:17
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