From 87360c5a4592c7dfdd595728bc76fd01ddf80667 Mon Sep 17 00:00:00 2001 From: Neil Date: Wed, 16 Sep 2026 23:55:29 -0700 Subject: [PATCH] fix(relay): carry the SAFETY: rationale main's casting gate now requires Main gained a `typescript/consistent-type-assertions` scan while this branch sat 432 commits behind, so every `as` the branch touches lands as a new finding. The parser is the one place the handshake shape is proved, so each cast names the check that earns it, and the hostile-frame cast in the round-trip test names the fact that it is a deliberate lie the type system cannot describe. --- src/relay/protocol.ts | 6 +++++- src/relay/relay-handshake-roundtrip.test.ts | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/relay/protocol.ts b/src/relay/protocol.ts index 0b5eee2704c..84656fed3cb 100644 --- a/src/relay/protocol.ts +++ b/src/relay/protocol.ts @@ -79,11 +79,13 @@ export function parseHandshakeMessage(payload: Buffer): HandshakeMessage { if (typeof parsed !== 'object' || parsed === null) { throw new Error('Handshake payload is not an object') } + // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the typeof/null guard directly above is exactly what makes this an index-able object; every read below still proves its own field. const msg = parsed as Record const t = msg.type const required = typeof t === 'string' && Object.hasOwn(HANDSHAKE_STRING_FIELDS, t) - ? HANDSHAKE_STRING_FIELDS[t as HandshakeMessage['type']] + ? // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: reached only when Object.hasOwn proved t is a key of this record, on the same line. + HANDSHAKE_STRING_FIELDS[t as HandshakeMessage['type']] : null if (required === null) { // Why typeof and not String(t): a peer-supplied `{ "type": { "toString": 1 } }` makes String() @@ -96,11 +98,13 @@ export function parseHandshakeMessage(payload: Buffer): HandshakeMessage { throw new Error(`Handshake field ${field} is not a string`) } } + // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the required === null bail above already refused every t that is not one of the four keys. for (const field of HANDSHAKE_OPTIONAL_STRING_FIELDS[t as HandshakeMessage['type']]) { if (msg[field] !== undefined && typeof msg[field] !== 'string') { throw new Error(`Handshake field ${field} is not a string`) } } + // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: this is the one place the shape is proved: the type is one of the four literals and every field the union declares has been checked to be a string. return msg as unknown as HandshakeMessage } diff --git a/src/relay/relay-handshake-roundtrip.test.ts b/src/relay/relay-handshake-roundtrip.test.ts index 6f128176ca5..a65f25064d8 100644 --- a/src/relay/relay-handshake-roundtrip.test.ts +++ b/src/relay/relay-handshake-roundtrip.test.ts @@ -260,6 +260,7 @@ describe('handshake round-trip over a real Socket pair', () => { const hostileClosed = new Promise((r) => hostile.once('close', () => r())) hostile.write( encodeHandshakeFrame( + // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: deliberately a lie. This is the frame a hostile peer sends and the type system cannot describe; the cast is what lets the encoder put it on the wire. JSON.parse('{"type":"orca-relay-handshake","version":{"toString":1}}') as HandshakeMessage ) )