| ... | ... | @@ -683,7 +683,7 @@ describe("EnvironmentRegistry", () => { |
| 683 | 683 | |
| 684 | 684 | it.effect("only a fresh health check for the rejected environment unlocks it", () => |
| 685 | 685 | Effect.gen(function* () { |
| 686 | | const harness = yield* makeHarness([RELAY_TARGET], [], [], { |
| 686 | const harness = yield* makeHarness([RELAY_TARGET, SECOND_RELAY_TARGET], [], [], { |
| 687 | 687 | initialDisabled: [RELAY_TARGET.environmentId], |
| 688 | 688 | }); |
| 689 | 689 | const descriptor = (environmentId: EnvironmentId): ExecutionEnvironmentDescriptor => ({ |
| ... | ... | @@ -778,8 +778,8 @@ describe("EnvironmentRegistry", () => { |
| 778 | 778 | yield* SubscriptionRef.update(discoveryState, (state) => ({ |
| 779 | 779 | ...state, |
| 780 | 780 | environments: new Map(state.environments).set( |
| 781 | | SECOND_TARGET.environmentId, |
| 782 | | discovered(descriptor(SECOND_TARGET.environmentId)), |
| 781 | SECOND_RELAY_TARGET.environmentId, |
| 782 | discovered(descriptor(SECOND_RELAY_TARGET.environmentId)), |
| 783 | 783 | ), |
| 784 | 784 | })); |
| 785 | 785 | yield* Deferred.await(unrelated); |
| ... | ... | @@ -798,8 +798,8 @@ describe("EnvironmentRegistry", () => { |
| 798 | 798 | environments: new Map([ |
| 799 | 799 | [RELAY_TARGET.environmentId, discovered(descriptor(RELAY_TARGET.environmentId))], |
| 800 | 800 | [ |
| 801 | | SECOND_TARGET.environmentId, |
| 802 | | discovered(descriptor(SECOND_TARGET.environmentId), "2026-09-15T00:01:00Z"), |
| 801 | SECOND_RELAY_TARGET.environmentId, |
| 802 | discovered(descriptor(SECOND_RELAY_TARGET.environmentId), "2026-09-15T00:01:00Z"), |
| 803 | 803 | ], |
| 804 | 804 | ]), |
| 805 | 805 | })); |
| ... | ... | @@ -827,6 +827,92 @@ describe("EnvironmentRegistry", () => { |
| 827 | 827 | }), |
| 828 | 828 | ); |
| 829 | 829 | |
| 830 | it.effect("discovery leaves direct connections that share an environment id alone", () => |
| 831 | Effect.gen(function* () { |
| 832 | const harness = yield* makeHarness([TARGET, RELAY_TARGET]); |
| 833 | const discovered = (environmentId: EnvironmentId) => { |
| 834 | const endpoint = { |
| 835 | httpBaseUrl: "https://relay.example.test", |
| 836 | wsBaseUrl: "wss://relay.example.test", |
| 837 | providerKind: "manual" as const, |
| 838 | }; |
| 839 | return { |
| 840 | environment: { |
| 841 | environmentId, |
| 842 | label: "Preview server", |
| 843 | endpoint, |
| 844 | linkedAt: "2026-09-25T00:00:00Z", |
| 845 | }, |
| 846 | availability: "online" as const, |
| 847 | status: Option.some<RelayEnvironmentStatusResponse>({ |
| 848 | environmentId, |
| 849 | endpoint, |
| 850 | status: "online", |
| 851 | checkedAt: "2026-09-25T00:00:00Z", |
| 852 | descriptor: { |
| 853 | environmentId, |
| 854 | label: "Preview server", |
| 855 | platform: { os: "darwin", arch: "arm64" }, |
| 856 | serverVersion: "2.0.0", |
| 857 | orchestrationProtocolVersion: ORCHESTRATION_PROTOCOL_VERSION + 1, |
| 858 | capabilities: { repositoryIdentity: true }, |
| 859 | }, |
| 860 | }), |
| 861 | error: Option.none(), |
| 862 | }; |
| 863 | }; |
| 864 | yield* Effect.gen(function* () { |
| 865 | const registry = yield* EnvironmentRegistry.EnvironmentRegistry; |
| 866 | yield* registry.start; |
| 867 | yield* awaitConnectionState( |
| 868 | registry, |
| 869 | TARGET.environmentId, |
| 870 | (state) => state.phase === "connected", |
| 871 | ); |
| 872 | const relayChecked = yield* Deferred.make<void>(); |
| 873 | yield* watchDiscoveredCompatibility().pipe( |
| 874 | Effect.provideService(EnvironmentRegistry.EnvironmentRegistry, { |
| 875 | ...registry, |
| 876 | setCompatibility: (environmentId, error) => |
| 877 | registry |
| 878 | .setCompatibility(environmentId, error) |
| 879 | .pipe( |
| 880 | Effect.andThen( |
| 881 | environmentId === RELAY_TARGET.environmentId |
| 882 | ? Deferred.succeed(relayChecked, undefined) |
| 883 | : Effect.void, |
| 884 | ), |
| 885 | ), |
| 886 | }), |
| 887 | Effect.provideService( |
| 888 | RelayEnvironmentDiscovery.RelayEnvironmentDiscovery, |
| 889 | RelayEnvironmentDiscovery.RelayEnvironmentDiscovery.of({ |
| 890 | state: |
| 891 | yield* SubscriptionRef.make<RelayEnvironmentDiscovery.RelayEnvironmentDiscoveryState>( |
| 892 | { |
| 893 | ...RelayEnvironmentDiscovery.EMPTY_RELAY_ENVIRONMENT_DISCOVERY_STATE, |
| 894 | environments: new Map([ |
| 895 | [TARGET.environmentId, discovered(TARGET.environmentId)], |
| 896 | [RELAY_TARGET.environmentId, discovered(RELAY_TARGET.environmentId)], |
| 897 | ]), |
| 898 | }, |
| 899 | ), |
| 900 | refresh: Effect.void, |
| 901 | }), |
| 902 | ), |
| 903 | Effect.forkScoped, |
| 904 | ); |
| 905 | yield* Deferred.await(relayChecked); |
| 906 | |
| 907 | const entries = yield* SubscriptionRef.get(registry.entries); |
| 908 | expect(entries.get(RELAY_TARGET.environmentId)).toMatchObject({ enabled: false }); |
| 909 | expect(entries.get(TARGET.environmentId)).toMatchObject({ enabled: true }); |
| 910 | expect(entries.get(TARGET.environmentId)?.unsupportedReason).toBeUndefined(); |
| 911 | expect((yield* registry.state(TARGET.environmentId)).phase).toBe("connected"); |
| 912 | }).pipe(Effect.provide(harness.layer), Effect.scoped); |
| 913 | }), |
| 914 | ); |
| 915 | |
| 830 | 916 | it.effect("discovery keeps unsupported environments off until compatibility changes", () => |
| 831 | 917 | Effect.gen(function* () { |
| 832 | 918 | const harness = yield* makeHarness([RELAY_TARGET], [], [], { |