From c21600ac1af27350e85095dda8f24ded294eb9c2 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Thu, 12 Nov 2026 07:01:18 +0000 Subject: [PATCH 1/2] test(client-runtime): pairing a host with this client's own environment id fails without spending the code Reproduces #27359. Fails on main: registerPairing redeems the code and returns the id as if it succeeded. AI-assisted; verified with the tests and tools listed above. --- .../src/connection/onboarding.test.ts | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/client-runtime/src/connection/onboarding.test.ts b/packages/client-runtime/src/connection/onboarding.test.ts index 2131507e547f7..df4b182ee95d5 100644 --- a/packages/client-runtime/src/connection/onboarding.test.ts +++ b/packages/client-runtime/src/connection/onboarding.test.ts @@ -442,9 +442,10 @@ describe("connection onboarding", () => { }), }, ] as const)( - "leaves a platform-managed $kind environment untouched when its id is paired", - ({ registration }) => - Effect.gen(function* () { + "refuses to pair a host reporting the platform-managed $kind environment's id, keeping the code", + ({ registration }) => { + const calls: Array<{ readonly url: string; readonly init: RequestInit }> = []; + return Effect.gen(function* () { const registry = yield* EnvironmentRegistry.EnvironmentRegistry; const onboarding = yield* Onboarding.ConnectionOnboarding; yield* registry.reconcilePlatform([registration]); @@ -455,11 +456,18 @@ describe("connection onboarding", () => { unsupportedReason: UNSUPPORTED_ERROR.message, }); - const environmentId = yield* onboarding.registerPairing(PAIRING_INPUT); + const error = yield* onboarding.registerPairing(PAIRING_INPUT).pipe(Effect.flip); - expect(environmentId).toBe(PAIRED_ENVIRONMENT_ID); + expect(error).toMatchObject({ + _tag: "ConnectionBlockedError", + reason: "configuration", + }); + expect(calls.map((call) => call.url)).toEqual([ + "https://remote.example.test/.well-known/t3/environment", + ]); expect(yield* SubscriptionRef.get(registry.entries)).toEqual(before); - }).pipe(Effect.provide(layerPairingOnboarding())), + }).pipe(Effect.provide(layerPairingOnboarding(undefined, calls))); + }, ); it.effect("leaves a switched-off environment unchanged when the pairing exchange fails", () => From 2126c8964bcdea8a6e63ddbb4b4e73928c3105ff Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Thu, 12 Nov 2026 07:05:14 +0000 Subject: [PATCH 2/2] fix(client-runtime): pairing a host that reports this client's own environment id fails before spending the code Fixes pingdotgg/t3code#27359 assertKnownAddress skipped platform-managed environment ids, and register returned false for them, so pairing redeemed the one-time code and reported success while saving nothing. The pre-exchange check now refuses a platform-managed id with a clear error, and register runs the same check under the lease before its platform short-circuit. AI-assisted; verified with the tests and tools listed above. Co-Authored-By: Claude Opus 5.5 --- .../client-runtime/src/connection/registry.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/client-runtime/src/connection/registry.ts b/packages/client-runtime/src/connection/registry.ts index 12f8aa5ec505f..6cb74a0e39e49 100644 --- a/packages/client-runtime/src/connection/registry.ts +++ b/packages/client-runtime/src/connection/registry.ts @@ -109,8 +109,9 @@ export class EnvironmentRegistry extends Context.Service< options?: { readonly knownAddressOnly?: boolean }, ) => Effect.Effect; /** - * Fails when the route would add a new address to a saved user environment. Pairing that does - * not target an environment checks this, because the server reports its own environment id. + * Fails when the route would add a new address to a saved user environment, or names a + * platform-managed one. Pairing that does not target an environment checks this, because the + * server reports its own environment id. */ readonly assertKnownAddress: ( route: ConnectionRoute, @@ -545,8 +546,13 @@ export const make = Effect.gen(function* () { route: ConnectionRoute, ) { const environmentId = route.target.environmentId; - if ((yield* Ref.get(platformEnvironmentIds)).has(environmentId)) return; const saved = (yield* SubscriptionRef.get(entries)).get(environmentId); + if ((yield* Ref.get(platformEnvironmentIds)).has(environmentId)) { + return yield* new ConnectionBlockedError({ + reason: "configuration", + detail: `That machine reports the same environment ID as ${saved?.target.label ?? "an environment this app already manages"}, so it can't be added. This happens when one machine's T3 data was copied to another.`, + }); + } if ( saved !== undefined && findRouteToSameAddress(connectionRoutes(saved), route) === undefined @@ -568,12 +574,12 @@ export const make = Effect.gen(function* () { return yield* withLeaseLock( environmentId, Effect.gen(function* () { - if ((yield* Ref.get(platformEnvironmentIds)).has(environmentId)) { - return false; - } if (options?.knownAddressOnly === true) { yield* assertKnownAddress(route); } + if ((yield* Ref.get(platformEnvironmentIds)).has(environmentId)) { + return false; + } const previous = (yield* SubscriptionRef.get(entries)).get(environmentId); let entry = registered; if (previous !== undefined) {