Repository navigation
Effect Service Conventions: 1 issue found
apps/server/src/mcp/PendingRequestMcpService.test.ts:31— service module members are imported as bare names (import { layer, PendingRequestMcpService } from "./PendingRequestMcpService.ts"), erasing the module namespace at a service boundary. Useimport * as PendingRequestMcpService from "./PendingRequestMcpService.ts"and referencePendingRequestMcpService.PendingRequestMcpService/PendingRequestMcpService.layer, matchingOrchestratorMcpService.test.ts.
Previously flagged typing issues in PendingRequestMcpService.ts are resolved: isMissingChild/projectionFailure now take ThreadManagementError with an exhaustive _tag switch, and dispatchFailure takes OrchestratorV2Error.
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/mcp/PendingRequestMcpService.ts, PendingRequestMcpService.test.ts, McpModeCeilings.ts, McpHttpServer.ts, OrchestratorMcpService.ts, toolkits/pendingRequest/{tools,handlers}.ts, orchestration-v2/Orchestrator.ts, orchestration-v2/ThreadManagementService.ts, packages/contracts/src/pendingRequestMcp.ts, packages/shared/src/t3McpToolPresentation.ts.
Checked and found compliant:
- Effect modules imported from subpaths as namespaces; no consolidated
from "effect"imports in touched code. PendingRequestMcpServicedefines its interface inline inContext.Service, exports a realmakeacquiringCrypto.CryptoandThreadManagementServicefrom the environment, and exportslayerviaLayer.effect;McpHttpServer.tsconsumes it as a module namespace.- No
ManagedRuntime.make,runPromise, orrunPromiseExitintroduced; no service instances passed as constructor parameters in production code. Test usesLayer.mock(ThreadManagementService)as a legitimate seam. PendingRequestMcpFailureusesSchema.TaggedErrorClasswith acodediscriminator, mirroring the established siblingOrchestratorMcpFailurecontract for MCP tool failures; message text is caller-visible tool output derived from structured request/thread identifiers rather than stringified defects.enforceRuntimeRequestPolicyCeilinginOrchestrator.tsconstructsOrchestratorDispatchErrorat the failure boundary using the module's existing string-cause convention.- Backend behavior changes are covered by focused unit tests plus the MCP toolkit integration test.
🔍 Agent activity — 14 tool calls
💭 I want to check whether the previously flagged issues in PendingRequestMcpService.ts at lines 88, 111, and 118 have been resolved in the current head, or if new problems have appeared, so I'll look at the actual file contents at commit 86498ed.
1. browse_code — apps/server/src/mcp/PendingRequestMcpService.ts
2. browse_code — apps/server/src/mcp/McpModeCeilings.ts
💭 Good, the earlier issues with error typing are resolved now. I'm checking whether the generic
errorMessagehelper that stringifies unknown errors, used across a few call sites, is still worth flagging like it was in the previous commit's review. I'm also considering whether the pattern of usingEffect.matchEffectwith a structuralisMissingChildpredicate over tags conflicts with the guideline preferringEffect.catchTagfor statically known tagged failures. Since one variant requires nested cause inspection rather than pure tag matching, it's borderline enough that I'll leave it unflagged, and I'm satisfied the privateSchema.ispredicates aren't being redundantly re-wrapped elsewhere. Checking import conventions next: the pure helper module import is fine with named imports, and the type-only import in PendingRequestMcpService.ts is also fine, but I'm noticing inconsistent styles across files — some import McpInvocationContext as a namespace, others use named imports for the service tag, which conflicts with the convention of importing local service modules as namespaces at service boundaries. I want to check how sibling orchestrator toolkit files handle this to see if there's an established consistency pattern, especially around aliasing that erases namespace clarity. Looking at the service definition file order in PendingRequestMcpService.ts, the tag placement relative to helper functions likeparseListCursorandfailureseems like a minor structural quirk but not a real issue since function hoisting handles the reference order fine. The more substantive concern isPendingRequestMcpFailure— it's defined with a structured error class but leans on a free-form message string alongside a 13-valuecodediscriminator, which conflicts with the convention that distinct failure reasons driving different user-facing messages or control flow should be split into separate error classes rather than bundled under one discriminator. I want to checkorchestratorMcp.tsfor the siblingOrchestratorMcpServicefailure type to see if this shape is already an established pattern for MCP tool failures before deciding whether to flag it, since the review guidance says to weigh existing conventions rather than blindly enforcing the newer instruction. I also note thegetCommandReceiptaddition toOrchestratorV2Shapeis just extending a pre-existing legacy interface, not introducing a new violation, and the optionalreplayedfield isn't really an Effect-convention concern either. Let me go look at that failure shape and the orchestrator toolkit now.
3. git_tools — TaggedErrorClass|Schema.Literals([
4. browse_code — apps/server/src/mcp/toolkits/orchestrator/handlers.ts
💭 The failure schema matches the existing OrchestratorMcpFailure pattern, so no issue there. Looking now at the other diff hunks for Effect conventions across OrchestratorMcpService.ts, Orchestrator.ts, and ThreadManagementService.ts, I notice runtimeModeRank and interactionModeRank were moved to McpModeCeilings.ts but appear to have been duplicated back in Orchestrator.ts instead of cleanly removed. That duplication is more of a DRY concern than a strict Effect service convention violation, and it might actually be intentional given that Orchestrator shouldn't import from the mcp layer, so I'll skip flagging it. The ThreadManagementServiceShape interface is pre-existing, nothing new there. Now I want to check McpInvocationContext.ts and compare import styles—namespace import versus named imports—against how orchestrator/tools.ts handles this same pattern.
5. browse_code — apps/server/src/mcp/toolkits/orchestrator/tools.ts
6. browse_code — apps/server/src/mcp/McpInvocationContext.ts
💭 This looks consistent with existing patterns. I'm double-checking that OrchestratorMcpService.ts doesn't have leftover unused imports after the rank functions were removed, then moving to review the file layout convention for the new PendingRequestMcpService.ts file. The service tag, make, and layer are positioned correctly amid the helper functions, dependency acquisition looks right pulling in Crypto and ThreadManagementService, and the layer definition follows the expected pattern. The test file mocking ThreadManagementService is an acceptable test seam. I'm now scrutinizing the test file's import style—it imports
layerandPendingRequestMcpServiceas named exports rather than importing the module as a namespace, which could violate the convention around preserving the module namespace at service boundaries. I need to flag whether this barelayeridentifier usage erases that namespace pattern. I want to check other error message derivations (like errorMessage on structured errors) to confirm consistency, and I'm now comparing this test's import style against similar test files for other services to determine whether flagging it is warranted. I'm now scanning the remaining diff for other stub layers or context usage patterns (like PendingRequestMcpService, McpInvocationContext) to see if they follow the same idiomatic Effect style as the orchestrator handlers, and checking tools.ts imports for anything else worth flagging. TheerrorMessagehelper andstablePartfunction look consistent with existing conventions and prior review comments, so I'm confirming those concerns are already resolved. Also checking the earlier flag onisMissingChild/projectionFailure— those now use a properly typedThreadManagementErrorwith an exhaustive switch, so that's resolved too. Next I want to diff from that last reviewed commit to head to see what's changed since then.
7. git_tools — f6002bf..86498ed
💭 Since the branch was likely force-pushed, I should review the current head thoroughly for any remaining violations. I want to check the other changed production files—Orchestrator.ts, ThreadManagementService.ts, OrchestratorMcpService.ts around resolveRuntimeMode, and McpHttpServer.ts—and verify whether the RuntimeMode/ProviderInteractionMode imports became unused types. Looking closer, I notice the new enforceRuntimeRequestPolicyCeiling function creates an OrchestratorDispatchError whose cause field is populated with a plain string rather than a real underlying error, which conflicts with the convention that cause should preserve the actual failure and that Defect shouldn't just stringify an opaque cause. I want to check whether this pattern already exists elsewhere in Orchestrator.ts's other OrchestratorDispatchError usages.
8. git_tools — new OrchestratorDispatchError({
💭 The string-cause pattern is already widespread in Orchestrator.ts, so this isn't a new violation worth flagging. The getCommandReceipt addition to OrchestratorV2Shape follows the same pre-existing legacy pattern, and since this PR isn't refactoring these services, I won't flag it either. I also want to check whether PendingRequestMcpService's use of matchEffect with a predicate to recover from tagged errors should be flagged instead of using catchTags—it handles a pure-tag case plus a nested cause check, which catchTags alone couldn't do, so the approach seems justified even though the resulting undefined-or-projection return type feels a little hacky. Actually,
Effect.catchIf(isMissingChild, ...)might be cleaner since nested cause inspection counts as a structural predicate per the guidance, so the current code is acceptable. Now I want to look at the remaining changed hunks I haven't reviewed yet in OrchestratorMcpService.ts and McpHttpServer.ts.
9. browse_code — apps/server/src/mcp/OrchestratorMcpService.ts
10. browse_code — apps/server/src/mcp/McpHttpServer.ts
💭 Everything checks out consistently with existing patterns. I want to verify PendingRequestMcpService.ts exports match how it's imported in McpHttpServer.ts and the handlers, then compare the test file's import style against similar test files like OrchestratorMcpService or WorktreeMcpService to confirm convention.
11. git_tools — from "./(PendingRequestMcpService|OrchestratorMcpService|WorktreeMcpService).ts"
💭 The new test file uses a bare
layerimport instead of the namespaced form likePendingRequestMcpService.layerthat other test files follow, which weakens the module boundary convention. I'm weighing whether this deserves a flagged finding, since it's only in a test file. I'll treat this as a real but low-severity convention violation rather than one that fails the check outright, since the naming convention is explicit even though this instance is confined to test scope. Fixing this properly would mean changing both the import and its usage across lines, so I'll note it without proposing an inline diff. Now I'm also checking whether the newfailure()helper is just a trivial wrapper constructing an error object, which the guidelines say to avoid adding. But I notice the sibling OrchestratorMcpService.ts already uses this same pattern extensively, so it's an established convention here even if it technically conflicts with the general rule about not hiding error construction behind a helper. Given that prior reviews of this file already saw thefailurehelper and chose not to flag it, re-flagging now would be inconsistent and would just add noise against a pattern that's clearly repo-wide in the MCP services. I'll skip it and move on to double-checking the test import usage and whether other new source files also use consolidated "effect" imports.
12. git_tools — from "effect"
13. browse_code — apps/server/src/mcp/PendingRequestMcpService.test.ts
💭 The only remaining issue is that bare
layernamed import in the test file, which the convention flags as namespace-erasing. Since fixing it would require changes at both the import line and its usage further down, I'll skip a diff-based suggestion and just describe the fix as a note instead. Now I'm weighing whether this is severe enough to fail the check, since the rules say any finding causes failure while "All clear" is only for zero findings. Looking at the sibling test file, I see it correctly uses a namespace import, while this one uses the unaliased anti-pattern — so the repo already has the right pattern established elsewhere, reinforcing that this is a genuine violation worth flagging. Okay, I'll settle on flagging it: the test file uses both the tag and layer from the module, which is exactly the multi-member case the convention prescribes namespace imports for, and the canonical sibling test follows that pattern too. I'll post the review comment noting this.
14. modify_pr — Reviewed the new PendingRequestMcpService, its toolkit wiring, and the orchestration/contract call sites against the Effect service conventions. The earlier typing findings (isMissingChild/projectionFailure/dispatchFailure now take the statically known error unions and switch exhaustively on _tag) are resolved. One remaining service-boundary import issue below; everything else — make/layer shape, environment-based dependency acquisition, namespace import in McpHttpServer.ts, and the Layer.mock test seam — looks consistent with the conventions.
Agent Credits: 145 credits
Token usage: 20 uncached input · 820,605 cache-read input · 106,069 cache-write input · 12,085 output
Agent Credits may also include non-token charges from external tools such as web research.