* feat(analytics): session-level $exception dedupe in before_send
A runaway client error (a render loop, a polling fetch that keeps
throwing) emits 100+ identical $exception events per session, which
showed up as a top PostHog cost/noise source after exception
autocapture landed (MUL-3331 / MUL-3330).
Add a per-tab-session fuse in before_send, after redaction: fingerprint
the already-redacted exception (type + redacted value + one deterministic
stack frame incl. colno), keep the first 3 per (session, fingerprint),
drop the rest. State lives in sessionStorage as a hash->count blob, so no
PII is persisted. Every storage failure fails open (keep the event);
before_send never throws.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
* feat(diagnostics): global 60s cooldown for client_unresponsive
A single sustained freeze is delivered as several long-task entries, so
emitting per entry made client_unresponsive volume grow without bound
with the freeze length (MUL-3331). Cap it with a module-level (page-
lifetime) global cooldown: at most one event per 60s window. No route
bucketing — a global window is the most direct cap on volume.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
* test(analytics): add exception-dedupe safety matrix
This file was written alongside the dedupe implementation but missed the
original commit, so the $exception fail-open / cap / fingerprint matrix
never landed on the branch. No implementation change — the tests pass as
written against the existing exception-dedupe.ts.
Covers: first-3-then-drop, fingerprint independence, colno discrimination,
hash-only storage (no PII), degraded/missing frames, undefined / throwing
/ corrupt-JSON sessionStorage fail-open, setItem-failure under-counts, and
the distinct-fingerprint cap (51st new fingerprint kept).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>