Skip to content

Companion-app skill: WebSocket resilience for blue/green deploys - #92

Open
beaugunderson wants to merge 2 commits into
mainfrom
bg-ws-deploy-resilience
Open

Companion-app skill: WebSocket resilience for blue/green deploys#92
beaugunderson wants to merge 2 commits into
mainfrom
bg-ws-deploy-resilience

Conversation

@beaugunderson

@beaugunderson beaugunderson commented Jun 4, 2026

Copy link
Copy Markdown
Member

The Canvas Plugin Assistant companion-app-patterns skill documented realtime push via WebSocket (rule 12 / §7) but its reconnect guidance was a thin fixed-4s-backoff snippet with no story for what happens during a daytime blue/green deploy — when the server drains the old container, drops every client's socket at once, and reconnects them onto a freshly booted process. WebSockets are a general SDK feature, though, not a companion-app-only one, so this PR also lifts the resilience guidance out of that single skill and puts it everywhere a plugin author will hit it.

The core principle: the socket is a re-sync hint, not a source of truth. Broadcasts are fire-and-forget and ephemeral (no replay, no per-client queue, no ack), and the plugin process keeps no durable state across a restart, so anything sent during the deploy gap is lost. The client recovers by re-fetching the authoritative snapshot from its SimpleAPI endpoint.

companion-app-patterns skill — rewrote the guidance to carry the resilience lessons from canvas-hyperscribe, scoped to what a plugin author can actually do inside the sandbox. companion_app_patterns_context.txt §7 replaces the old "### Reconnect" subsection with "### Surviving deploys & reconnection": the three facts that drive the design (broadcasts are ephemeral, the process holds no durable state, disconnects are synchronized), re-fetch the snapshot on every (re)connect by wiring the load to the socket open event, exponential backoff + jitter + cap instead of a fixed delay, reconnect immediately on the browser online event, and an optional heartbeat to detect the half-open socket a cutover can leave behind. A new "### Mutations must be idempotent across a deploy" subsection covers the dropped-response case: a cutover can drop the response to an in-flight mutating POST, the client can't tell "never applied" from "applied, response lost" so it retries, and the server must re-check state and no-op rather than double-apply. SKILL.md adds quick-reference rule 13, renumbers the following rules, and fixes the Reference Implementations cross-references.

canvas-sdk skill — this is the durable, plugin-agnostic home, since the same WebSocket concern applies to custom chart summary sections and real-time note-restriction updates (NoteRestrictionsUpdatedEffect), not just companion apps. Added a "### WebSockets must survive blue/green deploys" subsection with the four core principles (push is a hint / pull is the truth, re-fetch on every reconnect, backoff + jitter + cap plus the online event, idempotent mutations) and a pointer to the full worked client code in companion-app-patterns. The guidance lives in SKILL.md rather than coding_agent_context.txt because the latter is auto-regenerated from docs.canvasmedical.com and would overwrite anything added there.

wrap-up command — added a conditional "WebSocket Deploy Resilience" review gate (modeled on the existing cache-busting gate, its sibling "survive a deploy" check) so the guidance actually fires during real plugin work instead of only sitting in a reference doc. It greps for WebSocket usage and, if found, verifies all four requirements, then the trailing sections were renumbered and both summary tables gained a row.

No code or runtime behavior changes — this is plugin-authoring guidance only.

@kristenoneill

Copy link
Copy Markdown

@beaugunderson - should the scope of this be beyond companion apps?

@beaugunderson

Copy link
Copy Markdown
Member Author

@kristenoneill probably, i just updated the one place we talked about it in CPA, i'll widen it

@beaugunderson

Copy link
Copy Markdown
Member Author

made that change 👍

Plugin WebSockets drop mid-session at deploy cutover and reconnect onto a
fresh process. The skill documented push but not how to survive the gap.
Adds guidance distilled from canvas-hyperscribe: treat the socket as a
re-sync hint (broadcasts are ephemeral, the process holds no durable
state), re-fetch the snapshot on every reconnect, back off with jitter to
avoid a thundering herd, reconnect on browser online, and make mutating
POSTs idempotent for retry safety.
The blue/green deploy-resilience guidance only lived in the companion-app
skill, but WebSockets are a general SDK feature (custom chart summary
sections, NoteRestrictionsUpdatedEffect, companion apps). Add a plugin-
agnostic 'WebSockets must survive blue/green deploys' subsection to the
canvas-sdk skill (the durable, hand-authored home; the context file is
auto-regenerated from docs and would be overwritten), and add a
conditional WebSocket-resilience review gate to the wrap-up command so
the guidance fires during real plugin work instead of only sitting in a
reference doc.
@canvas-sisyphus

Copy link
Copy Markdown

Rebased bg-ws-deploy-resilience onto main (resolved conflicts locally) and force-pushed, preserving the branch's individual commits. Force-pushed rebased bg-ws-deploy-resilience to 5509aaa (2 commits, 6 file changes)

@canvas-sisyphus
canvas-sisyphus Bot force-pushed the bg-ws-deploy-resilience branch from 4cfc14f to 5509aaa Compare August 24, 2026 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants