diff --git a/tasks/new/2026-0824.01.jul.feat.sdk-hono.ghost-cockpit-protocol-0431.md b/tasks/new/2026-0824.01.jul.feat.sdk-hono.ghost-cockpit-protocol-0431.md new file mode 100644 index 0000000..3d6f5bf --- /dev/null +++ b/tasks/new/2026-0824.01.jul.feat.sdk-hono.ghost-cockpit-protocol-0431.md @@ -0,0 +1,67 @@ +# TASK METADATA + +- **Target Files:** `docs/GHOST_COCKPIT_SPEC.md`, `sdk/hono.ts`, + `sdk/hono.test.ts` +- **Core Objective:** Formalize the Ghost Cockpit Protocol specification and + write server/client reference helpers in `@auth-yes/sdk/hono` to support + non-destructive WebSocket telemetry freezes and seamless in-flight WebAuthn + re-authentication. +- **Dependencies:** Deno 2.x native WebSocket support, `AuthSdk` event bus + (`.on("invalidate")`) in `sdk/mod.ts`. +- **Additional Important Notes:** Must use native Hono `upgradeWebSocket` (do + not use `@hono/node-ws`). Client-side snippet demonstrating state-freeze and + background WebAuthn re-auth must be embedded within the spec markdown file. + +--- + +### 2. Architectural Considerations & Risks + +- **Risks:** + - **Memory Leaks:** If the WebSocket closes gracefully or errors out and the + `authSdk.off("invalidate")` cleanup is not correctly executed, the SDK's + listener map will leak memory over time. + - **Connection State Race Conditions:** Emitting the + `{ "type": "AUTH_REVOKED", "reason": "SESSION_EXPIRED" }` frame and closing + the socket must happen cleanly. The helper must handle scenarios where the + socket is already in a `CLOSING` or `CLOSED` state to avoid uncaught + exceptions during invalidation. + - **Blocking the Event Loop:** The `invalidate` event handler executes within + the SDK's Valkey push handler context. The WebSocket control frame emission + must not block or crash this primary loop. + +- **Alternatives:** + - We evaluated creating a dedicated Valkey Pub/Sub channel exclusively for + WebSocket termination. However, since `AuthSdk` already utilizes RESP3 BCAST + tracking and exposes a robust `.on("invalidate")` bus, utilizing this + existing mechanism directly in `sdk/hono.ts` is the cleanest, most + zero-dependency approach. It avoids adding unnecessary architectural layers. + +### 3. Proposed Implementation + +1. **Formalize `docs/GHOST_COCKPIT_SPEC.md`:** + - Document the choreography for the Ghost Cockpit Protocol. + - Explain the concept of freezing UI/telemetry state in memory upon receiving + the `AUTH_REVOKED` WebSocket frame. + - Embed a complete, reference client-side TypeScript snippet demonstrating + the background WebAuthn re-authentication flow (zero-redirect) and + subsequent reconnection and state resumption. + +2. **Implement WebSocket Guard in `sdk/hono.ts`:** + - Create a reusable helper (e.g., `createWebSocketAuthGuard` or + `createWebSocketSessionManager`). + - The helper will take an `AuthSdk` instance and a session token. + - It will attach an `invalidate` listener to the SDK. When the specific token + is invalidated, it will send the `AUTH_REVOKED` JSON string to the active + WebSocket and then explicitly close the connection. + - It will include robust lifecycle hooks to guarantee + `authSdk.off("invalidate", handler)` is called when the WebSocket closes + naturally or errors out. + - Add JSDoc comments to the helper with brief server-side usage examples + demonstrating its use alongside Hono's `upgradeWebSocket`. + +3. **Testing:** + - Update `sdk/hono.test.ts` to include tests for the new WebSocket guard + helper. + - Mock the `AuthSdk` invalidation emission to verify the helper sends the + correct payload and gracefully closes the mock WebSocket. + - Verify the unregister cleanup logic executes correctly on socket close.