Orchestrata Ultimate / Specs / 014-websocket-gateway

014-websocket-gateway: WebSocket Gateway

The WebSocket Gateway is the real-time control plane for Orchestrata. It exposes a bidirectional WebSocket server that allows external clients (web dashboards, CLI tools, mobile apps, external integrations) to observe and control the orchestration system in real-time. Clients can subscribe to CXP traffic, monitor Volk status, inspect governance decisions, query session state, and issue commands to the kernel — all through a structured RPC protocol over WebSocket.

At a glance

Item Value
Spec directory specs/014-websocket-gateway/
Status line in the spec Implemented
Requirement IDs defined 207
With a @traces citation in src/ 104 (50.2%)
With a @traces citation in tests/ 25 (12.1%)
Tracked files 7
RTM page 014-websocket-gateway

Reading this spec

The WebSocket Gateway is the real-time control plane of Orchestrata. It exposes a bidirectional WebSocket server so that external clients (web dashboards, CLI tools, mobile apps and integrations) can observe and control the orchestration system as it runs. Before it, the kernel, postman and orchestrator communicated only internally and were invisible from outside, and there was no way to start sessions or dispatch CXP packets remotely.

The scope is ten user stories: real-time CXP traffic observation, Volk status monitoring, a governance decision stream, session state inspection, remote command execution and gateway authentication (priority 1), then client presence and heartbeat, event replay and history, a metrics and health endpoint, and live knowledge graph queries (priority 2). Requirement IDs use the REQ-014- prefix.

The key decisions are an IGatewayServer interface registered in the DI container as ComponentType.GATEWAY; a server built on the websockets library on a configurable port (default 18790); token-based authentication with configurable strategies; JSON-RPC 2.0 for requests, responses and server-push notifications; a publish and subscribe model for event streams; an RPCDispatcher that routes calls to registered handlers with PAM++ authorization; gateway sessions that track clients with heartbeat and presence; and an audit trail of all gateway operations in Neo4j.

In the code, the package is orchestrata_ultimate/gateway. The largest tracers are orchestrata_ultimate/gateway/server, orchestrata_ultimate/gateway/handlers/session, orchestrata_ultimate/gateway/auth, orchestrata_ultimate/gateway/metrics and orchestrata_ultimate/gateway/handlers/volk. The per-requirement view is on the RTM page.

The spec's status line reads Implemented. It tracks 7 files and defines 207 requirement IDs. The full text follows below.

Measured coverage is 104 of 207 requirements cited by at least one @traces in src/ (50.2%), spread over 34 modules; the module citing the most of them is orchestrata_ultimate/gateway/server (20 requirements). In tests/, 25 requirements are cited by a test-side @traces.

Coverage gaps: 103 requirements have no citing symbol. The largest untraced groups are REQ-014-* (103). Untraced means no @traces names the ID; the behaviour may still exist in code that was never annotated. Test-side citations are thinner than code-side ones (25 against 104).

Requirements

Checkbox is the state recorded in the requirements checklist; Traced by is the count of src/ symbols whose @traces names the ID.

ID Done Requirement Traced by
REQ-014-001 no Client subscribes to CXP traffic via cxp.subscribe RPC method 2
REQ-014-002 no Server pushes CXP packets as they flow through the kernel 2
REQ-014-003 no Subscription supports filtering by volk_id (TO or FROM) 1
REQ-014-004 no Subscription supports filtering by thread_id none
REQ-014-005 no Subscription supports filtering by subject pattern (glob match) 1
REQ-014-006 no Subscription supports filtering by delivery_status none
REQ-014-007 no Multiple filters combine with AND semantics 2
REQ-014-008 no Client unsubscribes via cxp.unsubscribe with subscription_id 2
REQ-014-009 no Packet payloads optionally truncated (configurable max_payload_size) none
REQ-014-010 no Subscription confirmation includes subscription_id and active filter summary none
REQ-014-011 no Client queries CXP packet status via cxp.status with thread_id 2
REQ-014-012 no Status response includes delivery_status, work_status, timestamps none
REQ-014-013 no Status query returns history of status transitions none
REQ-014-014 no Status query handles unknown thread_id with clear error none
REQ-014-015 no Status query respects PAM++ authorization none
REQ-014-016 no Client calls volk.list to get all registered Volks 3
REQ-014-017 no Each Volk entry includes: alias, capabilities, health, active_tasks, last_activity 2
REQ-014-018 no Client calls volk.get with alias for detailed Volk information 2
REQ-014-019 no Detailed info includes: registration_time, protocols, resource_usage, session_id none
REQ-014-020 no Volk list supports pagination (offset, limit) none
REQ-014-021 no Client subscribes to volk.lifecycle events 1
REQ-014-022 no Events include: registered, deregistered, health_changed, task_started, task_completed none
REQ-014-023 no Each event includes volk_alias, event_type, timestamp, details 1
REQ-014-024 no Status updates pushed within 500ms of state change none
REQ-014-025 no Subscription supports filtering by volk_alias none
REQ-014-026 no Client registers new Volk via volk.register (admin scope required) 4
REQ-014-027 no Registration validates alias uniqueness and capability schema none
REQ-014-028 no Client deregisters Volk via volk.deregister (admin scope required) 4
REQ-014-029 no Deregistration handles in-flight messages gracefully none
REQ-014-030 no Management operations logged to audit trail none
REQ-014-031 no Client subscribes to governance.decisions stream 2
REQ-014-032 no Each decision includes: volk_id, action, resource, result (allow/deny) none
REQ-014-033 no Each decision includes: prolog_query, evaluation_latency_ms none
REQ-014-034 no Escalation events included with full escalation path and parties none
REQ-014-035 no Constitutional article violations include article reference and text none
REQ-014-036 no Client queries historical decisions via governance.query 2
REQ-014-037 no Query supports time range filter (date_from, date_to) none
REQ-014-038 no Query supports filtering by volk_id, result, action none
REQ-014-039 no Query results paginated (offset, limit) none
REQ-014-040 no Query results sorted by timestamp descending none
REQ-014-041 no Client evaluates governance check via governance.evaluate (read-only) 3
REQ-014-042 no Dry-run returns would-be result without side effects none
REQ-014-043 no Dry-run includes Prolog trace showing rule evaluation path none
REQ-014-044 no Dry-run logged as audit event with type "dry_run" none
REQ-014-045 no Dry-run requires read_write scope minimum none
REQ-014-046 no Client lists active Prolog rules via governance.rules (admin scope) 1
REQ-014-047 no Rules returned grouped by category (routing, permission, escalation, budget) none
REQ-014-048 no Each rule includes: predicate, arity, source_file, line_number none
REQ-014-049 no Rule listing supports filtering by category none
REQ-014-050 no Rule listing supports full-text search on predicate names none
REQ-014-051 no Client calls session.list to see all active sessions 2
REQ-014-052 no Each session entry includes: id, portfolio_id, status, opened_at, goals none
REQ-014-053 no Client calls session.get with session_id for full state 2
REQ-014-054 no Full state includes: context, facts, carryover_tasks, duration, summary 2
REQ-014-055 no Session list supports filtering by portfolio_id and status none
REQ-014-056 no Client subscribes to session.events for lifecycle events 2
REQ-014-057 no Events include: opened, closed, recovered, context_updated, error_occurred 1
REQ-014-058 no Each event includes session_id, event_type, timestamp, details 1
REQ-014-059 no Client subscribes to session.facts.subscribe for fact emission events 2
REQ-014-060 no Fact events include fact_type, session_id, data, timestamp none
REQ-014-061 no Client opens new session via session.open (read_write scope) 2
REQ-014-062 no Session open accepts: portfolio, goals, context none
REQ-014-063 no Client closes session via session.close (read_write scope) 2
REQ-014-064 no Session close accepts: session_id, status, summary, carryover_tasks 2
REQ-014-065 no Session control operations respect PAM++ governance none
REQ-014-066 no Client queries portfolio stats via session.portfolio.stats none
REQ-014-067 no Stats include: total_sessions, total_duration, completion_rate, active_count none
REQ-014-068 no Stats support filtering by portfolio_id none
REQ-014-069 no Stats cached in Redis with 5-minute TTL none
REQ-014-070 no Stats queryable with time range filter none
REQ-014-071 no Client sends CXP packet via cxp.send (read_write scope) 6
REQ-014-072 no CXP packet validated against SPEC-004 schema before dispatch none
REQ-014-073 no PAM++ validates sender authority before routing none
REQ-014-074 no Response includes delivery_status and routing decision none
REQ-014-075 no Failed dispatch returns structured error with reason 2
REQ-014-076 no Client triggers workflow via workflow.start (read_write scope) 11
REQ-014-077 no Client pauses workflow via workflow.pause (read_write scope) 9
REQ-014-078 no Client resumes workflow via workflow.resume (read_write scope) 10
REQ-014-079 no Client cancels workflow via workflow.cancel (read_write scope) 9
REQ-014-080 no Workflow commands validated against PAM++ governance 9
REQ-014-081 no Client queries current config via config.get (read_only scope) 9
REQ-014-082 no Client queries config by key path via config.get with path parameter 4
REQ-014-083 no Configuration values with secrets are redacted in responses 2
REQ-014-084 no Config response includes last_updated timestamp 6
REQ-014-085 no Config changes not permitted via gateway (read-only for safety) 2
REQ-014-086 no Client authenticates via auth.authenticate RPC method 3
REQ-014-087 no Authentication required before any other RPC method 1
REQ-014-088 no Unauthenticated RPC calls return JSON-RPC error code -32001 (Unauthorized) none
REQ-014-089 no Unauthenticated clients disconnected after grace period (default: 5s) 2
REQ-014-090 no Authentication events logged to audit trail none
REQ-014-091 no Static token configured via gateway config or GATEWAY_TOKEN env var 2
REQ-014-092 no Token comparison uses constant-time algorithm (hmac.compare_digest) 1
REQ-014-093 no Empty or missing tokens rejected immediately 2
REQ-014-094 no Token rotation supported via Redis-backed token store 1
REQ-014-095 no Static token auth returns read_write scope by default 1
REQ-014-096 no HMAC signature computed as HMAC-SHA256(secret, timestamp + nonce + client_id) 2
REQ-014-097 no Timestamp drift rejected if > configurable window (default: 60s) 1
REQ-014-098 no Nonce replay rejected within drift window (Redis-tracked) 1
REQ-014-099 no Multiple shared secrets supported for key rotation 1
REQ-014-100 no HMAC auth returns scope from client_id to scope mapping 1
REQ-014-101 no Prolog queried for gateway_access(ClientId, Scope) on auth 1
REQ-014-102 no Scoped access enforced: read_only, read_write, admin 1
REQ-014-103 no Auth decisions cached in Redis with configurable TTL (default: 300s) none
REQ-014-104 no Cache invalidated on Prolog rule changes none
REQ-014-105 no Policy auth failure includes reason from Prolog evaluation none
REQ-014-106 no Server sends WebSocket ping every heartbeat_interval (default: 30s) 1
REQ-014-107 no Client must respond with pong within heartbeat_timeout (default: 10s) none
REQ-014-108 no Client disconnected after heartbeat_max_misses consecutive missed pongs (default: 3) 1
REQ-014-109 no last_activity updated on any client message (not just pong) 2
REQ-014-110 no Heartbeat timing configurable per gateway instance 1
REQ-014-111 no Connected client list queryable via gateway.clients 3
REQ-014-112 no Each client entry includes: client_id, connected_at, last_activity, auth_scope, subscriptions 2
REQ-014-113 no Client provides metadata on connection (client_name, client_version, purpose) none
REQ-014-114 no Presence events pushed to gateway.presence subscribers 1
REQ-014-115 no Presence events include: connected, disconnected, timeout, metadata_updated none
REQ-014-116 no Disconnected client subscriptions cleaned up immediately none
REQ-014-117 no Client session removed from Redis on disconnect none
REQ-014-118 no Disconnect event logged to audit trail none
REQ-014-119 no Disconnect reason tracked: clean_close, timeout, error, server_shutdown none
REQ-014-120 no Connection cleanup completes within 1 second none
REQ-014-121 no Gateway maintains event ring buffer in Redis (configurable size, default: 10,000) 2
REQ-014-122 no Events stored as Redis sorted set with timestamp score none
REQ-014-123 no Events older than ring_buffer_ttl auto-expired (default: 24h) none
REQ-014-124 no Ring buffer write latency < 5ms per event none
REQ-014-125 no Buffer overflow evicts oldest events 2
REQ-014-126 no Client requests replay via gateway.replay with time range (since, until) none
REQ-014-127 no Client requests replay via gateway.replay with event count (last N events) 2
REQ-014-128 no Replay supports topic filter 2
REQ-014-129 no Replay supports same filters as live subscriptions none
REQ-014-130 no Replay delivers events in chronological order none
REQ-014-131 no Each event carries monotonically increasing sequence number per topic 2
REQ-014-132 no Client detects gaps via sequence numbers none
REQ-014-133 no Gap notification includes missing sequence range none
REQ-014-134 no Client can request gap fill via gateway.replay with sequence range none
REQ-014-135 no Sequence counter persisted in Redis across gateway restarts none
REQ-014-136 no HTTP /health endpoint returns 200 OK when gateway is operational 2
REQ-014-137 no HTTP /health returns 503 when gateway is degraded or shutting down none
REQ-014-138 no HTTP /ready checks Redis, Neo4j, Prolog, and kernel health 1
REQ-014-139 no /ready returns 200 only when all dependencies are healthy none
REQ-014-140 no Health check responses include component-level detail 2
REQ-014-141 no HTTP /metrics returns Prometheus text format 1
REQ-014-142 no Metric: orchestrata_gateway_connected_clients (gauge) 2
REQ-014-143 no Metric: orchestrata_gateway_total_connections (counter) 1
REQ-014-144 no Metric: orchestrata_gateway_messages_received_total (counter) 1
REQ-014-145 no Metric: orchestrata_gateway_messages_sent_total (counter) 1
REQ-014-146 no Metric: orchestrata_gateway_rpc_latency_seconds (histogram, by method) 1
REQ-014-147 no Metric: orchestrata_gateway_subscription_count (gauge, by topic) 2
REQ-014-148 no Metric: orchestrata_gateway_auth_success_total (counter) 1
REQ-014-149 no Metric: orchestrata_gateway_auth_failure_total (counter) 1
REQ-014-150 no Metric: orchestrata_gateway_events_dropped_total (counter, by topic) none
REQ-014-151 no Client calls knowledge.query with Cypher query string 3
REQ-014-152 no Queries validated as read-only (MATCH, RETURN, WITH, OPTIONAL MATCH only) none
REQ-014-153 no Mutations rejected (MERGE, CREATE, DELETE, SET, REMOVE, DETACH) 1
REQ-014-154 no Query timeout enforced (configurable, default: 10s) 1
REQ-014-155 no Results returned as JSON-serializable node/relationship structures 1
REQ-014-156 no Client calls knowledge.nodes with node_type and pagination 1
REQ-014-157 no Client calls knowledge.relationships with relationship_type and pagination 1
REQ-014-158 no Node results include all properties and labels none
REQ-014-159 no Relationship results include source, target, type, and properties none
REQ-014-160 no Browsing supports filtering by property values none
REQ-014-161 no PAM++ controls which clients can query which graph segments none
REQ-014-162 no Prolog predicate gateway_can_query_kg(ClientId, QueryPattern) enforced none
REQ-014-163 no Query audit records stored in Neo4j none
REQ-014-164 no Query results capped at configurable max_results (default: 1000) none
REQ-014-165 no Query execution time included in response metadata none
REQ-014-166 no Server starts on configured host:port (default: 0.0.0.0:18790) 6
REQ-014-167 no Server accepts concurrent connections up to max_clients (default: 100) none
REQ-014-168 no Server handles connection open, message, close, error events 3
REQ-014-169 no Server supports TLS when cert and key paths configured none
REQ-014-170 no Server gracefully shuts down on SIGTERM, closing all connections 4
REQ-014-171 no Messages follow JSON-RPC 2.0 specification none
REQ-014-172 no Requests have: jsonrpc, id, method, params none
REQ-014-173 no Responses have: jsonrpc, id, result or error 2
REQ-014-174 no Server-push notifications have: jsonrpc, method, params (no id) 2
REQ-014-175 no Batch requests supported (array of JSON-RPC messages) none
REQ-014-176 no Parse error returns JSON-RPC code -32700 1
REQ-014-177 no Invalid request returns JSON-RPC code -32600 1
REQ-014-178 no Method not found returns JSON-RPC code -32601 1
REQ-014-179 no Invalid params returns JSON-RPC code -32602 none
REQ-014-180 no Internal error returns JSON-RPC code -32603 2
REQ-014-181 no Unauthorized returns custom code -32001 none
REQ-014-182 no Rate limited returns custom code -32002 none
REQ-014-183 no Budget exceeded returns custom code -32003 none
REQ-014-184 no Maximum message size enforced (configurable, default: 1MB) none
REQ-014-185 no Oversized messages rejected with error none
REQ-014-186 no Rate limiting per client (configurable, default: 500 req/sec) none
REQ-014-187 no Rate limited clients receive -32002 error none
REQ-014-188 no WebSocket origin validation configurable none
REQ-014-189 no Per-client event buffer (configurable, default: 1000 events) none
REQ-014-190 no Buffer overflow drops oldest events and notifies client none
REQ-014-191 no Gap notification includes dropped count and sequence range none
REQ-014-192 no Events delivered asynchronously without blocking kernel EventBus 2
REQ-014-193 no Event serialization happens once, shared across subscribers 2
REQ-014-194 no Maximum subscriptions per client enforced (configurable, default: 50) none
REQ-014-195 no Subscription limit exceeded returns structured error none
REQ-014-196 no Subscriptions cleaned up on client disconnect 1
REQ-014-197 no Duplicate subscription to same topic+filter returns existing subscription_id none
REQ-014-198 no Subscription count per topic queryable via gateway.info none
REQ-014-199 no gateway.info returns: version, uptime, capabilities, topic list 3
REQ-014-200 no gateway.ping returns server timestamp for latency measurement 1
REQ-014-201 no Gateway capabilities list includes supported RPC methods none
REQ-014-202 no Gateway uptime measured from server start time 1
REQ-014-203 no METHODS (gateway/method_table.py) is the single declarative table of gateway methods (name, handler dotted path, mutates defaulting to true, expose, optional params_schema), importable without constructing any handler; RPCHandler's dispatch dict is built from it and equals it 2
REQ-014-204 no orchestrata-mcp is a stdio MCP server that is a WebSocket JSON-RPC client of the running gateway at GATEWAY_HOST:GATEWAY_PORT, authenticating with GATEWAY_TOKEN from the deployed environment (never a flag, never the ledger); its tool list is generated from METHODS (one tool per exposed method plus approve), so a method added to the table appears with no transport edit 2
REQ-014-205 no A mutating tool call needs a single-use, tool-bound, 300 s token issued by approve; without one it is refused with {"message":"PERMISSION_DENIED","capability":&lt;tool>,"ledger_row":&lt;id>} and nothing reaches the gateway; reuse, forgery, cross-tool use, approve on a read-only tool and unknown tools are refused with a ledger row; the token never appears in the ledger 3
REQ-014-206 no Streaming methods, legacy aliases and auth.authenticate are expose=False and absent from the tool list; a method not marked read-only is gated (fails closed) 1
REQ-014-207 no deploy/install-claude-config.sh registers codetools and orchestrata at user scope from the deployed release paths (idempotently, through the Claude CLI), writes the flat registration document, and refuses success unless each registered command resolves inside its deployed release none

Code that traces this spec

Module Symbols Requirements
orchestrata_ultimate/gateway/auth 2 10
orchestrata_ultimate/gateway/auth_handler 5 6
orchestrata_ultimate/gateway/cli 2 4
orchestrata_ultimate/gateway/exceptions 1 1
orchestrata_ultimate/gateway/handlers/_policy_gate 2 1
orchestrata_ultimate/gateway/handlers/_scope_guard 2 3
orchestrata_ultimate/gateway/handlers/auth 2 2
orchestrata_ultimate/gateway/handlers/config 3 5
orchestrata_ultimate/gateway/handlers/cxp 7 5
orchestrata_ultimate/gateway/handlers/gateway 6 6
orchestrata_ultimate/gateway/handlers/governance 8 4
orchestrata_ultimate/gateway/handlers/knowledge 6 6
orchestrata_ultimate/gateway/handlers/session 7 10
orchestrata_ultimate/gateway/handlers/volk 10 7
orchestrata_ultimate/gateway/handlers/workflow 7 5
orchestrata_ultimate/gateway/http_surface 4 3
orchestrata_ultimate/gateway/kernel_reprobe 5 4
orchestrata_ultimate/gateway/mcp_approval_gate 1 1
orchestrata_ultimate/gateway/mcp_ledger 1 1
orchestrata_ultimate/gateway/mcp_tool_spec 1 1
orchestrata_ultimate/gateway/mcp_transport 1 3
orchestrata_ultimate/gateway/method_spec 1 1
orchestrata_ultimate/gateway/metrics 9 8
orchestrata_ultimate/gateway/models 2 2
orchestrata_ultimate/gateway/protocol 4 4
orchestrata_ultimate/gateway/pubsub 4 5
orchestrata_ultimate/gateway/ring_buffer 4 4
orchestrata_ultimate/gateway/rpc 2 2
orchestrata_ultimate/gateway/runtime_config 11 5
orchestrata_ultimate/gateway/server 16 20
orchestrata_ultimate/gateway/session 4 4
orchestrata_ultimate/gateway/workflow_types 8 4
orchestrata_ultimate/kernel/cli_main 1 1
orchestrata_ultimate/orchestrator/pipeline_kernel 9 4

Checklists

checklists/README.md

WebSocket Gateway (U:GW) Checklists

Project: Orchestrata WebSocket Gateway (Spec 014) Component: U:GW (Gateway) Status: Planning Phase Owner: Architecture Team


Overview

The WebSocket Gateway (U:GW) is the real-time control plane for Orchestrata. It exposes a bidirectional WebSocket server that allows external clients to observe and control the orchestration system. The gateway bridges the internal kernel EventBus to external consumers via JSON-RPC 2.0 over WebSocket, with PAM++ authorization on all operations.


Checklist Summary
Checklist Total Items Completed Progress
Requirements 200+ 0 0%
Constitutional Compliance 110+ 0 0%
Testing Plan 350+ 0 0%
TOTAL 660+ 0 0%

Key Responsibilities
1. WebSocket Server and Protocol
2. Authentication and Authorization
3. Real-Time Event Streaming
4. Remote Command Execution
5. Observability

Performance Targets
Metric Target Critical Threshold
Connection Accept <50ms p95 <100ms p99
RPC Dispatch Overhead <10ms p95 <20ms p99
Event Delivery <100ms from kernel event p95 <200ms p99
Max Concurrent Clients 100 50 minimum
Event Broadcast 10,000 events/sec 5,000 events/sec
RPC Throughput 500 req/sec per client 200 req/sec

Checklist Files
1. requirements.md

Functional requirements organized by user stories:

2. constitutional.md

Compliance with all 11 constitutional articles:

3. testing.md

Comprehensive testing strategy:


Integration Points
Upstream Dependencies
Downstream Consumers

Dependencies
Required Services
Required Libraries
Optional Services

References

Last Updated: 2026-03-27 Version: 1.0.0 Maintained By: Architecture Team

checklists/constitutional.md

WebSocket Gateway (U:GW) - Constitutional Compliance

Component: U:GW (Gateway) Spec: 014-websocket-gateway Status: Compliance Review Total Compliance Items: 110+


Overview

This document tracks compliance of the WebSocket Gateway (U:GW) with all 11 articles of the Orchestrata Constitution. The gateway is an external-facing control plane, making constitutional compliance particularly critical — it is the primary attack surface and must enforce governance rigorously.


Article I: Agent Autonomy

Principle: Volks (agents) retain autonomy; the gateway coordinates but does not control.

Compliance Requirements
Autonomy Preservation

Priority: Critical Verification: Integration tests + manual review


Article II: Prolog as Single Source of Truth

Principle: All governance rules are defined in Prolog; the gateway queries Prolog for decisions.

Compliance Requirements
Prolog Integration

Priority: Critical Verification: Prolog integration tests + policy compliance tests


Article III: Session Isolation

Principle: Sessions are isolated; state does not leak between sessions.

Compliance Requirements
State Isolation

Priority: Critical Verification: Session isolation tests + state leak detection


Article IV: Hooks for Extensibility

Principle: The gateway provides extension points for customization without core modification.

Compliance Requirements
Extension Points

Priority: High Verification: Hook registration tests + extension tests


Article V: Minimal Core, Maximal Extension

Principle: Gateway core is minimal; features are added via extensions.

Compliance Requirements
Minimal Core

Priority: High Verification: Core size metrics + extension loading tests


Article VI: Python 3.14t Implementation

Principle: Gateway is implemented in Python 3.14t with modern async patterns.

Compliance Requirements
Python Version
Code Quality

Priority: High Verification: CI/CD checks + static analysis


Article VII: Testing Without Mocks

Principle: Tests use real implementations, not mocks.

Compliance Requirements
Real Systems Testing

Priority: Critical Verification: Test code review + mock detector


Article VIII: Metrics and Observability

Principle: All operations are observable and measurable.

Compliance Requirements
Metrics Collection
Observability

Priority: High Verification: Metrics tests + observability review


Article IX: Graceful Degradation

Principle: System degrades gracefully under failure, does not crash.

Compliance Requirements
Failure Handling
Recovery

Priority: High Verification: Failure injection tests + chaos tests


Article X: Version Compatibility

Principle: APIs are versioned; breaking changes are avoided.

Compliance Requirements
API Versioning

Priority: Medium Verification: Compatibility tests + version migration tests


Article XI: Documentation First

Principle: Documentation precedes implementation.

Compliance Requirements
Design Documentation

Priority: High Verification: Documentation review + doc tests


Summary Statistics
Article Total Items Completed Percentage
Article I (Autonomy) 10 0 0%
Article II (Prolog) 10 0 0%
Article III (Isolation) 10 0 0%
Article IV (Hooks) 10 0 0%
Article V (Minimal Core) 10 0 0%
Article VI (Python 3.14t) 20 0 0%
Article VII (No Mocks) 10 0 0%
Article VIII (Observability) 20 0 0%
Article IX (Degradation) 20 0 0%
Article X (Versioning) 10 0 0%
Article XI (Documentation) 10 0 0%
TOTAL 140 0 0%

Last Updated: 2026-03-27 Version: 1.0.0 Maintained By: Architecture Team

checklists/requirements.md

The requirement list above comes from this file; 0 of 207 checkbox items are ticked.

checklists/testing.md

WebSocket Gateway (U:GW) - Testing Plan

Component: U:GW (Gateway) Spec: 014-websocket-gateway Status: Test Planning Phase Total Test Cases: 350+


Overview

This document defines the comprehensive testing strategy for the WebSocket Gateway (U:GW). All tests follow the strict "no mocking" policy and use real implementations including real WebSocket connections, real Redis, real Neo4j, and real Prolog for governance evaluation.


Test Categories Summary
Category Test Count Purpose Priority
Unit Tests 120+ Core logic validation Critical
Integration Tests 100+ System integration Critical
Contract Tests 30 Protocol compliance High
Performance Tests 60+ Latency & throughput High
Compliance Tests 11 Constitutional compliance Critical
Failure Scenario Tests 40+ Error handling & recovery High
TOTAL 361+

Unit Tests (120+)
WebSocket Server Tests (15 tests)
JSON-RPC Protocol Tests (20 tests)
Authentication Tests (25 tests)
Subscription Management Tests (20 tests)
Event Delivery Tests (20 tests)
Heartbeat Tests (10 tests)
Ring Buffer Tests (10 tests)

Integration Tests (100+)
Kernel EventBus Integration (20 tests)
Redis Integration (20 tests)
Neo4j Integration (15 tests)
Prolog Integration (15 tests)
End-to-End Tests (30 tests)

Contract Tests (30)
JSON-RPC 2.0 Compliance (10 tests)
Event Schema Compliance (10 tests)
IComponent Compliance (10 tests)

Performance Tests (60+)
Connection Performance (15 tests)
RPC Performance (15 tests)
Event Broadcast Performance (15 tests)
Health and Metrics Performance (15 tests)

Compliance Tests (11)

Failure Scenario Tests (40+)
Connection Failures (10 tests)
Dependency Failures (15 tests)
Protocol Failures (10 tests)
Resource Exhaustion (5 tests)

Summary Statistics
Category Test Count Completed Percentage
Unit Tests 120 0 0%
Integration Tests 100 0 0%
Contract Tests 30 0 0%
Performance Tests 60 0 0%
Compliance Tests 11 0 0%
Failure Scenario Tests 40 0 0%
TOTAL 361 0 0%

Last Updated: 2026-03-27 Version: 1.0.0 Maintained By: Architecture Team

Other tracked files

Full spec text

Verbatim from specs/014-websocket-gateway/spec.md; headings are pushed down two levels.

SPEC-014: WebSocket Gateway

Metadata


Overview

What

The WebSocket Gateway is the real-time control plane for Orchestrata. It exposes a bidirectional WebSocket server that allows external clients (web dashboards, CLI tools, mobile apps, external integrations) to observe and control the orchestration system in real-time. Clients can subscribe to CXP traffic, monitor Volk status, inspect governance decisions, query session state, and issue commands to the kernel — all through a structured RPC protocol over WebSocket.

Why
How

User Scenarios

US-001: Real-Time CXP Traffic Observation (P1)

As a developer or monitoring dashboard I want to subscribe to live CXP packet flow between Volks So that I can observe agent communication in real-time

Acceptance Criteria:


US-002: Volk Status Monitoring (P1)

As a system operator I want to see real-time status of all registered Volks So that I can detect failures and monitor agent health

Acceptance Criteria:


US-003: Governance Decision Stream (P1)

As a compliance auditor or developer I want to observe PAM++ governance decisions in real-time So that I can verify policy enforcement and debug authorization issues

Acceptance Criteria:


US-004: Session State Inspection (P1)

As a developer I want to inspect active session state and context So that I can debug session issues and verify state persistence

Acceptance Criteria:


US-005: Remote Command Execution (P1)

As a system operator or external integration I want to issue commands to the orchestration system remotely So that I can control agent workflows without direct process access

Acceptance Criteria:


US-006: Gateway Authentication (P1)

As a security administrator I want to authenticate gateway clients before granting access So that unauthorized clients cannot observe or control the system

Acceptance Criteria:


US-007: Client Presence and Heartbeat (P2)

As the gateway server I want to track connected client health via heartbeat So that stale connections are cleaned up and presence is accurate

Acceptance Criteria:


US-008: Event Replay and History (P2)

As a developer debugging an issue I want to replay recent events from before I connected So that I can see what happened leading up to the current state

Acceptance Criteria:


US-009: Metrics and Health Endpoint (P2)

As a monitoring system (Prometheus, Grafana) I want to scrape gateway health and connection metrics So that I can monitor gateway availability and load

Acceptance Criteria:


US-010: Knowledge Graph Live Query (P2)

As a developer or dashboard I want to query the knowledge graph through the gateway So that I can explore the graph without direct Neo4j access

Acceptance Criteria:


Functional Requirements

Core Gateway

FR-001: IGatewayServer Interface (P1)

FR-002: WebSocket Server (P1)

FR-003: JSON-RPC Protocol (P1)

FR-004: RPC Method Dispatch (P1)

Authentication

FR-005: Authentication Framework (P1)

FR-006: Static Token Auth (P1)

FR-007: HMAC Auth (P2)

FR-008: PAM++ Policy Auth (P2)

Pub/Sub Event Streams

FR-009: Subscription Management (P1)

FR-010: Event Topics (P1)

FR-011: Event Delivery (P1)

Event History

FR-012: Event Ring Buffer (P2)

Gateway Sessions

FR-013: Client Session Tracking (P1)

FR-014: Heartbeat (P2)

RPC Methods

FR-015: CXP Methods (P1)

FR-016: Volk Methods (P1)

FR-017: Session Methods (P1)

FR-018: Governance Methods (P1)

FR-019: Knowledge Graph Methods (P2)

FR-020: Gateway Methods (P1)

Observability

FR-021: HTTP Health Endpoints (P2)

FR-022: Gateway Metrics (P2)

Governance

FR-023: PAM++ Gateway Predicates (P1)

FR-024: Audit Trail (P1)


Non-Functional Requirements

Performance

NFR-001: Connection Handling

NFR-002: Throughput

Reliability

NFR-003: Availability

NFR-004: Data Integrity

Security

NFR-005: Transport Security

NFR-006: Access Control


Technical Design

Architecture
┌────────────────────────────────────────────────────────────────┐
│                    WebSocket Gateway (U:GW)                     │
├────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐         │
│  │   WebSocket   │  │  JSON-RPC    │  │    Auth      │         │
│  │   Server      │──│  Dispatcher  │──│  Framework   │         │
│  │  (websockets) │  │              │  │              │         │
│  └──────────────┘  └──────────────┘  └──────────────┘         │
│         │                 │                 │                    │
│         ▼                 ▼                 ▼                    │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐         │
│  │   Client      │  │   RPC        │  │  Subscription│         │
│  │   Sessions    │  │   Handlers   │  │  Manager     │         │
│  └──────────────┘  └──────────────┘  └──────────────┘         │
│         │                 │                 │                    │
│         ▼                 ▼                 ▼                    │
│  ┌─────────────────────────────────────────────────────┐       │
│  │              Kernel EventBus Integration             │       │
│  │   (subscribes to kernel events, pushes to clients)   │       │
│  └─────────────────────────────────────────────────────┘       │
│         │                 │                 │                    │
│         ▼                 ▼                 ▼                    │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐         │
│  │    Redis      │  │    Neo4j     │  │   Prolog     │         │
│  │  (ring buf,   │  │  (audit,     │  │  (PAM++      │         │
│  │   auth cache) │  │   history)   │  │   gateway)   │         │
│  └──────────────┘  └──────────────┘  └──────────────┘         │
└────────────────────────────────────────────────────────────────┘
Key Interfaces
class IGatewayServer(IComponent, ABC):
    """WebSocket gateway control plane."""

    @abstractmethod
    async def start_serving(self) -> None:
        """Start the WebSocket server and begin accepting connections."""

    @abstractmethod
    async def stop_serving(self) -> None:
        """Gracefully stop the server, closing all client connections."""

    @abstractmethod
    async def broadcast(
        self,
        topic: str,
        event: GatewayEvent,
    ) -> int:
        """Broadcast event to all subscribers of a topic. Returns delivery count."""

    @abstractmethod
    async def send_to_client(
        self,
        client_id: str,
        message: dict,
    ) -> bool:
        """Send a message to a specific client. Returns True if delivered."""

    @abstractmethod
    def get_connected_clients(self) -> list[GatewayClientInfo]:
        """Return list of connected clients with metadata."""

    @abstractmethod
    def get_subscription_count(self, topic: str) -> int:
        """Return number of active subscriptions for a topic."""

    @abstractmethod
    async def replay_events(
        self,
        *,
        topic: str | None = None,
        since: datetime | None = None,
        count: int | None = None,
        filters: dict | None = None,
    ) -> list[GatewayEvent]:
        """Replay events from the ring buffer."""


class IAuthStrategy(Protocol):
    """Protocol for gateway authentication strategies."""

    async def authenticate(
        self,
        credentials: dict,
    ) -> AuthResult:
        """Authenticate a client. Returns AuthResult with scope and client_id."""

    def get_strategy_name(self) -> str:
        """Return the name of this auth strategy."""


class GatewayEvent:
    topic: str
    sequence: int
    timestamp: datetime
    payload: dict
    source: str


class GatewayClientInfo:
    client_id: str
    gateway_session_id: str
    connected_at: datetime
    last_activity: datetime
    auth_scope: str
    subscriptions: list[str]
    client_metadata: dict


class AuthResult:
    authenticated: bool
    client_id: str
    scope: str          # "read_only" | "read_write" | "admin"
    expires_at: datetime | None
    metadata: dict


class GatewayConfig:
    host: str = "0.0.0.0"
    port: int = 18790
    auth_strategy: str = "static_token"      # "static_token" | "hmac" | "prolog_policy"
    static_token: str | None = None
    hmac_secret: str | None = None
    max_clients: int = 100
    heartbeat_interval_seconds: float = 30.0
    heartbeat_timeout_seconds: float = 10.0
    heartbeat_max_misses: int = 3
    max_subscriptions_per_client: int = 50
    event_buffer_per_client: int = 1000
    ring_buffer_size: int = 10000
    ring_buffer_ttl_seconds: int = 86400
    max_message_size_bytes: int = 1_048_576
    tls_cert_path: str | None = None
    tls_key_path: str | None = None
JSON-RPC Message Format

Request:

{
    "jsonrpc": "2.0",
    "id": "req-001",
    "method": "cxp.subscribe",
    "params": {
        "filters": {"volk_id": "U:Cd", "delivery_status": "delivered"}
    }
}

Response:

{
    "jsonrpc": "2.0",
    "id": "req-001",
    "result": {
        "subscription_id": "sub-abc123",
        "topic": "cxp.traffic",
        "filters": {"volk_id": "U:Cd", "delivery_status": "delivered"}
    }
}

Server Push (notification):

{
    "jsonrpc": "2.0",
    "method": "cxp.traffic",
    "params": {
        "sequence": 42,
        "timestamp": "2026-03-27T14:30:22Z",
        "payload": {
            "to": "U:Cd",
            "from": "U:Ox",
            "thread_id": "thread-001",
            "subject": "code_generation_request",
            "delivery_status": "delivered"
        }
    }
}
Redis State Persistence

Client sessions:

orchestrata:gateway:client:{client_id}          — HASH {connected_at, auth_scope, client_metadata}
orchestrata:gateway:clients                      — SET of client_ids

TTL: None (cleaned on disconnect).

Event ring buffer:

orchestrata:gateway:events:{topic}              — ZSET (score=timestamp, member=event_json)
orchestrata:gateway:events:sequence:{topic}     — STRING (int, monotonic counter)

TTL: Configurable (default: 86400s).

Auth nonce tracking (HMAC):

orchestrata:gateway:nonce:{nonce}               — STRING ("used")

TTL: Matches drift window (default: 60s).

Auth decision cache (Prolog policy):

orchestrata:gateway:auth:{client_id}:{scope}    — STRING ("allow" | "deny")

TTL: Configurable (default: 300s).

Neo4j Audit Schema

Nodes:

Relationships:

Prolog Governance Predicates
%% Gateway access control
gateway_access(ClientId, admin) :-
    registered_admin(ClientId).

gateway_access(ClientId, read_write) :-
    registered_operator(ClientId),
    \+ suspended(ClientId).

gateway_access(ClientId, read_only) :-
    registered_client(ClientId),
    \+ suspended(ClientId).

%% Per-method authorization
gateway_can_execute(ClientId, Method) :-
    gateway_access(ClientId, Scope),
    method_requires_scope(Method, RequiredScope),
    scope_sufficient(Scope, RequiredScope).

scope_sufficient(admin, _).
scope_sufficient(read_write, read_write).
scope_sufficient(read_write, read_only).
scope_sufficient(read_only, read_only).

%% Method scope requirements
method_requires_scope('cxp.send', read_write).
method_requires_scope('cxp.subscribe', read_only).
method_requires_scope('session.open', read_write).
method_requires_scope('session.close', read_write).
method_requires_scope('volk.register', admin).
method_requires_scope('volk.deregister', admin).
method_requires_scope('governance.rules', admin).
method_requires_scope(_, read_only).  % default

%% Topic subscription authorization
gateway_can_subscribe(ClientId, Topic) :-
    gateway_access(ClientId, Scope),
    topic_requires_scope(Topic, RequiredScope),
    scope_sufficient(Scope, RequiredScope).

topic_requires_scope('governance.decisions', read_write).
topic_requires_scope('kernel.events', read_write).
topic_requires_scope(_, read_only).  % default
Kernel EventBus Integration

The gateway subscribes to kernel events during initialize() and bridges them to WebSocket clients:

# During initialize()
await kernel.event_bus.subscribe(
    "cxp.*",
    self._on_cxp_event,
    subscriber_id="SYS:GATEWAY",
)
await kernel.event_bus.subscribe(
    "volk.lifecycle.*",
    self._on_volk_event,
    subscriber_id="SYS:GATEWAY",
)
await kernel.event_bus.subscribe(
    "governance.*",
    self._on_governance_event,
    subscriber_id="SYS:GATEWAY",
)
await kernel.event_bus.subscribe(
    "session.*",
    self._on_session_event,
    subscriber_id="SYS:GATEWAY",
)
await kernel.event_bus.subscribe(
    "provider.*",
    self._on_provider_event,
    subscriber_id="SYS:GATEWAY",
)
Configuration
# configs/monolithic.yaml
gateway:
  enabled: true
  host: "0.0.0.0"
  port: 18790
  auth_strategy: "static_token"
  static_token: «redacted»
  max_clients: 100
  heartbeat_interval_seconds: 30
  heartbeat_timeout_seconds: 10
  heartbeat_max_misses: 3
  max_subscriptions_per_client: 50
  event_buffer_per_client: 1000
  ring_buffer_size: 10000
  ring_buffer_ttl_seconds: 86400
  max_message_size_bytes: 1048576
  tls:
    enabled: false
    cert_path: null
    key_path: null
  http:
    health_enabled: true
    metrics_enabled: true
    metrics_port: 9090
Integration Points
Component Integration
orchestrata-core IGatewayServer interface, ComponentType.GATEWAY
orchestrata-kernel EventBus subscription for all system events
orchestrata-cxp CXP packet validation and dispatch
orchestrata-session Session state queries and lifecycle commands
orchestrata-governance PAM++ authorization for all gateway operations
orchestrata-knowledge Read-only Cypher query execution
orchestrata-provider Provider event forwarding (SPEC-011)
orchestrata-di DI registration and dependency resolution
configs/monolithic.yaml Gateway configuration source

Integration Points

orchestrata-core
orchestrata-kernel
orchestrata-cxp
orchestrata-session
orchestrata-governance
orchestrata-knowledge
orchestrata-provider
Redis
Neo4j
Prolog Engine

Success Criteria

  1. Server Running: WebSocket gateway starts and accepts connections on configured port
  2. Authentication: Clients authenticate before accessing any RPC method
  3. Real-Time Events: CXP traffic, Volk lifecycle, and governance decisions streamed to subscribers within 100ms
  4. Remote Control: Clients can send CXP packets and manage sessions through the gateway
  5. Governance: All gateway operations authorized via PAM++ before execution
  6. Observability: Health, readiness, and Prometheus metrics endpoints operational
  7. Resilience: Gateway handles client disconnects, buffer overflows, and dependency failures gracefully
  8. Audit: All operations recorded in Neo4j audit trail
  9. Performance: < 10ms RPC overhead, 10,000 events/second broadcast capacity

Dependencies


Terminology


Data Models

JSON-RPC Request Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "GatewayRPCRequest",
    "type": "object",
    "required": ["jsonrpc", "method"],
    "properties": {
        "jsonrpc": {
            "type": "string",
            "const": "2.0"
        },
        "id": {
            "oneOf": [
                {"type": "string"},
                {"type": "integer"},
                {"type": "null"}
            ],
            "description": "Request identifier. Omit or null for notifications."
        },
        "method": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]*\\.[a-z][a-z0-9_]*$",
            "description": "Namespaced method name (e.g., cxp.subscribe, session.open)."
        },
        "params": {
            "oneOf": [
                {"type": "object"},
                {"type": "array"},
                {"type": "null"}
            ],
            "description": "Method parameters. Named (object) preferred over positional (array)."
        }
    },
    "additionalProperties": false
}
JSON-RPC Response Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "GatewayRPCResponse",
    "type": "object",
    "required": ["jsonrpc", "id"],
    "properties": {
        "jsonrpc": {
            "type": "string",
            "const": "2.0"
        },
        "id": {
            "oneOf": [
                {"type": "string"},
                {"type": "integer"},
                {"type": "null"}
            ]
        },
        "result": {
            "description": "Present on success. Absent on error."
        },
        "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
                "code": {"type": "integer"},
                "message": {"type": "string"},
                "data": {"description": "Optional structured error details."}
            }
        }
    },
    "additionalProperties": false
}
GatewayEvent Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "GatewayEvent",
    "type": "object",
    "required": ["topic", "sequence", "timestamp", "payload", "source"],
    "properties": {
        "topic": {
            "type": "string",
            "description": "Event topic (e.g., cxp.traffic, volk.lifecycle)."
        },
        "sequence": {
            "type": "integer",
            "minimum": 0,
            "description": "Monotonically increasing sequence number per topic."
        },
        "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 timestamp of event occurrence."
        },
        "payload": {
            "type": "object",
            "description": "Event-specific payload."
        },
        "source": {
            "type": "string",
            "description": "Component that generated this event."
        }
    }
}
auth.authenticate Params Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "AuthenticateParams",
    "type": "object",
    "required": ["strategy"],
    "properties": {
        "strategy": {
            "type": "string",
            "enum": ["static_token", "hmac", "prolog_policy"]
        },
        "token": {
            "type": "string",
            "description": "Required for static_token strategy."
        },
        "client_id": {
            "type": "string",
            "description": "Required for hmac and prolog_policy strategies."
        },
        "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Required for hmac strategy."
        },
        "nonce": {
            "type": "string",
            "description": "Required for hmac strategy."
        },
        "signature": {
            "type": "string",
            "description": "HMAC-SHA256 signature. Required for hmac strategy."
        },
        "client_metadata": {
            "type": "object",
            "properties": {
                "client_name": {"type": "string"},
                "client_version": {"type": "string"},
                "purpose": {"type": "string"}
            }
        }
    }
}
auth.authenticate Result Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "AuthenticateResult",
    "type": "object",
    "required": ["authenticated", "client_id", "scope"],
    "properties": {
        "authenticated": {"type": "boolean"},
        "client_id": {"type": "string"},
        "scope": {
            "type": "string",
            "enum": ["read_only", "read_write", "admin"]
        },
        "expires_at": {
            "type": ["string", "null"],
            "format": "date-time"
        },
        "gateway_version": {"type": "string"},
        "capabilities": {
            "type": "array",
            "items": {"type": "string"}
        }
    }
}
cxp.subscribe Params Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "CXPSubscribeParams",
    "type": "object",
    "properties": {
        "filters": {
            "type": "object",
            "properties": {
                "volk_id": {"type": "string", "pattern": "^U:[A-Z][a-z]$"},
                "thread_id": {"type": "string", "format": "uuid"},
                "subject": {"type": "string", "description": "Glob pattern match."},
                "delivery_status": {
                    "type": "string",
                    "enum": ["queued", "delivered", "acknowledged", "failed"]
                }
            }
        },
        "max_payload_size": {
            "type": "integer",
            "minimum": 0,
            "description": "Truncate payload beyond this size in bytes."
        }
    }
}
cxp.send Params Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "CXPSendParams",
    "type": "object",
    "required": ["target", "payload"],
    "properties": {
        "target": {
            "type": "string",
            "pattern": "^U:[A-Z][a-z]$",
            "description": "Destination Volk alias."
        },
        "payload": {
            "oneOf": [
                {"type": "object"},
                {"type": "string"},
                {"type": "null"}
            ]
        },
        "subject": {
            "type": "string",
            "maxLength": 200
        },
        "priority": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10,
            "default": 5
        },
        "thread_id": {
            "type": "string",
            "format": "uuid",
            "description": "Optional. Auto-generated if omitted."
        }
    }
}
session.open Params Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "SessionOpenParams",
    "type": "object",
    "properties": {
        "portfolio": {"type": "string"},
        "goals": {
            "type": "array",
            "items": {"type": "string"}
        },
        "context": {
            "type": "object",
            "description": "Initial session context data."
        }
    }
}
gateway.replay Params Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "GatewayReplayParams",
    "type": "object",
    "properties": {
        "topic": {"type": "string"},
        "since": {"type": "string", "format": "date-time"},
        "until": {"type": "string", "format": "date-time"},
        "count": {"type": "integer", "minimum": 1, "maximum": 10000},
        "sequence_from": {"type": "integer", "minimum": 0},
        "sequence_to": {"type": "integer", "minimum": 0},
        "filters": {"type": "object"}
    }
}
knowledge.query Params Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "KnowledgeQueryParams",
    "type": "object",
    "required": ["cypher"],
    "properties": {
        "cypher": {
            "type": "string",
            "description": "Read-only Cypher query. Mutations are rejected."
        },
        "params": {
            "type": "object",
            "description": "Cypher query parameters."
        },
        "timeout_seconds": {
            "type": "number",
            "minimum": 1,
            "maximum": 60,
            "default": 10
        },
        "max_results": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10000,
            "default": 1000
        }
    }
}

Error Conditions

ID Condition Handling
ERR-001 Client sends RPC method before auth.authenticate Reject with JSON-RPC error -32001 (Unauthorized), disconnect after 5-second grace period
ERR-002 Client provides invalid or expired authentication token Return error -32001 with data.reason (e.g., "token_expired", "invalid_signature")
ERR-003 Client exceeds configured rate limit (default: 500 req/sec) Reject with error -32002 (Rate Limited), include data.retry_after_ms in response
ERR-004 Client sends message exceeding max_message_size_bytes (default: 1MB) Reject frame with WebSocket close code 1009 (Message Too Big)
ERR-005 Client attempts to subscribe to more than max_subscriptions_per_client topics (default: 50) Reject subscription with error -32602 and data.current_count
ERR-006 cxp.send targets non-existent Volk alias Return error -32602 with data.reason set to "unknown_target_volk"
ERR-007 knowledge.query contains mutation keywords (CREATE, MERGE, DELETE, SET, REMOVE, DETACH) Reject query with error -32602 and data.reason set to "mutation_not_allowed"
ERR-008 knowledge.query exceeds configured timeout (default: 10s) Cancel query, return error -32603 with data.reason set to "query_timeout"
ERR-009 Redis becomes unavailable during operation Switch to in-memory fallback for client sessions, defer ring buffer writes, default deny for uncached auth
ERR-010 Neo4j becomes unavailable Defer audit writes, return error -32603 for knowledge.* methods with data.reason set to "neo4j_unavailable"
ERR-011 Prolog engine becomes unavailable Use cached governance decisions where available, deny all uncached authorization requests (fail-closed)
ERR-012 Client connection drops mid-RPC (WebSocket close before response) Cancel in-flight operations, clean up subscriptions within 1 second
ERR-013 Two clients attempt HMAC authentication with same nonce within drift window Accept first, reject second with error -32001 and data.reason set to "nonce_replay"
ERR-014 Per-client event buffer overflows (default: 1000 events) Drop oldest events, send gap notification with dropped count and sequence range
ERR-015 max_clients reached (default: 100) and new connection arrives Reject connection with WebSocket close code 1013 (Try Again Later), log rejection
ERR-016 governance.evaluate dry-run encounters Prolog evaluation error Return Prolog error in data.prolog_error with error code -32603
ERR-017 Batch JSON-RPC request contains more than 50 individual requests Reject entire batch with error -32600 and data.reason set to "batch_too_large"
ERR-018 Client sends WebSocket binary frame (non-text) Reject frame with WebSocket close code 1003 (Unsupported Data)

Testing


Definition of Done


Examples

Example: Authentication Flow (Static Token)

Request:

{
    "jsonrpc": "2.0",
    "id": "auth-001",
    "method": "auth.authenticate",
    "params": {
        "strategy": "static_token",
        "token": "my-secret-gateway-token",
        "client_metadata": {
            "client_name": "vizint-command-center",
            "client_version": "1.0.0",
            "purpose": "dashboard"
        }
    }
}

Response:

{
    "jsonrpc": "2.0",
    "id": "auth-001",
    "result": {
        "authenticated": true,
        "client_id": "client-a1b2c3d4",
        "scope": "read_write",
        "expires_at": null,
        "gateway_version": "1.0.0",
        "capabilities": ["cxp", "session", "volk", "governance", "knowledge", "gateway"]
    }
}
Example: Subscribe to CXP Traffic

Request:

{
    "jsonrpc": "2.0",
    "id": "req-002",
    "method": "cxp.subscribe",
    "params": {
        "filters": {
            "volk_id": "U:Cd",
            "delivery_status": "delivered"
        }
    }
}

Response:

{
    "jsonrpc": "2.0",
    "id": "req-002",
    "result": {
        "subscription_id": "sub-abc123",
        "topic": "cxp.traffic",
        "filters": {"volk_id": "U:Cd", "delivery_status": "delivered"}
    }
}

Subsequent Server Push:

{
    "jsonrpc": "2.0",
    "method": "cxp.traffic",
    "params": {
        "sequence": 42,
        "timestamp": "2026-03-28T14:30:22Z",
        "payload": {
            "message_id": "msg-e4f5a6b7",
            "to": "U:Cd",
            "from": "U:Ox",
            "thread_id": "thread-001",
            "subject": "code_generation_request",
            "delivery_status": "delivered",
            "work_status": "pending",
            "priority": 5
        },
        "source": "kernel.postman"
    }
}
Example: Send CXP Packet

Request:

{
    "jsonrpc": "2.0",
    "id": "req-003",
    "method": "cxp.send",
    "params": {
        "target": "U:Vz",
        "subject": "generate_component",
        "payload": {
            "component": "UserService",
            "language": "python",
            "framework": "fastapi"
        },
        "priority": 7
    }
}

Response:

{
    "jsonrpc": "2.0",
    "id": "req-003",
    "result": {
        "status": "sent",
        "thread_id": "thread-8f9e0d1c",
        "message_id": "msg-2b3c4d5e",
        "routed_via": "U:PS"
    }
}
Example: Error Response (Unauthorized)
{
    "jsonrpc": "2.0",
    "id": "req-004",
    "error": {
        "code": -32001,
        "message": "Unauthorized",
        "data": {
            "reason": "authentication_required",
            "hint": "Call auth.authenticate before any other method."
        }
    }
}
Example: Event Replay

Request:

{
    "jsonrpc": "2.0",
    "id": "req-005",
    "method": "gateway.replay",
    "params": {
        "topic": "cxp.traffic",
        "count": 10,
        "filters": {"volk_id": "U:Vz"}
    }
}

Response:

{
    "jsonrpc": "2.0",
    "id": "req-005",
    "result": {
        "events": [
            {
                "topic": "cxp.traffic",
                "sequence": 35,
                "timestamp": "2026-03-28T14:25:00Z",
                "payload": {"from": "U:Ox", "to": "U:Vz", "subject": "task_assignment"},
                "source": "kernel.postman"
            },
            {
                "topic": "cxp.traffic",
                "sequence": 38,
                "timestamp": "2026-03-28T14:28:12Z",
                "payload": {"from": "U:Vz", "to": "U:Ox", "subject": "task_progress"},
                "source": "kernel.postman"
            }
        ],
        "total_matched": 2,
        "buffer_range": {"oldest_sequence": 1, "newest_sequence": 42}
    }
}

Security

Authentication and Authorization

All gateway operations require authentication before access. The gateway supports three authentication strategies:

Authentication scopes:

Transport Security
Access Control
Audit and Logging

Governance

PAM++ Gateway Predicates

The gateway extends PAM++ with governance predicates for authorization:

% Client access levels
gateway_access(ClientId, admin).
gateway_access(ClientId, read_write).
gateway_access(ClientId, read_only).

% Per-method authorization
gateway_can_execute(ClientId, Method).

% Topic subscription authorization
gateway_can_subscribe(ClientId, Topic).

% Knowledge graph query authorization
gateway_can_query_kg(ClientId, QueryPattern).
Method Scope Requirements
Topic Subscription Requirements
Governance Decisions

All gateway operations log governance decisions to the audit trail including:


API Contracts

Contract: Gateway JSON-RPC API (contracts/gateway/rpc-v1.0.0.yaml)
info:
  title: Orchestrata Gateway JSON-RPC 2.0 API
  version: 1.0.0
  spec_id: 014-websocket-gateway
  spec_version: 1.0.0
  maturity: experimental
  transport: websocket
  protocol: json-rpc-2.0

methods:
  auth.authenticate:
    description: Authenticate a client with the gateway
    scope_required: null
    params:
      type: object
      required: [strategy]
      properties:
        strategy:
          type: string
          enum: [static_token, hmac, prolog_policy]
        token:
          type: string
        client_id:
          type: string
        timestamp:
          type: string
          format: date-time
        nonce:
          type: string
        signature:
          type: string
        client_metadata:
          type: object
    result:
      type: object
      required: [authenticated, client_id, scope]
      properties:
        authenticated:
          type: boolean
        client_id:
          type: string
        scope:
          type: string
          enum: [read_only, read_write, admin]
        expires_at:
          type: string
          format: date-time
          nullable: true
        gateway_version:
          type: string
        capabilities:
          type: array
          items:
            type: string

  cxp.subscribe:
    description: Subscribe to CXP packet traffic
    scope_required: read_only
    params:
      type: object
      properties:
        filters:
          type: object
          properties:
            volk_id:
              type: string
              pattern: "^U:[A-Z][a-z]$"
            thread_id:
              type: string
              format: uuid
            subject:
              type: string
            delivery_status:
              type: string
              enum: [queued, delivered, acknowledged, failed]
        max_payload_size:
          type: integer
          minimum: 0
    result:
      type: object
      required: [subscription_id, topic]
      properties:
        subscription_id:
          type: string
        topic:
          type: string
        filters:
          type: object

  cxp.unsubscribe:
    description: Unsubscribe from a CXP traffic subscription
    scope_required: read_only
    params:
      type: object
      required: [subscription_id]
      properties:
        subscription_id:
          type: string
    result:
      type: object
      required: [unsubscribed]
      properties:
        unsubscribed:
          type: boolean

  cxp.send:
    description: Send a CXP message through the Postman
    scope_required: read_write
    params:
      type: object
      required: [target, payload]
      properties:
        target:
          type: string
          pattern: "^U:[A-Z][a-z]$"
        payload:
          oneOf:
            - type: object
            - type: string
            - type: "null"
        subject:
          type: string
          maxLength: 200
        priority:
          type: integer
          minimum: 0
          maximum: 10
        thread_id:
          type: string
          format: uuid
    result:
      type: object
      required: [status, thread_id]
      properties:
        status:
          type: string
          enum: [sent, failed, queued]
        thread_id:
          type: string
        message_id:
          type: string
        routed_via:
          type: string

  cxp.status:
    description: Query status of a CXP thread
    scope_required: read_only
    params:
      type: object
      required: [thread_id]
      properties:
        thread_id:
          type: string
          format: uuid
    result:
      type: object
      required: [thread_id, delivery_status, work_status]
      properties:
        thread_id:
          type: string
        delivery_status:
          type: string
        work_status:
          type: string
        transitions:
          type: array
          items:
            type: object
            properties:
              status:
                type: string
              timestamp:
                type: string
                format: date-time

  volk.list:
    description: List all registered Volks
    scope_required: read_only
    params:
      type: object
      properties:
        offset:
          type: integer
          minimum: 0
        limit:
          type: integer
          minimum: 1
          maximum: 100
    result:
      type: object
      required: [volks, total]
      properties:
        volks:
          type: array
          items:
            type: object
            required: [alias, capabilities, health]
            properties:
              alias:
                type: string
              capabilities:
                type: array
                items:
                  type: string
              health:
                type: string
              active_tasks:
                type: integer
              last_activity:
                type: string
                format: date-time
        total:
          type: integer

  session.open:
    description: Open a new orchestration session
    scope_required: read_write
    params:
      type: object
      properties:
        portfolio:
          type: string
        goals:
          type: array
          items:
            type: string
        context:
          type: object
    result:
      type: object
      required: [session_id, status]
      properties:
        session_id:
          type: string
        status:
          type: string
        opened_at:
          type: string
          format: date-time

  session.close:
    description: Close an active orchestration session
    scope_required: read_write
    params:
      type: object
      required: [session_id]
      properties:
        session_id:
          type: string
        status:
          type: string
        summary:
          type: string
        carryover_tasks:
          type: array
          items:
            type: string
    result:
      type: object
      required: [session_id, status, duration_seconds]
      properties:
        session_id:
          type: string
        status:
          type: string
        duration_seconds:
          type: number
        closed_at:
          type: string
          format: date-time

  gateway.replay:
    description: Replay historical events from the ring buffer
    scope_required: read_only
    params:
      type: object
      properties:
        topic:
          type: string
        since:
          type: string
          format: date-time
        until:
          type: string
          format: date-time
        count:
          type: integer
          minimum: 1
          maximum: 10000
        filters:
          type: object
    result:
      type: object
      required: [events, total_matched]
      properties:
        events:
          type: array
          items:
            $ref: "#/schemas/GatewayEvent"
        total_matched:
          type: integer
        buffer_range:
          type: object
          properties:
            oldest_sequence:
              type: integer
            newest_sequence:
              type: integer

  gateway.info:
    description: Get gateway metadata and capabilities
    scope_required: read_only
    params: null
    result:
      type: object
      required: [version, uptime_seconds, capabilities, topics]
      properties:
        version:
          type: string
        uptime_seconds:
          type: number
        capabilities:
          type: array
          items:
            type: string
        topics:
          type: array
          items:
            type: string

  gateway.ping:
    description: Ping the gateway for latency measurement
    scope_required: read_only
    params: null
    result:
      type: object
      required: [server_timestamp]
      properties:
        server_timestamp:
          type: string
          format: date-time

  knowledge.query:
    description: Execute a read-only Cypher query against the knowledge graph
    scope_required: read_only
    params:
      type: object
      required: [cypher]
      properties:
        cypher:
          type: string
        params:
          type: object
        timeout_seconds:
          type: number
          default: 10
        max_results:
          type: integer
          default: 1000
    result:
      type: object
      required: [records, execution_time_ms]
      properties:
        records:
          type: array
        execution_time_ms:
          type: number
        truncated:
          type: boolean

  governance.evaluate:
    description: Dry-run a governance evaluation
    scope_required: read_write
    params:
      type: object
      required: [volk_id, action]
      properties:
        volk_id:
          type: string
        action:
          type: string
        resource:
          type: string
    result:
      type: object
      required: [result, prolog_trace]
      properties:
        result:
          type: string
          enum: [allow, deny, escalate]
        prolog_trace:
          type: string
        articles_applied:
          type: array
          items:
            type: string

error_codes:
  -32700:
    message: Parse error
    description: Invalid JSON received
  -32600:
    message: Invalid request
    description: JSON-RPC structure invalid
  -32601:
    message: Method not found
    description: Unknown RPC method
  -32602:
    message: Invalid params
    description: Parameter validation failed
  -32603:
    message: Internal error
    description: Server-side processing error
  -32001:
    message: Unauthorized
    description: Authentication required or failed
  -32002:
    message: Rate limited
    description: Client exceeded rate limit
  -32003:
    message: Budget exceeded
    description: Token or resource budget exceeded

event_topics:
  cxp.traffic:
    description: CXP packet flow between Volks
    scope_required: read_only
  volk.lifecycle:
    description: Volk registration, deregistration, health changes
    scope_required: read_only
  governance.decisions:
    description: PAM++ governance decisions and escalations
    scope_required: read_write
  session.events:
    description: Session lifecycle events
    scope_required: read_only
  kernel.events:
    description: Kernel-level system events
    scope_required: read_write
  gateway.presence:
    description: Client connection and disconnection events
    scope_required: read_only
  provider.events:
    description: LLM provider events
    scope_required: read_only

performance:
  connection_accept_p95_ms: 50
  rpc_dispatch_overhead_p95_ms: 10
  event_delivery_p95_ms: 100
  broadcast_throughput_eps: 10000
  max_concurrent_clients: 100
  ring_buffer_write_p95_ms: 5

security:
  authentication_required: true
  authorization_scopes: [read_only, read_write, admin]
  tls_supported: true
  rate_limit_default_rps: 500
  max_message_size_bytes: 1048576

observability:
  emits_metrics: true
  metric_names:
    - orchestrata_gateway_connected_clients
    - orchestrata_gateway_total_connections
    - orchestrata_gateway_messages_received_total
    - orchestrata_gateway_messages_sent_total
    - orchestrata_gateway_rpc_latency_seconds
    - orchestrata_gateway_subscription_count
    - orchestrata_gateway_auth_success_total
    - orchestrata_gateway_auth_failure_total
    - orchestrata_gateway_events_dropped_total
  health_endpoint: /health
  ready_endpoint: /ready
  metrics_endpoint: /metrics

spec_traceability:
  spec_id: "014-websocket-gateway"
  spec_version: "1.0.0"
  user_stories:
    - "US-001"
    - "US-002"
    - "US-003"
    - "US-004"
    - "US-005"
    - "US-006"
    - "US-007"
    - "US-008"
    - "US-009"
    - "US-010"
    - "US-011"
    - "US-012"

Observability

Logging Requirements
  1. Component Logging
    • Log all major operations with appropriate log levels
    • Include correlation IDs for request tracing
    • Log performance metrics for critical operations
    • Log errors with full context for debugging
Metrics Requirements
  1. Performance Metrics
    • Operation duration histograms
    • Request/error rate counters
    • Resource utilization gauges
    • Business metrics relevant to domain
Tracing Requirements
  1. Distributed Tracing
    • Trace propagation across component boundaries
    • Span attributes for domain-specific context
    • Trace sampling based on operational needs
Alerting Requirements
  1. Critical Alerts
    • Error rate spikes
    • Performance degradation
    • Resource exhaustion
    • Business metric anomalies
Dashboard Requirements
  1. Operational Dashboard
    • Real-time system health
    • Performance trends
    • Error analysis
    • Resource monitoring

Revision History

Date Version Author Changes
2026-03-27 1.0.0 Mohamed Initial specification
2026-03-28 1.0.0 Mohamed Added Data Models, Error Conditions, Performance Requirements, Testability, DoD, Terminology, Examples, Contracts sections per spec standard improvements