Repository navigation
Effect Service Conventions: 1 minor finding
One minor error-modeling finding; the rest of the new Effect service code follows the conventions.
apps/server/src/provider/Layers/OmpAdapter.ts(lines 453, 822): wrapper errors setdetail: cause.message, andProviderAdapterProcessError/ProviderAdapterRequestErrorderivemessagefromdetail, so the wrapper message is built from the cause instead of stable structural attributes. Suggested keeping the failure only ascauseand using the available structural context (attachment id / process step), whichOmpTextGeneration.tsalready does for the same attachment read.
The previously flagged Effect.catchTag usage in apps/server/src/textGeneration/AcpTextGeneration.ts is now Effect.catchTags({ SchemaError: ... }) and is resolved.
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/provider/Drivers/OmpDriver.ts, apps/server/src/provider/Layers/OmpAdapter.ts, apps/server/src/provider/Layers/OmpProvider.ts, apps/server/src/provider/Services/OmpAdapter.ts, apps/server/src/provider/acp/OmpAcpSupport.ts, apps/server/src/provider/acp/AcpSessionRuntime.ts, apps/server/src/provider/acp/AcpRuntimeModel.ts, apps/server/src/provider/Layers/ProviderRegistry.ts, apps/server/src/orchestration/Layers/ProviderCommandReactor.ts, apps/server/src/textGeneration/AcpTextGeneration.ts, apps/server/src/textGeneration/OmpTextGeneration.ts, apps/server/src/textGeneration/{Cursor,Grok}TextGeneration.ts, apps/server/src/serverSettings.ts, packages/client-runtime/src/providerCapabilities.ts, plus the touched web/mobile call sites.
Checks performed and found clean:
- Imports: all new server modules use subpath namespace imports (
import * as Effect from "effect/Effect", etc.); no consolidatedfrom "effect"imports were introduced.OmpAcpSupport.tsusesimport * as AcpSessionRuntimeandOmpAdapter.tsusesimport type * as AcpSessionRuntime, matching the Cursor/Grok siblings. - Service definition/layout:
OmpDriverfollows the existing driver shape (driverKind,configSchema,defaultConfig,create) and is registered inBUILT_IN_DRIVERS;Services/OmpAdapter.tsmirrors the existing per-instance adapter shape anchors (GrokAdapterShape,CursorAdapterShape) rather than aContext.Service, so the inline-interface rule does not apply. No compatibility re-export shims were added. - Dependency acquisition:
makeOmpAdapter,makeOmpTextGeneration, andOmpDriver.createall acquireChildProcessSpawner,FileSystem,Path,Crypto,ServerConfig,ServerSettingsService,HttpClient, andScopefrom the Effect environment.Layer.succeed(ChildProcessSpawner, input.childProcessSpawner)insidemakeOmpAcpRuntimeis the pre-existing ACP runtime seam shared withGrokAcpSupport/CursorAcpSupport, not new fake injection. NoManagedRuntime.make,runPromise, orrunPromiseExitwas introduced in the new service code. - Errors/predicates: failures use existing
Schema.TaggedErrorClasstypes with structured fields and preservecause; recovery usesEffect.catchTags/Effect.catch(whole-channel), with nocatchTagor predicate-basedcatchIffor known tags; no single-use(...) => new SomeError(...)alias helpers were added. - Behavior changes (interaction-mode normalization, OMP snapshot/model discovery, ACP usage updates, maintenance precedence) are covered by focused tests in
ProviderCommandReactor.test.ts,OmpProvider.test.ts,OmpAdapter.test.ts,OmpAcpSupport.test.ts,providerMaintenance.test.ts, andproviderCapabilities.test.ts.
🔍 Agent activity — 16 tool calls
💭 It looks like the previously flagged
catchTagissue in AcpTextGeneration.ts was already resolved—the diff shows it's usingEffect.catchTagswith a SchemaError handler now. I'm going through the other key files touched, like OmpDriver.ts, OmpAdapter.ts, OmpProvider.ts, and OmpAcpSupport.ts, to check they follow Effect conventions. I noticeServices/OmpAdapter.tsstill exports a standaloneOmpAdapterShapeinterface extendingProviderAdapterShape, which conflicts with the convention against retaining separateFooShapeinterfaces outside aContext.Servicedeclaration—but sincemakeOmpAdapterjust returns a plain object rather than defining an actual Effect service, and this mirrors existing adapters like CursorAdapter and GrokAdapter, I want to confirm whether that pattern is already established elsewhere in the repo before flagging it. I should also check how OmpAdapter.test.ts sets up its test tags, since it seems to follow the same test harness conventions used for other adapters. I'm also noticing an error-wrapping issue in OmpDriver.ts, where the message is built directly fromcause.message, which explicitly violates the rule against deriving a wrapper's message from the underlying cause rather than from stable structural fields—I want to check whether OpenCodeDriver or GrokDriver do the same thing to see if this is a pre-existing pattern being copied forward or a new violation. I should also check whether ProviderAdapterProcessError and ProviderAdapterRequestError in OmpAdapter similarly embedcause.messageintodetail, and compare against the logging pattern that usesCause.pretty(cause)to see if raw defect text is being logged elsewhere in the codebase as a baseline convention. ThemakeOmpAcpRuntimeWithSpawnfunction passes aChildProcessSpawner["Service"]instance directly, which raises the same flag about accepting service instances rather than layers, but I want to verify this mirrors existing Cursor/Grok ACP runtime patterns before treating it as a real issue.
1. browse_code — apps/server/src/provider/acp/*.ts
2. browse_code — apps/server/src/provider/Services/*.ts
💭 Other adapters like GrokAdapter follow the same shape pattern, so this looks consistent with the repo's baseline convention rather than a new violation worth flagging. The rule about not retaining standalone shape interfaces seems targeted at Context.Service definitions, and these adapters aren't Context.Service in production since they're created per instance—let me check GrokAdapter's Services file to confirm.
3. browse_code — apps/server/src/provider/Services/GrokAdapter.ts
4. browse_code — apps/server/src/provider/acp/GrokAcpSupport.ts
💭 The baseline patterns line up with OmpAcpSupport, so those look fine. Now I want to check how existing drivers handle errors using the
detail: cause.messagepattern.
5. git_tools — detail: `Failed to build
6. git_tools — detail: cause.message
💭 These patterns are consistent across five sibling implementations already in the repo, so flagging them here would mean demanding unrelated cleanup on a new provider that's just mirroring existing conventions. Given the instruction to only report concrete violations introduced within the changed scope and not fail for legacy patterns, I'm leaning toward not flagging this since it matches the established sibling pattern exactly. There's some ambiguity about the output format—an instruction mentions responding "All clear" if no findings, but that conflicts with the required JSON schema, so I'll stick with the schema and mark state as success if I don't find real violations. Now let me dig into the new AcpTextGeneration.ts file itself to check for actual convention issues.
7. browse_code — apps/server/src/textGeneration/AcpTextGeneration.ts
💭 I'm noting that the named type import of the service tag from AcpSessionRuntime should follow the convention of importing service modules as namespaces at boundaries, while keeping named imports only for pure helpers or error types. Since it's used purely as a type reference here, I lean toward treating this as a low-value nit rather than a real violation, and want to grep other files to see how they consistently handle this import.
8. git_tools — AcpSessionRuntime.ts";
💭 I notice AcpTextGeneration.ts is the only file using named imports from that service module, since it only needs the service tag type and a result type—purely type-level usage. That's a minor convention deviation worth weighing whether it needs a comment, since the convention generally allows named imports for pure helper or type-only cases. I'll set this aside as marginal and instead focus on reviewing OmpAdapter.ts more thoroughly for substantive issues around runtime setup, layer construction, and error modeling. Checking that dependency acquisition and error construction in the config/service resolution match the existing Grok/Cursor adapter patterns—they do, so nothing new to flag there. I'm now scanning OmpProvider.ts and ProviderCommandReactor.ts for similar consistency, and confirming OmpDriver.ts uses namespace imports consistently with the rest of the codebase.
9. git_tools — from "effect"
10. browse_code — apps/server/src/provider/Layers/OmpAdapter.ts
💭 The sibling adapters look consistent, so I move to checking the mobile/web changed files for Effect service issues — those are React and the new client-runtime package is just pure functions, so nothing to flag there. I check ProviderAdapterProcessError to see whether
detailis required in the message, then verify the OmpAdapter finalizer's use of Effect.catch is appropriate since it fully handles the error channel. I also want to look forcatchIforcatchTagusage in the new files.
11. git_tools — catchTag(|catchIf(|ManagedRuntime|runPromise
12. browse_code — apps/server/src/provider/Errors.ts
💭 I'm noting that while this new code technically matches the forbidden pattern of copying
cause.messageinto adetailfield, this is a pre-existing convention used throughout the codebase's error classes. Flagging it here would just be holding this instance to a stricter standard than its legacy siblings, so I'm leaning toward treating it as an accepted existing pattern rather than a new issue worth reporting. Actually, looking more closely at OmpAdapter, there are two spots doing this — one for ACP runtime creation failures, and one for attachment read failures duringsession/prompt. The attachment case stands out because a sibling file, OmpTextGeneration.ts, handles the identical failure correctly by using structured context (the attachment id) instead of copying the raw error message, and even nearby code in the same function uses a structural detail for invalid attachment ids. That inconsistency within the same PR feels like a legitimate, narrow finding: the adapter'ssendTurnshould follow the sibling's approach rather than copyingcause.message. I want to check CursorAdapter's equivalent code to confirm what the intended baseline behavior actually is.
13. browse_code — apps/server/src/provider/Layers/CursorAdapter.ts
💭 OmpAdapter matches CursorAdapter exactly, mirroring the pattern used across five other siblings in the codebase. Flagging this feels like noise since it's just consistent with established repo conventions, and the instructions favor treating pattern parity as acceptable rather than a defect worth calling out. Weighing candidates, the strongest one is the
detail: cause.messageusage in OmpAdapter, since the same PR handles it correctly elsewhere in OmpTextGeneration and the convention explicitly forbids this pattern — that's a defensible, in-scope finding. A weaker alternative would be the named import style in AcpTextGeneration.ts diverging from the namespace-import convention followed by every other consumer, though it's a much more minor concern. I want to check whether I'm overlooking something more substantive in the AcpSessionRuntime changes — specifically whether thesessionConfigOptionsFromSetuphelper was left behind unused after the diff replaced its usage with a conditional check onsessionSetupResult.configOptions. Worth confirming if that function is now dead code.
14. git_tools — sessionConfigOptionsFromSetup
💭 I'm verifying that
Effect.fnUntracedin ProviderCommandReactor follows existing conventions, and checking thatnormalizeThreadInteractionModejust dispatches a command rather than defining new behavior. I also confirmproviderCapabilities.tsis pure with no Effect usage, and note that the mobile project-actions file importsuseServerConfigs. Now I'm weighing whether to flag the pattern in OmpAdapter.ts wheredetail: cause.messageis copied directly into a wrapper message — this violates the stated convention against redundant detail fields, occurs twice in a new file within changed scope, and is contradicted by the correct approach shown elsewhere in the same PR (OmpTextGeneration.ts), making it a solid, actionable finding. I'll post a concise inline comment covering the attachment read error and mention the second occurrence in the process error, but first I need to locate the exact line numbers in the new file to anchor the diff comments correctly.
15. git_tools — detail: cause.message
💭 I'm planning to add an inline suggestion at line 822, refining the error detail message for the failed attachment read to be more structural and self-contained, while also noting line 453 as a related spot. I'm checking the indentation matches the surrounding code block. I'll skip flagging the AcpTextGeneration named import since it's low value and only type-consumed. On severity, I'm weighing whether this convention violation should trigger a failure or just a neutral note — it's an explicit error-modeling rule, but the same pattern shows up across other adapters like Cursor, Grok, and Codex, which makes it feel more like established repo-wide practice than a true violation, so I'm leaning toward not failing the check outright. Given the finding is minor and consistent with existing sibling adapters, I'll mark this as neutral rather than a failure, and I'll go ahead and post the comment since staying silent would mean falsely claiming "all clear" when there's a legitimate convention hit worth noting. Now let me draft that comment.
16. modify_pr — Reviewed the new Oh My Pi Effect service code (OmpDriver, OmpAdapter, OmpProvider, OmpAcpSupport, OmpTextGeneration, the shared AcpTextGeneration helper, and the AcpSessionRuntime/ProviderCommandReactor changes) against the Effect service conventions. Dependency acquisition, layer/make shape, catchTags usage, and namespace imports all look consistent; one minor error-modeling note below.
Agent Credits: 229 credits