Files
buzz/crates
DuncanandWill Pfleger b1bb270fe9 fix(relay): exempt ephemeral events from Messages quota; add limit_type observability
Ephemeral events (kinds 20000–29999) are never persisted by storage, yet
WS admission billed them against the per-minute durable Messages budget.
With buzz-acp publishing up to 90 observer frames/min + 20 typing
indicators/min/channel + 1 presence/min, agents consumed ~111 of their
120/min Messages budget on pure telemetry, causing repeated 40s quota
stalls that blocked real message delivery.

Changes:
- WS admission now skips LimitType::Messages for ephemeral kinds, using
  the existing is_ephemeral() range predicate (same one storage uses to
  refuse persistence — admission and storage now agree by construction).
  Ephemeral events still count against WsEvents so per-second burst
  protection remains intact.
- Add agent_ws_events_per_sec to RateLimitConfig (env:
  BUZZ_RATE_LIMIT_AGENT_WS_EVENTS_PER_SEC). Agents previously inherited
  human_ws_events_per_sec silently. Default matches human default (10/s)
  so this is behavior-neutral at merge; tune on builderlab once
  limit_type instrumentation data is available.
- Delete three dead tier fields that were defined and env-loadable but
  enforced nowhere: agent_elevated_messages_per_min,
  agent_platform_messages_per_min, agent_standard_api_calls_per_min.
- Add limit_type to NOTICE/CLOSED rejection text (format: 'quota exceeded
  ({limit_type}); retry in {N}s' — the 'retry in Ns' phrase is preserved
  for client parsers) and to buzz_admission_rejections_total metric as a
  new label on both WS and HTTP paths.

Post-deploy validation: ACP Messages rejections should drop to ~0;
any residual >5s retry hint on the WS path indicates an unenumerated
durable WS publisher.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-08-05 11:26:54 -04:00
..
2026-07-27 14:18:24 -04:00