Skip to content

fix(mcp): preserve empty option descriptions

MacroscopeApp / Macroscope - Effect Service Conventions failed Aug 30, 2026 in 3m 5s

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. Use import * as PendingRequestMcpService from "./PendingRequestMcpService.ts" and reference PendingRequestMcpService.PendingRequestMcpService / PendingRequestMcpService.layer, matching OrchestratorMcpService.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.
  • PendingRequestMcpService defines its interface inline in Context.Service, exports a real make acquiring Crypto.Crypto and ThreadManagementService from the environment, and exports layer via Layer.effect; McpHttpServer.ts consumes it as a module namespace.
  • No ManagedRuntime.make, runPromise, or runPromiseExit introduced; no service instances passed as constructor parameters in production code. Test uses Layer.mock(ThreadManagementService) as a legitimate seam.
  • PendingRequestMcpFailure uses Schema.TaggedErrorClass with a code discriminator, mirroring the established sibling OrchestratorMcpFailure contract for MCP tool failures; message text is caller-visible tool output derived from structured request/thread identifiers rather than stringified defects.
  • enforceRuntimeRequestPolicyCeiling in Orchestrator.ts constructs OrchestratorDispatchError at 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 errorMessage helper 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 using Effect.matchEffect with a structural isMissingChild predicate over tags conflicts with the guideline preferring Effect.catchTag for 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 private Schema.is predicates 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 like parseListCursor and failure seems like a minor structural quirk but not a real issue since function hoisting handles the reference order fine. The more substantive concern is PendingRequestMcpFailure — it's defined with a structured error class but leans on a free-form message string alongside a 13-value code discriminator, 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 check orchestratorMcp.ts for the sibling OrchestratorMcpService failure 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 the getCommandReceipt addition to OrchestratorV2Shape is just extending a pre-existing legacy interface, not introducing a new violation, and the optional replayed field 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 layer and PendingRequestMcpService as 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 bare layer identifier 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. The errorMessage helper and stablePart function look consistent with existing conventions and prior review comments, so I'm confirming those concerns are already resolved. Also checking the earlier flag on isMissingChild/projectionFailure — those now use a properly typed ThreadManagementError with 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 layer import instead of the namespaced form like PendingRequestMcpService.layer that 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 new failure() 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 the failure helper 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 layer named 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.