Skip to content

bug(frontend): free users flood classify-event with ~95k tier_403/day since #4779 premium-gated it — client callsite bypasses premiumFetch gating, no 403 backoff #4865

Description

@koala73

Evidence (Axiom wm_api_usage)

Since 2026-07-04 ~17:30 UTC — 6 minutes after the #4779 deploy (17:24, "quota direct llm endpoints") — free-plan logged-in users have been generating a sustained tier_403 flood on the newly premium-gated endpoint:

day route 403s distinct free users
07-04 (from 17:30) /api/intelligence/v1/classify-event 13,978 222
07-05 (partial day) /api/intelligence/v1/classify-event 94,444 328

Per-user cadence is ~1/min sustained for 20+ hours (top user: 2,286 rejections) — a polling/per-event loop, not manual retries.

What this means

#4779 premium-gated classify-event server-side AND claimed the generated client routes through premiumFetch. The server gate is working (403s are correct). But the client keeps calling it for free users — either a consumer callsite that doesn't route through premiumFetch (the audit-every-consumer pattern), a call issued before entitlement state hydrates that then retries per event, or missing 403 backoff in the caller.

Impact:

  • Whatever free-tier UX consumed event classification is now silently failing ~95k times/day (if the feature was intended to stay free, the gate itself is misapplied — decide which).
  • ~95k/day wasted edge requests + Axiom ingest + rate-limit pressure.
  • 403 noise this loud buries genuine auth incidents in the usage telemetry (this was found while investigating an unrelated P0).

Fix directions

  1. Decide intent: was classify-event supposed to remain callable for free users (with quota) or be Pro-only? fix(api): quota direct llm endpoints #4779's body says premium-gate, so presumably Pro-only.
  2. Audit every client callsite of classify-event (not just the generated client) and gate on entitlement before dispatch; found sites must stop the per-event loop for free users.
  3. Add 403-response backoff/circuit-breaking to the calling service so a future gating change can't produce an unbounded retry flood.
  4. Verify in Axiom after deploy: free-user 403s on this route should drop to ~0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions