Track B Phase 3 (CR-7) — governance event types on the live feed
2026-06-21
LOCKSTEP TRACEABILITY MATRIX --- api_endpoints: ["GET /auth/events — extended event vocabulary (no new route)"] sdk_methods_updated: ["none"] mcp_tools_updated: ["none"] ---
What We Built
The dashboard's SSE stream (GET /auth/events) previously carried only operational types (request | budget | circuit | security | cache | ping). CR-7 adds the governance vocabulary the Phase 3 LIVE ● feed subscribes to: scope_denial, would_deny, grant_issued, grant_revoked, chain_break. Each is a real decision or authority mutation with a flat, small payload ({ principal, requestId?, grantId?, source?, requested?, reason?, ts }), emitted at the chokepoint that already exists:
scope_denial/would_denyriderecordAuthorizationDenial— the single point every enforced denial and warn-mode would-deny already passes through. The event fires the instant the decision is made, independent of whether the durable chain write succeeds (the decision already happened; enforcement is unaffected).grant_issued/grant_revokedriderecordGrantLifecycle— the shared hook for issue/attenuate/revoke across both the apiKey/v1/grantsand JWT/auth/grantssurfaces, so one emission point covers them all.chain_breakis declared and emittable; its producer is the audit-verify path (a follow-on Phase 3 slice).
Why It Matters
Phase 1's evidence view was honest but static — an operator refreshed to see what happened. CR-7 makes governance _live_: a scope denial, a would-deny preview, or a break-glass revoke appears on the operator's feed the moment it occurs, with the principal and reason attached. It's the substrate the would-deny preview and the Ledger's live tail are built on.
How It Works
emitGovernanceEvent(tenantId, type, payload) (in sse-broadcaster.ts) stamps ts and fans out through the existing SSEBroadcaster — fire-and-forget, swallowing its own errors so the live feed can never affect the act it describes. Clients filter via ?types=scope_denial,grant_revoked,…; the VALID_TYPES allowlist in the /auth/events capability was extended in lockstep so the new types are subscribable.
The Numbers
- 5 governance event types; 3 new tests (delivery +
tsstamping, type-filter drop,formatSSEline). - 9,029 unit tests pass;
pnpm checkgreen. No new route, no SDK/MCP surface — an additive event vocabulary on an existing stream.
Competitive Edge
Plenty of gateways stream request logs. Streaming _governance decisions_ — "agent X was denied tool:shell, here's why" and "grant g9 was just revoked, cascade" — as first-class typed events is the evidence plane in real time.
Lockstep Checklist
- [x] API Routes:
/auth/eventsvocabulary extended; emission wired atrecordAuthorizationDenial+recordGrantLifecycle. - [x] TS/Python SDK: none.
- [x] MCP Schemas: none.
- [x] Tests: 3 new broadcaster tests; full suite green.
Remaining (Phase 3)
Frontend consumption (the LIVE ● feed wiring the new types into the Ledger/Grants surfaces), the chain-verify badge (CR-1, against the existing /auth/governance/audit/verify), chain_break emission from the verify path, the would-deny preview UI (CR-3), and effective-state badges (CR-2/CR-5). Phase 4 (Plans) after.