Repository navigation
Effect Service Conventions: 1 issue found
apps/server/src/ws.ts:1387— the newserver.updateServerWithProgresshandler recovers the knownServerSelfUpdateErrortag withEffect.catchTag; conventions requireEffect.catchTags({ ... })even when handling a single tag.
No other violations found in the changed Effect service scope.
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 examined in scope: apps/server/src/cloud/selfUpdate.ts, apps/server/src/ws.ts, apps/server/src/auth/RpcAuthorization.ts, apps/server/src/environment/ServerEnvironment.ts, packages/client-runtime/src/state/server.ts, packages/client-runtime/src/rpc/client.ts, packages/client-runtime/src/connection/supervisor.ts, packages/contracts/src/{rpc,server,environment}.ts, and the touched web components/tests.
Checks performed and found compliant:
- Effect modules imported as subpath namespaces;
@t3tools/contractskept as named imports (allowed). ServerSelfUpdatekeeps the canonical order (errors/schemas,Context.Servicewith inline interface,make,layer); the newreportProgressparameter is a callback strategy, not service injection.packages/client-runtime/src/state/server.tsacquiresEnvironmentRegistryfrom the environment withyield* EnvironmentRegistryand exposes it in the command's requirements; noManagedRuntime.make,runPromise, orrunPromiseExitintroduced in domain code.- New failures (
ServerUpdateResumeTimeoutError,ServerUpdateProgressIncompleteError) useSchema.TaggedErrorClasswith structural attributes and derivemessagefrom them; neither has an underlying failure to preserve ascause. isRpcClientErroris now a directly exportedSchema.ispredicate rather than a private wrapper.- Log annotations use the curated
error.reasonstring; no raw command output, payloads, or credentials added.
🔍 Agent activity — 1 tool call
💭 I'm examining the diff for Effect service convention violations across several key files, particularly looking at how error classes are defined in the client runtime and whether they're following the proper patterns with
Schema.TaggedErrorClass. The error handling inserverUpdateFailureMessagederives messages from error objects for UI state, which seems appropriate. I'm also checking the import patterns — there's a named import fromeffect/unstable/rpcin the test file, which appears to be a pre-existing pattern in the codebase rather than a new violation of the consolidation convention. Now I'm spotting a concrete issue: the diff introducesEffect.catchTagin ws.ts, but the conventions explicitly require usingEffect.catchTagswith an object, even for single tags. That's a clear violation I need to flag with a line reference. I'm also looking at the callback parameter in selfUpdate.ts to check if it follows the conventions around effect signatures. I should verify the line position in ws.ts for the inline comment, check how the test file handles error creation withEffect.die, and look for any other uses ofcatchTagin the codebase before examining the handler context. I'm noticing that the code usesEffect.catchTagin the ws.ts file around line 1385, but the style guide is clear that this should beEffect.catchTagsinstead—even when handling just a single tag. This PR introduced a violation of that guideline. The repo does usecatchTagin 18 other places, but the instructions say to treat the authoritative guidance as the standard and flag violations introduced in the changed scope. Since this is explicitly enumerated in the style guide, I should report it as a finding, though it's a single instance. Now I need to examine the state/server.ts and selfUpdate.ts files more carefully to see if there are other substantive issues. I'm checking the selfUpdate.ts file to review the ServerSelfUpdateError and the failWith helper, keeping in mind the convention against creating helpers that just wrap error construction. I need to look at how scheduleRestart handles errors and ensure the new logging with error.reason follows the safety guidelines—avoiding raw wire payloads or command arguments while keeping direct error attributes and log annotations properly bounded. I should look at the restart logic and where the in-flight flag gets reset to understand the flow better. I'm checking whether the error annotation pattern witherror.reasonis a pre-existing convention by looking at the git diff to see what's actually new versus what was already there in the respawn branch. ThefailWithhelper is pre-existing throughout the file, so flagging it would require repository-wide cleanup rather than addressing just what's introduced in this PR — I'll skip that. The real issue isEffect.catchTagin ws.ts at line 1387, which the instructions explicitly prohibit, and even though the repo uses it widely elsewhere, the guidelines say to treat the instructions as authoritative over existing patterns, so this is a legitimate finding to report. I'm now examining the dependency acquisition and runtime boundaries in the client-runtime changes —createRuntimeCommandproperly usesatomRegistryand acquiresEnvironmentRegistrythrough the Effect system, and the server update action hook usage looks correct. TheEffect.tapErrorandEffect.forkChildcalls are fine, and the mutablecurrentStageclosure variable isn't a listed convention issue. One concern: the failure message derives fromerror.messageof arbitrary errors, which could expose defect text in the UI if it's an RpcClientError — but this mirrors the pre-existing pattern in ServerUpdateAction.tsx, so it's not a new issue. The contract schemas likeServerSelfUpdateProgressEventcheck out, and the new error types likeServerUpdateResumeTimeoutErroruse plain strings rather than branded types, which is acceptable. I'm also verifying that helper functions likeisLegacyUpdateHandoffLosssafely access their expected properties, and that the exported schema predicates follow the convention of exporting directSchema.ischecks rather than wrapping them in redundant functions — the diff correctly exportsisRpcClientErrornow. Looking at the import organization in ServerUpdateAction.tsx to ensure consistency with the client-runtime types. Checking the service boundary conventions — in state/server.ts, the import ofEnvironmentRegistryshould follow the pattern of importing the local service module as a namespace rather than importing the service tag directly, so it would beimport * as EnvironmentRegistrythen accessingEnvironmentRegistry.EnvironmentRegistry. Looking at the import patterns across the codebase, I see that named imports of the tag are actually the dominant pattern in production files like session.ts, threads.ts, shell.ts, and runtime.ts, whereas the namespace-only approach only appears in tests and connections.ts. Flagging this as a violation would be overly pedantic and inconsistent with what the repo already does, especially since the convention specifically calls out aliased imports rather than straightforward named imports of the same name. The real finding isEffect.catchTagin ws.ts — the instructions explicitly forbid it, and while the repo does use it elsewhere, this is a clear violation I should flag. I've checked the diff and that's the only new occurrence of catchTag or catchIf. The other changes I'm reviewing — the mutable state in supervisor.ts, the error handling in ServerUpdateResumeTimeoutError, the timeoutOption usage — all look fine and don't violate the constraints. Now I need to verify thatcreateRuntimeCommandis an existing helper that's being imported, not something new being added that would bypass the constraints. I found one instance ofEffect.catchTagin ws.ts at line 1387, but I'm not sure if that's significant enough to fail the check. The guidelines say the check defaults to failure unless there are no findings, and a clear convention violation would cause failure—but I need to determine if this is actually a violation or just a stylistic preference. Looking at the explicit instructions under "Errors and predicates," it says to useEffect.catchTagswith multiple tags and avoidcatchTagentirely. That's pretty clear, so I should flag it. Though I'm wondering if this is a deliberate test case given how commoncatchTagis across the repo. The instructions do say to treat them as authoritative regardless of existing patterns, so I'll report it. Let me check if there are other substantive findings I'm missing—looking at the error handling conventions, the update flow spanning stream, Ref, and atomRegistry, and howserverUpdateFailureMessagederives messages from unknown errors. The error message handling is interesting because it stringifies unknown errors into UI state, but that's a projection rather than an error class itself. The new error classes likeServerUpdateResumeTimeoutErrorandServerUpdateProgressIncompleteErrordon't have underlying causes, which seems fine. They're not part of a schema union, and theisLegacyUpdateHandoffLosspredicate isn't schema-derived. Inws.ts, the code usesStream.callbackwithQueue.failand catches the single known tag appropriately, importing the error type correctly. Now I'm verifying the exact line position in the diff for the inline comment — line 1387 inws.tsis indeed an added line with the right indentation. I'm posting the review suggestion for the error handling pattern.
1. modify_pr — One convention finding: the new streaming self-update handler recovers a known tagged failure with Effect.catchTag. Everything else in the changed Effect service scope (service definition/make/layer shape in apps/server/src/cloud/selfUpdate.ts, the new Schema.TaggedErrorClass errors and exported Schema.is predicate in packages/client-runtime, dependency acquisition via yield* EnvironmentRegistry) looks consistent with the conventions.
Agent Credits: 93 credits