Repository navigation
Effect Service Conventions: 1 issue found
apps/desktop/src/wsl/DesktopWslEnvironment.ts — the new windowsIpv4Interfaces() helper calls NodeOS.networkInterfaces() directly inside the production service implementation, hiding a runtime-backed dependency instead of acquiring the existing DesktopNetworkInterfaces Effect service with yield* DesktopNetworkInterfaces.DesktopNetworkInterfaces. As a result neither getDistroIpImpl's requirements nor DesktopWslEnvironment.layer's type expose the dependency, and the new behavior can only be tested through the pure pickDistroIp helper.
An inline comment with the suggested fix has been posted on the affected range.
Details
Note
Your check run agent prompt is: .macroscope/check-run-agents/effect-service-conventions.md
More information about how Check Run Agents work can be found in our Help Center.
Reviewed files in scope: apps/desktop/src/wsl/DesktopWslEnvironment.ts and apps/desktop/src/wsl/DesktopWslEnvironment.test.ts.
Checked and found compliant:
- Effect modules imported as subpath namespaces (
effect/Effect,effect/Option,effect/Layer, ...); no consolidated named imports from"effect". - Canonical module order preserved; inline
Context.Serviceinterface, singlemake-equivalent construction andexport const layerunchanged. - No
ManagedRuntime.make,runPromise, orrunPromiseExitintroduced; the onlyLayer.succeedin the file is the pre-existinglayerTestseam. - No new error classes, predicates, or
catchTag/catchIfusage; existingDesktopWslDistroListErroruntouched. - Behavior change (distro IP selection) is covered by focused unit tests on the extracted pure helpers, and the removed
hostname -Irationale comment was replaced with equivalent documentation.
Supporting evidence for the finding: apps/desktop/src/backend/DesktopNetworkInterfaces.ts defines a Context.Service wrapping NodeOS.networkInterfaces() with make/layer, and apps/desktop/src/backend/DesktopServerExposure.ts consumes it via yield* DesktopNetworkInterfaces.DesktopNetworkInterfaces with a Layer.succeed test double in DesktopServerExposure.test.ts — showing the established pattern this change bypasses.
🔍 Agent activity — 6 tool calls
💭 I'm looking at the diff to check conventions—it adds pure helpers, a
WindowsIpv4Interfaceinterface, and awindowsIpv4Interfaces()function that callsNodeOS.networkInterfaces()imperatively inside an Effect generator, and I'm weighing whether that synchronous OS read counts as a hidden side effect. The rules against hiding dependencies mention module globals, closures over singleton services, or Layer.succeed implementations calling imperative APIs, but this isn't a Layer.succeed, so there may be a platform service abstraction elsewhere in the repo worth checking.
1. browse_code — apps/desktop/src/wsl/DesktopWslEnvironment.ts
2. browse_code — apps/desktop/src/wsl/DesktopWslEnvironment.ts
💭 I'm checking the repo's conventions around imports and logging, and looking for whether there's an existing pattern for accessing network interfaces elsewhere in the codebase before using
node:osdirectly.
3. git_tools — networkInterfaces
💭 I notice there's an existing
DesktopNetworkInterfacesEffect service that properly wrapsNodeOS.networkInterfaces()with error handling, but the newDesktopWslEnvironment.tscode calls the native API directly instead, bypassing that service and hiding a dependency that should be surfaced through Effect's yield pattern. Now I want to look more closely at how the WSL environment layer is composed to see whether wiring in the proper dependency is straightforward.
4. browse_code — apps/desktop/src/backend/DesktopNetworkInterfaces.ts
5. browse_code — apps/desktop/src/wsl/DesktopWslEnvironment.ts
💭 I've confirmed there's already a dedicated
DesktopNetworkInterfacesEffect service designed to wrapNodeOS.networkInterfaces()with proper structured error handling. The PR sidesteps this entirely by importingnode:osdirectly and callingwindowsIpv4Interfaces()imperatively inside the service implementation, creating a hidden dependency on an imperative API when the convention requires acquiring Effect service dependencies from the environment viayield*. I noticeDesktopBackendConfiguration.tsdoes the same thing, but that's legacy code, and per the convention I should only flag newly introduced violations — this one is new and there's an existing service that should be used instead. The tests cover pure helpers well, but there's no service-level integration test since the dependency isn't injectable, which ties back to the same core issue: with proper dependency injection this would be testable via a Layer. I'm also noting thatgetDistroIpImpl's type signature only exposesChildProcessSpawneras a requirement, omitting the network interfaces dependency it actually uses — violating the convention that make/layer types must expose all their requirements. I'm confirming this is a single, clear finding worth failing the check on: a hidden imperative dependency where an existing Effect service should be used instead. The fix would require touching multiple places (thegetDistroIpImplsignature and its layer), so I'll describe the fix in prose rather than providing a diff, and point the comment at thewindowsIpv4Interfacesfunction around lines 768-783. Time to write up the review comment and post it.
6. modify_pr — One convention violation found: the new distro-IP probe reads the Windows network interfaces through a direct node:os call inside the Effect service implementation instead of acquiring the existing DesktopNetworkInterfaces service from the environment.
Agent Credits: 53 credits