Repository navigation
Effect Service Conventions: 1 issue found
apps/server/src/project/AgentSessionScanner.ts:29— theProjectionSnapshotQueryservice tag is imported as a named import instead of via a module namespace (import * as ProjectionSnapshotQuery from ...+ProjectionSnapshotQuery.ProjectionSnapshotQuery), diverging from the service-boundary import convention used by the siblingProjectSetupScriptRunner.tsand by this module's own test file.
Previously flagged items are resolved: AgentSessionScanError now carries the multi-value operation discriminator with a message derived from it, ws.ts passes the scanner's structural operation through instead of copying cause.message, and make is exported alongside layer.
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: apps/server/src/project/AgentSessionScanner.ts, apps/server/src/project/AgentSessionScanner.test.ts, apps/server/src/ws.ts, apps/server/src/auth/RpcAuthorization.ts, packages/contracts/src/agentSessions.ts, packages/contracts/src/rpc.ts, packages/contracts/src/settings.ts, and the new web onboarding modules.
Checks that passed:
- Effect modules imported as subpath namespaces;
@t3tools/contractskept as named imports. - Canonical single-file layout: errors,
Context.Servicetag with inline interface, exportedmake,export const layer. - Dependencies acquired from the environment via
yield*; no service-instance parameters,ManagedRuntime.make, orrunPromisein service code.Layer.succeedappears only as a test seam in the new test file. scantyped asAgentSessionScanner["Service"]["scan"].- Errors defined with
Schema.TaggedErrorClass, messages derived from structural attributes, realcausepreserved at the RPC translation boundary (mirrors the existingFilesystemBrowseErrormapping, whose optionalcauseis a contract-compatibility convention). - New backend behavior is covered by focused tests rather than mocked business logic.
🔍 Agent activity — 1 tool call
💭 Checking the PR against the previous flagged issues at commit 3905ec8 — the three fixes appear to be in place. The operation field now properly uses schema literals with a derived message, the ws.ts file correctly passes the operation from the cause, and the make function is properly exported. Now scanning the current head for new issues. There's some duplication between
AgentSessionScanFailedErrorin AgentSessionScanner.ts andAgentSessionScanErrorin the contracts, with ws.ts mapping between them. This is at the RPC boundary translating an internal error to a contract error, which is acceptable, though there's a structural difference in how the cause is defined — required as a defect in the scanner versus optional in the contract. The mapError construction is inline rather than a redundant wrapper, so it's not violating the guidelines. The previous feedback about passing the operation through was addressed, so this doesn't seem like a new violation. Looking at imports in AgentSessionScanner.ts, there's a named import ofProjectionSnapshotQueryfrom the local service module, but the convention calls for importing the service module as a namespace and accessing its public shape that way — the test file actually follows this pattern correctly. This is a violation of the established convention. Other imports likeresolveCodexHomeLayoutandexpandHomePathare fine as pure helpers. I should check how other server files import ProjectionSnapshotQuery to see if this is legacy code or a widespread pattern. The service definition order looks acceptable: imports, error class, Context.Service tag, type definitions, interfaces, helpers, then make and layer. Test layers for ServerSettings and ServerConfig are fine. The test file properly usesLayer.succeedwith the service tag andEffect.diefor unused paths. Since this is new behavior, tests are required and justified. The web-side code in agentSessions.ts is fine, and AgentSessionScanner.ts correctly uses the["Service"]accessor pattern. Now I need to check the AgentSessionScanError contracts. Looking at thecausefield in the error schema — it's marked optional withSchema.optional(Schema.Defect()), but the construction in ws.ts always passes a cause, which suggests it should be required according to the convention. That's a minor finding, though optional fields at schema boundaries might be intentional for client decoding. Let me check how other contract errors in the repo handle this pattern to understand the conventions better, then verify against the actual files at head. I'm noticing an import convention inconsistency inAgentSessionScanner.ts— it's using a named import for the service tag while its siblingProjectSetupScriptRunner.tsand the test file both use namespace imports, which violates the pattern of importing local service modules as namespaces at service boundaries. I should also look at how the contract errors handleSchema.optional(Schema.Defect())compared to other contract error patterns. There's a duplication issue here:AgentSessionScanFailedErrorin the server andAgentSessionScanErrorin the contracts have identical shapes, but only the contract error is the declared RPC error channel. The question is whether the scanner could just fail directly with the contract'sAgentSessionScanErrorinstead of wrapping the server error, since many services in this repo probably use contract errors directly. Let me check howfilesystemBrowsehandles this pattern. The filesystem browse pattern shows a consistent approach where server-internal errors get mapped to contract errors in ws.ts, which is fine. I'm noticing the duplicate error types—AgentSessionScanFailedErrorandAgentSessionScanErrorwith identical fields—and while it's borderline, the mapping preserves both the operation and cause, which aligns with the guidelines. The real question is whethercauseshould be optional in the contract. Every construction site in ws.ts includes a cause, but during rolling upgrades when clients decode contract errors, optional might be intentional—similar to howFilesystemBrowseErrorhandles it. I should check the full filesystem.ts implementation to see the pattern. The schema pattern withSchema.optional(Schema.Defect())aligns with the existing conventions, so that's good. Moving through the other new files now—the web state file imports a helper function that's straightforward, and the WelcomeWizard component uses standard hooks without any Effect service complications. Checking the ws.ts changes... the AgentSessionScanner is properly yielded and its layer is provided correctly. The test file references look fine from a convention standpoint. For the error contracts,AgentSessionScanErrorfollows the pattern with its operation discriminator, and the scanner's separate error type is acceptable. One thing to verify: in AgentSessionScanner.ts, there's a Path service being provided inside the service constructor—it's redundant since the service is already in the environment, but that's not technically a convention violation. Checking the error handling structure —AgentSessionScanFailedErroris properly required, and theContext.Serviceinterface follows the right ordering with error, tag, types, make, and layer. The main question is whether the scanner should reuse the contract error directly instead of wrapping it in a duplicate class, since the two are structurally identical, but this doesn't clearly violate the stated rules about error translation boundaries. I need to flag the import namespace violation in AgentSessionScanner.ts at line 29, but since fixing it requires coordinating changes across both the import statement and its usage at line 128, a single inline suggestion won't be self-contained. Given that this is a clear convention violation, I'll mark the check as failed.
1. modify_pr — One convention issue found in the new server service module. The three items flagged on the previous revision (redundant failure singleton on AgentSessionScanError, message-derived wrapper in ws.ts, unexported make) are all resolved.
Agent Credits: 85 credits