From bedc94c5ecbece4e594a1ff23defd0d4fbeeb193 Mon Sep 17 00:00:00 2001 From: Neil Date: Fri, 11 Sep 2026 00:19:21 -0700 Subject: [PATCH] docs(relay): the negotiation needs three conditions to become reachable, not two The note the previous commit carried lists two prerequisites. There are three, and the missing one is the one a reader cannot see from this file. validateGrant's refusal is a single `if` with two disjuncts. Deleting the `serverBuildId` clause -- prerequisite (2) -- leaves the other standing: `grant.protocolVersion !== PTY_CONSUMER_SESSION_PROTOCOL_VERSION`, a different constant from this file's RELAY_PROTOCOL_VERSION, compared for exact equality with no range, no floor and no fallback. Two peers that just negotiated a compatible relay protocol are still refused if their PTY-session constants differ by one. And there is no channel to resolve it with. Verified rather than assumed: `capabilities` on orca-relay-handshake-ok is written at exactly one site (relay-handshake.ts) and read by nothing outside tests. It is a published field with no consumer, so (3) is not 'delete another clause' -- it is 'give that field a reader first'. The error text compounds it: the refusal interpolates only the build ids, so a pure protocol-version mismatch reports as 'expected build X, got X' with two identical ids, sending the next debugger at the gate that is not the problem. Anyone implementing N+1 from the two-item list ships a broken negotiation and debugs it at the wrong gate. Recorded here because this file is what they will read first. --- src/shared/relay-protocol-version.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/shared/relay-protocol-version.ts b/src/shared/relay-protocol-version.ts index b4345ebb8a3..0a4c6303d9e 100644 --- a/src/shared/relay-protocol-version.ts +++ b/src/shared/relay-protocol-version.ts @@ -30,13 +30,27 @@ export const RELAY_PROTOCOL_VERSION = 1 * no live reader at all. * * Keep it — the mechanism is correct and hostile-input-safe, and it is the part that has to exist - * first. Making it live needs two more changes, both of which must land together: + * first. Making it live needs THREE more changes, all of which must land together. Landing only + * the first two ships a negotiation that still refuses, later and less legibly: * 1. route the bridge to the incumbent's socket rather than to its own version directory; * 2. stop `validateGrant` (`ssh-pty-consumer-session.ts`) refusing on `serverBuildId`. Its * premise, "client and relay ship in one build", is still TRUE today and becomes false the * moment (1) lands — it is a second gate that would refuse what the handshake just admitted. + * 3. give that same refusal a way to survive a protocol-version difference. It is ONE `if` with + * two disjuncts, and deleting the `serverBuildId` clause leaves the other one standing: + * `grant.protocolVersion !== PTY_CONSUMER_SESSION_PROTOCOL_VERSION` — a DIFFERENT constant + * from this file's `RELAY_PROTOCOL_VERSION`, compared for exact equality, with no range, no + * floor and no fallback. Two peers that just negotiated a compatible relay protocol are still + * refused if their PTY-session constants differ by one. And there is nothing to negotiate it + * with: `capabilities` on `orca-relay-handshake-ok` is written at exactly one site + * (`relay-handshake.ts`) and read by nothing outside tests, so (3) means giving that field a + * reader before it can carry the peer's PTY-session protocol. * - * Until both land, a change here cannot be validated by any end-to-end test, only by the + * Budget a debugging session for the error text too: the refusal interpolates only the build ids, + * so a pure protocol-version mismatch reports as "expected build X, got X" with two IDENTICAL ids, + * which points at the gate that is not the problem. + * + * Until all three land, a change here cannot be validated by any end-to-end test, only by the * handshake's own unit suite. */