ποΈ Event Architecture
UNIFIED EVENT PIPELINE
Gateway Events
Runtime telemetry via SSE. Lifecycle, tools, activity.
ephemeralBridge Events
Transport layer. 38 event types. Dispatch, CRUD, security.
SSE + selective persistPlatform Events
Business logic in Convex. Workflows, governance, approvals.
365-day TTLConvex Runtime
System-level log stream. Functions, OCC, console.
ephemeralβ
Normalization Layer. event-normalizer.ts
All events converted to NormalizedEvent envelope: id, source, category, timestamp, payload. Three normalizers (gateway, bridge, runtime). 16 semantic categories.
operator surfacesβ
/observe
Unified live timeline
SSE + audit events merged
/analytics
Cost and token economics
Aggregates + time-series
/audit
Persistent compliance record
365-day append-only table
Bridge Audit Relay22 event types selectively persisted to audit table
π‘ Four Event Sources
Every observable signal in the platform originates from one of four sources. Each has different transport characteristics, lifetime guarantees, and use cases.| Source | Origin | Transport | Lifetime | Primary Surface |
|---|---|---|---|---|
| Gateway Events | Gateway WebSocket relay | SSE (ephemeral) | In-memory buffer (500 events) | /observe |
| Bridge Events | Bridge server | SSE (ephemeral) | In-memory buffer + selective persistence | /observe, /audit |
| Platform Events | Convex mutations | Append-only table | 365-day TTL | /audit |
| Convex Runtime | Convex log stream | SSE (ephemeral) | In-memory buffer | /observe |
Ephemeral events (gateway, bridge, Convex runtime) live only in the browserβs in-memory buffer. Selected bridge events are persisted to the audit table by the Bridge Audit Relay β a render-nothing React component that subscribes to the SSE wildcard and writes 22 audit-worthy event types to Convex.
πΊ Live Monitoring
The observe layer merges two event streams into a single chronological timeline:- SSE events from the
useUnifiedEventshook β gateway telemetry, bridge activity, and Convex runtime logs, all normalized into theNormalizedEventenvelope - Convex audit events from
auditEvents.byTimeRangeβ persistent platform events converted into the same envelope viaauditToNormalized()
Filtering
The observe layer provides four facets for narrowing the view:| Facet | Options |
|---|---|
| Source | All, Gateway, Bridge, Convex Audit, Convex Backend |
| Time range | 5m, 15m, 1h, 24h, All |
| Category | 16 toggle-able categories (convex_function defaults to off) |
| Text search | Matches against event name, display label, agent ID, resource ID |
π Activity Stream
The/logs page provides a terminal-style view of gateway log output, displaying BridgeLogPayload events with level, message, and agent context. This is the raw diagnostic feed from the gateway runtime.
For a higher-level operational view, the InterventionCenter sidebar component surfaces items requiring immediate operator attention:
- Pending approvals with wait-time display
- Recent failures filtered by
workflow_failed,step_failed,safety_gate_blocked,deployment_failed
auditEvents.recent and the pending approvals table to provide at-a-glance health awareness without navigating away from the current page.
π§ Event Normalization
All events flowing through the platform are converted into a singleNormalizedEvent envelope:
| Normalizer | Source | Key Behavior |
|---|---|---|
normalizeGatewayEvent | Gateway WebSocket | Handles double-nested payload.data.data structure. Refines the "agent" event type into lifecycle, tool, assistant, thinking, error by inspecting the stream sub-field. |
normalizeBridgeEvent | Bridge SSE | Unwraps the bridge EventBus wrapper pattern. Prefixes event names with bridge: for category classification. |
normalizeConvexRuntimeEvent | Convex log stream | Sets source to "convex_runtime". Generates display labels highlighting anomalies: function failures, OCC conflicts, slow execution, console errors. |
lifecycle, tool, chat, assistant, thinking, error, cron, system, agent_crud, skill, security, session, step, process, convex_console, convex_function.
The Bridge Audit Relay
The Bridge Audit Relay is the critical seam between ephemeral and persistent observability. It is a render-nothing React component that subscribes to the bridge SSE wildcard ("*") and selectively persists events to the Convex auditEvents table.
What gets persisted: 22 event types organized in two layers:
- Layer 1 β Platform governance (13 events): Agent CRUD (5), skill changes (3), security posture, gateway health, config reload, session compaction lifecycle (2)
- Layer 2 β Agent execution (7 events):
agent.lifecycle.start/end/error,agent.tool.start/end/result,agent.activity - Convex runtime (2 events):
convex.console(ERROR only),convex.function(failures, OCC conflicts, and system limit warnings only)
π° Cost Tracking
Token cost flows through a four-stage pipeline:Capture
Every LLM interaction creates a
tokenEvents record with input, output, thinking, cache-read, and cache-write token counts. Cost is computed at write time using live pricing from the Convex Model Registry, stored as costAtCapture with a pricingSnapshot for auditability.Hourly Aggregation
A cron runs every hour, scanning the last 2-hour window of
tokenEvents and grouping them into costAggregates documents keyed by time bucket, agent, and model dimensions.Daily Aggregation
A second cron runs every 24 hours, scanning the last 2 days of raw events into daily buckets.
tokenEvents.summary query intelligently combines pre-computed aggregates for full-hour windows with raw event scans for partial hours at range boundaries, keeping arbitrary time-range queries fast even with millions of events.
π Gateway Health
A Convex cron runs every 60 seconds, pingingGET /api/health on every registered gateway with a 10-second timeout. All gateways are pinged in parallel via Promise.allSettled.
| Response | Status |
|---|---|
HTTP 200 with status: "degraded" in body | degraded |
| HTTP 200 (any other body) | healthy |
| Any error or timeout | offline |
lastHealthCheck timestamp is written on every check for recency tracking. When the status actually changes, a transition is recorded in gatewayHealthHistory for the 90-day audit trail.
ποΈ Data Retention
| Data Type | Retention | Managed By |
|---|---|---|
| Audit events | 365 days | Daily cron at 03:15 UTC |
| Token events (raw) | 90 days | Daily cron at 03:00 UTC |
| Hourly cost aggregates | 30 days (then rolled into daily) | Weekly compaction cron |
| Daily cost aggregates | 90 days (then rolled into weekly) | Weekly compaction cron |
| Gateway health history | 90 days | Retention cron |
| SSE events (ephemeral) | In-memory only | Browser session |
For trace-level execution visibility, see Traces. For cost analytics and budgets, see Analytics & Cost. For the compliance audit log, see Audit Trail.

