Pathrule

Real-Time UI with WebSockets

Pathrule3 Rules • 2 Memories • 1 Skill

A WebSocket provides an ordered byte stream for one live connection, not durable delivery across disconnects, browser sleep, server restarts, deployment, or a client that processes messages slower than the producer sends them. This pattern constrains authenticated connection setup, message validation, and bounded queues; it records sequence, resume, presence, and optimistic-state decisions and provides a reconnect failure test. It complements Kafka and background-job patterns by focusing on the browser-facing session, where ephemeral connection state must reconcile with an authoritative API or event log.

Suggested path map

Pathrule places each piece on the matching path, so your assistant only sees it where it belongs. This is the scoping you get on import; you can adjust it in your workspace.

/ workspace root
test-websocket-resynchronization
server/
realtime/
Authenticate and authorize the live subscription
Validate every message against a versioned envelope
Bound outbound and inbound connection buffers
src/
realtime/
Reconnect resumes from an authoritative cursor
Presence is leased, approximate state

Rules

3
Authenticate and authorize the live subscription/server/realtimehighstrictValidate connection identity, origin, channel access, and authorization changes instead of inheriting trust from page load.
1A long-lived connection can outlast tokens, membership, and resource permissions. Accepting a socket once and trusting every later subscribe command creates access that cannot be revoked correctly.
2 
3- Authenticate the handshake or first protocol message through a reviewed token mechanism and validate browser origin where the deployment relies on it.
4- Authorize each channel, document, tenant, or topic subscription against current server state; do not trust a client-supplied tenant or room name.
5- Define token expiry and permission-change behavior, including reauthentication, subscription removal, or connection close with a stable reason.
6- Rate-limit connection, authentication, subscription, and message actions separately so reconnect storms and channel scanning cannot consume the service.
7 
8See /src/realtime for the adjacent decision or procedure that completes this constraint.
Validate every message against a versioned envelope/server/realtimehighstrictUse bounded payload schemas, message type allowlists, correlation identity, and explicit protocol errors on both client and server.
1WebSocket frames are untrusted input without HTTP route and body-parser boundaries. A generic event name plus arbitrary object recreates remote procedure calls without a reviewable contract.
2 
3- Define an envelope with protocol version, type, message or operation identity, and a payload schema per allowed message.
4- Reject unknown types, oversized frames, invalid nesting, and unsupported versions before dispatching to domain behavior.
5- Separate commands, events, acknowledgements, and errors so clients do not confuse a requested action with an authoritative state transition.
6- Log protocol type, stable identity, size, and outcome without recording secret or personal payload fields.
7 
8See /tests/realtime for the adjacent decision or procedure that completes this constraint.
Bound outbound and inbound connection buffers/server/realtimehighstrictSet queue, frame, rate, and processing limits, then close or degrade slow consumers with a recoverable reason.
1A connection that receives faster than it can transmit or process accumulates memory. Backpressure must become a protocol decision before one slow browser harms every session in the process.
2 
3- Track buffered bytes and queued messages per connection and define a maximum with a close, snapshot, or coalescing policy.
4- Coalesce replaceable state updates such as progress or presence instead of retaining every intermediate value.
5- Keep durable domain events outside the socket process so dropping an ephemeral connection does not lose the authoritative transition.
6- Apply inbound rate and concurrency limits before expensive validation or database work, and return a protocol-level throttle or close reason clients understand.
7 
8See /src/realtime for the adjacent decision or procedure that completes this constraint.

Memories

2
Reconnect resumes from an authoritative cursor/src/realtimePersist the last applied sequence, request events after it, and fall back to a fresh snapshot when the history window is unavailable.
1A new socket is a new stream. Reconnecting without a cursor either loses events created during the gap or forces the client to append a full replay over state it already has.
2 
3- Give authoritative events a stable stream and sequence identity and make client application idempotent by event ID.
4- Persist or retain the last applied cursor at the state owner, not merely in the socket instance that was lost.
5- On reconnect, request events after the cursor and apply them in order; buffer out-of-order arrivals only within a strict bound.
6- When the cursor is too old or the server cannot prove continuity, replace local state from a versioned snapshot and resume from its cursor.
7 
8See /server/realtime for the rule or workflow that puts this decision into practice.
Presence is leased, approximate state/src/realtimeRepresent presence with heartbeats and expiry, and never use it as durable identity, authorization, or business truth.
1Disconnect events are not guaranteed when a laptop sleeps, a network changes, or a process dies. Presence must expire without a clean close and tolerate brief disagreement between viewers.
2 
3- Issue a connection or session presence identity distinct from the user account and refresh it through bounded heartbeats.
4- Expire presence after a documented lease and communicate that online indicators are approximate rather than instantaneous truth.
5- Aggregate multiple tabs and devices intentionally so one closing tab does not mark a still-connected user offline.
6- Keep authorization and durable workflow state in the authoritative backend; presence can inform UI but cannot grant access or prove attendance.
7 
8See /server/realtime for the rule or workflow that puts this decision into practice.

Skills

1
test-websocket-resynchronization/rootBreak and resume live connections across gaps, duplicates, reordering, slow consumers, token changes, and server restarts.
1---
2name: test-websocket-resynchronization
3description: Test a WebSocket protocol or real-time UI change before release.
4---
5 
6# Test Websocket Resynchronization
7 
8Run this procedure when the affected surface changes, before the result is promoted to production. Record evidence for every step instead of accepting a plausible-looking result.
9 
10- [ ] Connect with valid, expired, unauthorized, wrong-origin, malformed, oversized, and unsupported-version inputs and confirm rejection occurs before subscription or domain work.
11- [ ] Produce events while the client is disconnected, then reconnect from a current, old, invalid, and missing cursor; verify replay or snapshot behavior.
12- [ ] Duplicate and reorder events around optimistic UI changes and prove the final state follows authoritative sequence without duplicate rows or effects.
13- [ ] Throttle the client and server consumer to grow buffers; verify coalescing, limits, close reason, and recovery without process-level memory growth.
14- [ ] Restart and deploy socket servers while several tabs and devices are connected, then revoke access and confirm every connection eventually loses the subscription.
15 
16## Exit criteria
17 
18The change is complete only when the expected behavior, failure behavior, and rollback path have all been exercised with representative data. Preserve the evidence with the change so the next operator can repeat the same checks.

Why this pattern

AI agents often authenticate only the initial page, assume reconnect preserves missed events, append duplicates without sequence identity, or allow an unbounded client message queue.

Built for Frontend and backend teams building collaborative, presence, notification, monitoring, or live-update interfaces.

Keeps your assistant from:

  • Applying the same event twice after reconnect
  • Missing events produced while the browser was suspended
  • Treating a socket connection as permanent authorization
  • Crashing a client or server through unbounded buffered messages
License
Apache-2.0
Version
1.0.0
Updated
2026-08-25
View source