# 1.4. Socket.IO Real-time Layer REST hands off work; **Socket.IO delivers the experience**. Every streaming answer, phase change, and error travels over a single Socket.IO connection managed by `@ehildt/nestjs-socket.io` using KeyDB as the shared adapter backbone. ## Concepts - **Room** — the dashboard joins a `roomId` per active request/conversation scope; the server streams into that room (`emitToRoom`) or, rarely, broadcasts (`emitToAll`). - **Event name** — the client chooses the event it listens on and passes it as the `event` query param of `POST /harness`; the `202` response echoes it so both sides always agree. - **Correlation** — every payload carries `requestId` (and usually `conversationId`), so multiple concurrent exchanges in one room stay attributable. Server-side emission lives in `modules/socket-io/services/socket-io-events.service.ts` and degrades gracefully: if the socket instance is not yet available it logs rather than throwing, and failed emissions are logged with the event name. ## Event contract Payloads emitted during a harness run (see **1.2 — Streaming**): | Payload kind | Meaning | | ----------------- | --------------------------------------------------------------------------- | | `text` / `stream` | Incremental assistant output (append to the live exchange) | | `assistant` | Completed assistant message object | | `clarification` | The harness asks the user for clarification instead of answering | | `result` | Terminal, validated structured result (schema-bound) | | `error` | Something failed — renderable inline error object | | `cancel_result` | Outcome of a `POST /harness/cancel` request | Phase markers and step progress also appear in the structured payloads; the dashboard's debug panel mirrors the raw event stream for inspection. ## Configuration `SOCKET_IO_*` env group: connect timeout, max HTTP buffer size, transports, CORS origin/methods/credentials, ping interval/timeout, EIO3 compatibility. Production deployments behind a proxy must enable sticky sessions **or** rely on the KeyDB adapter (default here) for cross-instance room routing. ## Dashboard counterpart The dashboard owns a `socket` Pinia store that maintains the connection (`VITE_SOCKET_URL`, default `http://localhost:3000`), dispatches incoming events into the messages/conversation stores, and keeps a socket debug journal. See **2.1** and **2.2**.