Repository navigation
Effect Service Conventions: 1 issue found
apps/desktop/src/cua/CuaDriverServerEnvironment.ts:77 — CuaDriverConfigurationError is constructed with a fabricated binaryPath: "<not configured>" for the missing-configuration case, producing the misleading message Could not configure embedded cua-driver at '<not configured>'. This pure validation failure is semantically distinct from the toFileUrl failure (which has a real path and cause) and should be its own tagged error, handled with Effect.catchTags in DesktopApp.ts.
The prior finding on the required cause field has been addressed (cause is now Schema.optional(Schema.Defect())).
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.
Files reviewed in scope:
apps/desktop/src/cua/CuaDriverServerEnvironment.ts(+ test)apps/desktop/src/app/DesktopApp.tsapps/server/src/cua/CuaDriverEmbedded.ts(+ test)apps/server/src/serverRuntimeStartup.tsapps/server/src/orchestration-v2/Adapters/CodexAdapterV2.ts(+ test)apps/server/src/provider/Layers/codexLaunchArgs.ts(+ test)apps/web/src/components/settings/SettingsPanels.tsxpackages/contracts/src/settings.ts(+ test)
Checked and found conforming:
- All Effect modules imported as namespaces from
effect/*subpaths; named imports are limited to whole packages and pure-helper modules, matching existing repo practice (installDesktopIpcHandlers,startupAccess.ts). - No new
Context.Servicedefinitions, so service layout/make/layerrules do not apply; the new modules are scoped effect helpers. - No
ManagedRuntime.make,runPromise, orrunPromiseExitintroduced; no service instances passed as constructor parameters.Path.Pathis acquired from the environment viayield*. Effect.catchuses inDesktopApp.ts,serverRuntimeStartup.ts, andmonitorEmbeddedCuaDriverExiteach intentionally handle the whole error channel.CuaDriverStartErrorpreserves the immediatecauseat every wrapping site and derivesmessagefrombinaryPathonly.cause: String(error.cause)in log annotations follows the existing repository-wide logging pattern and was not flagged.
🔍 Agent activity — 1 tool call
💭 I'm looking at the changed files to see what's been addressed. The previous feedback about the optional cause in
CuaDriverEmbedded.tshas already been handled — the file appears to have been refactored andCuaDriverServerEnvironment.tsnow properly includescause: Schema.optional(Schema.Defect()). Let me check what the current state of the head looks like. Looking at the error modeling inCuaDriverServerEnvironment.ts, I notice it's using a sentinel value"<not configured>"as the binaryPath when the driver isn't configured. This is problematic because it conflates two distinct failure modes — the driver not being configured versus a toFileUrl failure — both using the same error class. The message would read something like "Could not configure embedded cua-driver at ''", which is semantically awkward. This violates the principle of capturing stable, serializable domain context without encoding the same distinction twice. The sentinel placeholder in a structural field is a questionable pattern that might be worth flagging. ForCuaDriverEmbedded.ts, the code readsprocess.envdirectly inside Effect functions rather than acquiring it through Effect's configuration or service layer. The conventions around hiding dependencies in module globals apply when creating or consuming Effect services, and these are just plain Effect functions without a Context.Service or layer, so it's not necessarily a violation. I should check howEffect.catchis being used elsewhere to see if there's a pattern. Looking at the error handling inCuaDriverEmbedded.ts, theCuaDriverStartErrorwraps three distinct failures (module import, host construction, start) under a single error tag without any operation discriminator to distinguish between them. The conventions suggest either adding a multi-valuestageoroperationfield to identify which step failed, or splitting them into separate error classes entirely. Now I need to check the actual repo to see what utilities are available and verify the error handling patterns in files likeserverRuntimeStartup.ts, particularly around how causes are being logged and whether the string conversion of error causes aligns with the conventions. I'm identifying remaining violations in the error handling approach. ThebinaryPath: "<not configured>"sentinel is problematic because it conflates two semantically distinct failures—a missing driver configuration versus a failed module URL build. These should be split into separate error classes rather than forcing different failure modes into the same field with a placeholder value. I'm also reviewing other potential issues:Effect.catchusage appears acceptable when the entire error channel is intentionally handled, and I'm examining how error causes are stringified in log annotations to ensure they stay bounded and preserve exact error information. Passing the cause value directly instead of stringifying it would be more consistent. Looking at module-level dependencies, the code readsprocess.envdirectly in Effect code rather than through a service, which goes against the convention of avoiding hidden dependencies in module globals. The repo does usePath.Pathin the desktop version, andcodexLaunchArgstakes an environment parameter, but I'm not seeing a clear existing pattern for how this should be handled. That said, this isn't technically a service violation based on the rules provided. TheinstallCodexLaunchArgsfunction returning a thunk that produces an Effect is fine, and sincestartEmbeddedCuaDriveris a scoped effect used during startup rather than a service being created or refactored, it doesn't require a Context.Service definition. For the imports, the namespace subpath imports look good, but I'm checking whether CuaDriverServerEnvironment should be imported as a namespace at the service boundary. It's just a module of pure helpers and effect functions without a Context.Service tag, so the convention about importing service modules as namespaces might not apply here. Let me look at how DesktopApp handles similar helper modules — it seems to use namespace imports for things like DesktopAppSettings. I should check what pattern other non-service modules follow in the desktop repo, and also see how serverRuntimeStartup and CodexAdapterV2 handle their imports from similar utility modules. The named imports align with how the repo handles non-service modules, so that's consistent. Now I'm weighing whether these Cua modules should be services—startEmbeddedCuaDriverreads and mutatesprocess.envdirectly, which technically violates the principle about hiding dependencies in globals or singleton closures, though environment access is a bit of a gray area for these conventions. The more pressing issue is that sentinelbinaryPath: "<not configured>"string. It's not real domain context—it's a placeholder masquerading as a path, and when it appears in logs like "Could not configure embedded cua-driver at ''", it's misleading. The conventions suggest splitting semantically distinct failures into separate error classes: missing configuration should be separate from file-URL construction failures. Since the prior run flagged an issue in this same area that the author fixed, I should check what's changed between those commits to see if new violations have crept in. I'm weighing whether to flag the sentinelbinaryPathas a violation and considering how to handle the error class design — either makingbinaryPathoptional or creating a separateCuaDriverNotConfiguredErrorclass, though the latter would require updating the desktop caller that currently accesseserror.binaryPathin its logging. The sentinel value might be a legitimate finding, but it's borderline nitpicking and could come across as overly strict. Let me look for stronger violations elsewhere. I'm checking the UI components and adapter code now — theCodexAdapterV2change is interesting because it readsprocess.envinside a Layer factory, which could be a hidden global dependency, though it seems intentional for live environment variables. I need to examine the broader service context around this to see if there's a real convention violation. I'm spotting a couple of issues here. The main one is that sentinel valuebinaryPath: "<not configured>"standing out as a code smell. There's also the logging inserverRuntimeStartup.tswhere it's convertingerror.causeto a string and mixing that unstructured text into a structured error log, which breaks the logging convention. The convention is clear: preserve the exact underlying value ascause, don't stringify arbitrary defect text into the log payload. So logging{ binaryPath, cause: String(error.cause) }violates that — they're stringifying when they should be passing the raw value. Let me search the codebase to see if this pattern shows up elsewhere or if it's an isolated violation. There's an established pattern here that shouldn't be flagged. Looking at the convention more carefully—it asks for stable, serializable domain context like operation, resource path, and normalized status. Using a fake"<not configured>"path feels like a workaround rather than proper context. Plus, the guidance about splitting failures into separate error classes only applies when there's a discriminator choosing different user messages, but both cases produce the same message here. Now I need to figure out the response format. The check defaults to failure but should return "All clear" if there are no findings—which seems contradictory at first. The system requires JSON output, so I'll interpret this as: no violations means a success state with the summary "All clear" in JSON format. I'm also reconsidering whether to flag the sentinel comment and whether the desktop-side "not configured" scenario can actually occur given how the configuration function is called. Looking at the environment variable handling, the dev case requiresT3CODE_CUA_DRIVER_PATHto be set or it errors, which then shows the "Cua could not start" dialog to the user—that's reasonable. TheconfigureCuaDriverServerEnvironmentfunction reads fromprocess.envdirectly for the default parameter, which is slightly inconsistent with taking an environment parameter but acceptable. ThereplaceCuaDriverServerEnvironmentfunction usesEffect.addFinalizerwhich requires a Scope, and I need to verify that the startup effect actually has one available. ThedisableCuaDriverServerEnvironmentfinalizer restores the inherited environment at scope close, which is semantically odd but not a convention violation. Finally, the error handling in DesktopApp catches errors, but the error channel fromconfigureCuaDriverServerEnvironmentis specifically typed asCuaDriverConfig. TheCuaDriverStartErroris used across three distinct stages—module import, host construction, and process start—but lacks a stage discriminator field, so logs can't distinguish which step failed. While the convention doesn't require multi-value discriminators, adding anoperationorstagefield would follow the principle of mapping failures with known context rather than wrapping an entire pipeline in one generic error. I'm also reconsidering the sentinelbinaryPathissue more carefully against the stated rules. The rule against manufacturing placeholder data to populate required structural attributes applies here—creating a misleading message for a pure validation error violates the spirit of not fabricating data. I should flag this with a concrete fix: introduce a distinct error type likeCuaDriverNotConfiguredinstead. Since the DesktopApp caller spreadserror.binaryPath, I'll need to either makebinaryPathoptional in the schema or create a separate error class and update the caller. I'll post an inline comment on line 77 of CuaDriverServerEnvironment.ts describing the issue and the fix approach. The simpler approach would be makingbinaryPathoptional in the schema with a conditional message, though that still requires tweaking the message getter. I'm leaning toward marking this as a failure since it's a genuine modeling violation, despite the single moderate finding—the explicit guidance in the instructions points that way, even if the risk of a false positive feels manageable. Let me verify the line number in the diff matches what I'm seeing: line 77 in the new 100-line file shows the error being thrown with a placeholder value, which confirms the issue. I'll post the review with the failure designation.
1. modify_pr — Effect service conventions review: one error-modeling issue found in the new Cua modules. Everything else (namespace imports from effect/*, Schema.TaggedErrorClass usage, scoped finalizers, Path.Path acquired from the environment, whole-channel Effect.catch) matches the conventions.
Agent Credits: 86 credits