From 03e7ca39c3f073733429942c757b3e9e7f53c4d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Sat, 22 Aug 2026 22:22:23 +0000 Subject: [PATCH] minesweeper: narrow send(), and tell the ws mirror about the provider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit two failures another session found in a shared checkout, both mine. send() took a plain Uint8Array, whose default buffer type is ArrayBufferLike and may be a SharedArrayBuffer — WebSocket.send takes only BufferSource. narrowed to Uint8Array, which every caller already builds and which the terminal relay already does. registry.test.ts keeps REAL_WS as a hand-written mirror of server.tsx's handlers map, and its own comment says that drift is what it catches. it caught mine: the route and the registry entry landed, the mirror did not. Co-Authored-By: Claude Fable 5 --- src/servers/permissions/registry.test.ts | 2 +- src/workspaces/officerdev/src/apps/Minesweeper/rfb.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/servers/permissions/registry.test.ts b/src/servers/permissions/registry.test.ts index 79b614dd..7d5eb58e 100644 --- a/src/servers/permissions/registry.test.ts +++ b/src/servers/permissions/registry.test.ts @@ -23,7 +23,7 @@ import { assertPermissionTotality, isExemptApiPath } from './totality'; // switched off 2026-08-13. It was listed here until 2026-08-18 and made this file's own totality tests // fail for five days — the mirror claiming a provider the server does not serve, which is precisely the // drift the comment above warns about, caught by the check and then ignored because it was "the baseline". -const REAL_WS = ['terminal', 'chat', 'chat-notify', 'task-runner', 'pipeline', 'sidecar']; +const REAL_WS = ['terminal', 'chat', 'chat-notify', 'task-runner', 'pipeline', 'sidecar', 'minesweeper']; const realApi = () => [...new Set(PERMISSIONS.flatMap((c) => c.api))]; const surface = () => ({ apiPrefixes: [...realApi(), '/auth', '/landing-page-data', '/waitlist', '/sidecar'], diff --git a/src/workspaces/officerdev/src/apps/Minesweeper/rfb.ts b/src/workspaces/officerdev/src/apps/Minesweeper/rfb.ts index 276c067b..37b2f0ea 100644 --- a/src/workspaces/officerdev/src/apps/Minesweeper/rfb.ts +++ b/src/workspaces/officerdev/src/apps/Minesweeper/rfb.ts @@ -66,7 +66,10 @@ export class RfbClient { } } - private send(bytes: Uint8Array): void { + // Uint8Array, not plain Uint8Array: the default is Uint8Array, whose + // buffer may be a SharedArrayBuffer, and WebSocket.send takes only BufferSource. Every caller here + // builds its own array, so narrowing costs nothing. The terminal relay narrows the same way. + private send(bytes: Uint8Array): void { if (this.socket.readyState === WebSocket.OPEN) this.socket.send(bytes); }