Repository navigation
Effect Service Conventions: 1 issue found
1 finding
apps/server/src/provider/Drivers/CodexDriver.ts:221— the new skill-discovery fallback logserror: String(error), copying arbitrary error text (including the spawnedcodex app-servercommand fromCodexAppServerSpawnError) into the log payload. Log a normalized tag (errorTag/causeErrorTagfrom@t3tools/shared/observability, as the other provider layers do) and keep the real error only ascause.
An inline review comment with a suggested fix has been posted.
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 in-scope changes:
apps/server/src/provider/Drivers/CodexDriver.ts— newlistSkillsclosure. Namespace subpath imports (import * as Duration from "effect/Duration") are correct;Effect.provideService(ChildProcessSpawner...)re-provides a dependency already acquired from the environment inside the same constructor (a legitimateR = nevernarrowing, not fake injection); the whole error channel is intentionally handled, soEffect.catchis appropriate. Only the log annotation is flagged.apps/server/src/provider/Layers/CodexProvider.ts— extraction ofopenCodexAppServerProbeplus the newlistCodexProviderSkillskeepsEffect.fnnaming, reusesbuildCodexInitializeParams()(removing a duplicated literal), and leaves scope acquisition to callers. No error-modelling changes introduced.apps/server/src/provider/Layers/ProviderRegistry.ts,Services/ProviderRegistry.ts,ProviderDriver.ts— additivelistSkillsmethod/optional instance hook. The pre-existingServices/Layerssplit andProviderRegistryShapeinterface are legacy and out of scope for this PR.apps/server/src/ws.ts,apps/server/src/auth/RpcAuthorization.ts,packages/contracts/src/{rpc,server}.ts,packages/client-runtime/src/state/server.ts— new RPC method, scope entry, and schemas follow existing patterns; failures stay in the Effect channel (Effect.orElseSucceed), with noManagedRuntime.make,runPromise, orLayer.succeedhidden-runtime usage.apps/web/src/state/queries.ts,apps/web/src/components/chat/ChatComposer.tsx,ChatView.tsx— React query/UI wiring at the framework boundary; no Effect service construction.- Tests (
ProviderRegistry.test.ts,server.test.ts,providerMaintenanceRunner.test.ts,testUtils/providerRegistryMock.ts) — focused backend behavior coverage for the new routing, using test layers rather than mocking business logic.
🔍 Agent activity — 1 tool call
💭 I'm looking at the diff to identify Effect service convention violations, starting with the CodexDriver file which uses
Effect.catchto handle errors andEffect.timeoutwith error catching, which appears acceptable for intentional error channel handling. I'm also checking the broader usage patterns ofEffect.catchagainst the guidelines to see where it's being applied appropriately. The ProviderRegistry file has a pre-existingProviderRegistryShapeinterface that the PR modifies, but since this is legacy code and the instructions say not to flag unrelated repository-wide cleanup, I'm not flagging it. However, I'm noticing thatlistSkillsreturns an Effect with no error channel, yet it callsinstanceRegistry.getInstancewhich could fail — that might be a type mismatch worth investigating. Thews.tsfile is usingEffect.orElseSucceedto swallow errors and returnOption.none(), which seems to violate the convention about keeping failures typed in the Effect layer rather than bypassing it. Let me look at the actual implementation files to verify whetherCodexDriverproperly provides service instances and whetherProviderRegistry.listSkillsis correctly typed for its error handling. I'm looking at a logging issue in CodexDriver where an error is being stringified directly into a log annotation. The problem is that this could expose sensitive information like command arguments or stderr output, which violates the logging safety guidelines that require sanitized error handling. However, stringifying errors into log annotations is pretty standard practice, so this feels like a weak finding. TheEffect.catchis properly scoped to the channel, and the pre-existingdetail: cause.messageon line 143 isn't part of the diff anyway. Moving through the other files now —ws.tslooks fine, and inProviderRegistry.ts, theinstanceRegistry.getInstancecall would cause a type error if it had an error channel since the return type specifies no error, so that's presumably safe. I'm checking for anycatchIf,catchTag,Layer.succeed,ManagedRuntime, orrunPromisepatterns in the changed code, but none appear in the diff. Now I need to look at the imports inapps/web/src/state/queries.ts. Checking the ChatComposer and contracts imports to make sure they're following conventions properly, and the CodexProvider's consolidated imports from "effect" look fine. I'm noticing the newlistCodexProviderSkillsandopenCodexAppServerProbefunctions might have resource lifecycle issues sinceLayer.buildneeds a scope to work correctly. Looking at the error handling withEffect.catch((error) => ... String(error))— this could be problematic under the logging guidelines. The error object could be aCodexAppServerSpawnErrorwith command strings and spawn stderr in its message, or aTimeoutError, or a JSON-RPC error containing wire payloads. Converting that to a string and putting it in a log annotation looks like it's capturing arbitrary defect text, which the rules explicitly prohibit. This feels like a genuine violation worth flagging. Let me check if other parts of the codebase doerror: String(error)in similar logging calls to see if this is a pattern. I'm noticing that the code usesString(error)to convert the error directly into the log payload, which goes against the repo's convention of using normalized error tags or passing the cause through proper channels. This looks like it could violate the check's rule about not copying arbitrary defect text into parallel log payloads—the check specifically wants normalized categories exposed instead. Since this is a new line in the CodexDriver.ts diff and falls under the "Errors and predicates" section, it's worth flagging. I've checked ChatComposer and it doesn't have Effect service concerns since it's React. Thews.tshandler usesEffect.orElseSucceedto swallow failures intentionally, which aligns with the convention of keeping failures typed in Effect when callers need fallback behavior. ThelistSkillsfield on the registry shape is optional as expected. Now I'm looking at whetherEffect.catchis being used appropriately—the rule says to useEffect.catchTagsfor statically known tagged failures, andEffect.catchis only appropriate when the entire error channel needs handling. In CodexDriver, the entire error channel (spawn errors, timeouts, jsonrpc errors) is being handled, so that's fine. The main issue I found is theerror: String(error)pattern—sinceEffect.catchprovides a typed error union where all errors have a_tagproperty, I should suggest replacing it witherrorTag: error._tagto preserve the error type information instead of stringifying it. The safer approach would be usingEffect.catchCausewithcauseErrorTag, which is the dominant pattern in the repo, but that requires additional imports and changes the structure. I'll describe the issue without proposing a strict diff. I should also look at theerrorTaghelper function in the shared observability module. I can useerrorTag()from the observability utilities to normalize the error, which is cleaner than manual handling. Since CodexDriver doesn't currently import from that package, I'll need to add the import statement. Let me check if there are any other issues in the diff I should address. Looking through the rest of the changes, the interface naming conventions are acceptable—ProviderRegistryListSkillsInputis fine for an input type, and the optionallistSkillsfield on the driver instance is reasonable. The contract definitions look good too. The tests are in place for the new behavior, which satisfies the testing requirement. So the only real finding is the log annotation issue, which is a modest but clear violation of the rules. Given the instructions that this check defaults to failure when there are findings, I'll mark it as failure and post an inline comment on line 221 of CodexDriver.ts about theString(error)pattern not matching the repo's convention of using errorTag or causeErrorTag.
1. modify_pr — One finding on error-log hygiene in the new Codex skill-discovery fallback. Everything else (subpath namespace imports, Effect.fn service methods, whole-channel Effect.catch, contract schemas, added focused tests) matches the conventions.
Agent Credits: 84 credits