bf5c358668
Subscribe/unsubscribe with per-event authorization via Directus delegation: - src/live/authz.ts: createAuthzClient factory; canAccessEvent(cookieHeader, eventId) calls GET /items/events/<id>?fields=id, delegates row-level security to Directus (200=allow, 403=forbidden, 404=not-found, else error). - src/live/registry.ts: createSubscriptionRegistry with bidirectional indexes (WeakMap<conn, topics> + Map<topic, conns>); subscribe/unsubscribe/ onConnectionClose/connectionsForTopic/topicsForConnection/stats. Authorization runs once at subscribe time. Snapshot is stubbed as [] until task 1.5.5. Includes pluggable SnapshotProvider interface for task 1.5.5 injection. - src/live/protocol.ts: adds 'error' to ErrorCode union for transient authz failures. - src/main.ts: wires createAuthzClient + createSubscriptionRegistry; replaces the stub message handler with the real subscribe/unsubscribe router; passes registry.onConnectionClose as the server's onClose callback. - test/live-authz.test.ts: 6 unit tests for all canAccessEvent outcomes. - test/live-registry.test.ts: 9 unit tests for subscribe/unsubscribe semantics, idempotency, gauge correctness, and onConnectionClose cleanup.