auth-yes/tasks/complete/2026-0824.01.jul.feat.sdk-hono.ghost-cockpit-protocol-0431.md
google-labs-jules[bot] b919c66cbc feat(sdk): Implement Ghost Cockpit Protocol WebSocket guard helper
- Formalized Ghost Cockpit Protocol in docs/GHOST_COCKPIT_SPEC.md.
- Added `GhostCockpitClient` reference implementation.
- Implemented `createWebSocketGuard` in `sdk/hono.ts` to seamlessly terminate invalidated user sessions with code 1008.
- Added robust lifecycle cleanups and error checking for WebSocket frame deliveries on socket close.
- Added comprehensive integration tests in `sdk/hono.test.ts`.
- Cleaned unused imports and fixed all linting warnings.
- Moved task definition to complete.

Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
2026-08-24 04:53:51 +00:00

3.4 KiB

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.