Repository navigation
Effect Service Conventions: 1 issue found
1 finding
apps/server/src/provider/acp/XAiAcpExtension.ts(lines 328, 330): the newisGrokPlanMarkdownPathhelper readsprocess.platformfrom the module global instead of the injectedHostProcessPlatformreference. The repo enforces this as an error (t3code/no-global-process-runtimeinvite.config.ts), and these are the only unsuppressed occurrences in the tree. The neighbouringgrokPlanSessionPrefixes()similarly readsprocess.env.HOME/USERPROFILE/GROK_HOMEdirectly, whileUsageServicein this same PR correctly resolvesGROK_HOMEthroughHostProcessEnvironment.
Suggested fix: resolve the platform/environment in the Effect caller (GrokAdapter) via yield* HostProcessPlatform / yield* HostProcessEnvironment (both are Context.References with defaults, so no extra layer is required) and pass them into the helpers. This also removes the need for the new test to mutate process.env.
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.
Scope reviewed: changed .ts/.tsx files under apps/**, packages/**, infra/**, plus directly affected call sites.
Checked and clean
- Imports: new Effect imports (
effect/Clock,effect/Duration,effect/Queue,effect/Option,effect/Result) use subpath namespace form; no consolidatedfrom "effect"imports were introduced. Named imports from@t3tools/contracts,@t3tools/shared/model,@t3tools/shared/shell, andeffect/unstable/processmatch the established repo-wide convention. - Service definitions: no new
Context.Servicewas added.AcpSessionRuntime's inline interface was extended (setSessionModel(modelId, meta)) without reintroducing a standalone shape type.GrokSkills.tsis a plain helper module (pure parser +Effect.fnprobe), not a service, somake/layernaming rules do not apply. - Dependency acquisition:
GrokDriveracquirescwdfromServerConfigin the environment and passes it as a plain value;UsageServiceacquiresHostProcessEnvironmentfrom the environment. NoManagedRuntime.make,runPromise, orrunPromiseExitwas introduced in domain/service code; the only newLayer.succeedis aChildProcessSpawnertest seam inGrokSkills.test.ts. - Errors: no new error classes were introduced.
settleXAiPromptCompletionuses the existingEffectAcpErrors.AcpRequestError(structuredcode+errorMessage) and itsinternalErrorstatic factory; the rate-limit failure originates from a protocol notification with no underlying error, so an absentcauseis correct. No newcatchTag/predicate-basedcatchIfrecovery of known tags. TheEffect.catch(() => Effect.void)on the watchdog fiber intentionally handles the whole channel. - File layout: no service module moves or compatibility shims; no obsolete
domain/Services+domain/Layerspairs left behind. - Change discipline: added tests cover new backend behavior (watchdog liveness, permission-option fallback, plan capture, Grok usage parsing) rather than proving a mechanical refactor.
🔍 Agent activity — 1 tool call
💭 I'm reviewing the diff for Effect service convention violations, checking the new GrokSkills.ts file and changes across the Grok adapter, provider, and runtime files. I'm looking at the imports in GrokSkills.ts to see how Effect, Option, Result, and the process modules are being used. I'm checking whether the named imports from
effect/unstable/processviolate the namespace import convention, and whether the environment parameter indiscoverGrokSkillsrepresents a hidden dependency similar to the existingcheckGrokProviderStatuspattern. I'm also scanning the test file's use ofChildProcessSpawnerand the XAiAcpExtension's error handling to see if they follow existing conventions in the repo. That import style matches the repo-wide standard, so that's fine. The default parameter referencing the module-level process.env mirrors what the sibling checkGrokProviderStatus function does, so I want to check how other skill discovery functions, like the Claude skills discovery one, handle this for consistency. I'm checking the GrokAdapter and XAiAcpExtension changes, noting they reuse an existing AcpRequestError class from effect-acp rather than defining a new tagged error, which seems acceptable since the rate limit error doesn't need to preserve an underlying cause. Now I'm looking at how UsageService imports its dependencies. I want to verify whether usingNodeOS.homedir()directly for the.grokconfig path matches how the claude and codex directories are resolved elsewhere in the codebase. I should check whether NodeOS is already imported in UsageService, since it's likely used elsewhere in the file. I notice a discrepancy between what I saw earlier and this grep result — the line I'm looking at now uses a different override mechanism than the grokHomeEnv logic I viewed before, so I need to reconcile which version is actually current in the file. That grep line was likely stale, so I'll trust the actual file view instead. Since this PR is feature work rather than a service refactor, I'm checking it against review conventions: there don't seem to be new service definitions since GrokSkills is just plain functions, and errors are handled via the existing AcpRequestError pattern rather than new error classes. Now I want to check the touched files for Layer.succeed, ManagedRuntime.make, and runPromise usage across GrokAdapter, GrokProvider, GrokDriver, GrokSkills, AcpRuntimeModel, AcpSessionRuntime, GrokAcpSupport, XAiAcpExtension, GrokTextGeneration, UsageService, and the usage/web/mobile files — let me grep for those patterns. Those consolidated imports aren't in any touched files, which is good. Now I'm checking whether the diff introduces actual convention violations, looking through GrokAdapter.ts and GrokProvider.ts to see if their factory functions and status checks follow existing patterns. The addedcwdparam flows cleanly from ServerConfig into checkGrokProviderStatus, which seems fine since it's just passing a configuration value. I'm also checking AcpSessionRuntime.ts, where a new optional meta field was added to the setSessionModel interface — that's a minor addition to an existing Context.Service and shouldn't be an issue. Now I'm looking at XAiAcpExtension.ts, where new helper functions read environment variables and platform info directly rather than going through the existing HostProcessEnvironment and HostProcessPlatform services used elsewhere in the codebase — this could be a violation of the convention against hiding dependencies in module-level globals or closures over singleton services. I'm weighing whether this is a real violation worth flagging, since these are plain helper functions rather than Effect services, and the review guidance says not to demand unrelated repo-wide cleanup or flag things outside the PR's changed scope. I want to check whether there's existing precedent in the repo for readingprocess.envdirectly outside of the HostProcessEnvironment service before deciding how to call this out. Since other non-test files already read process.env directly, this isn't an unusual violation worth flagging, especially since it's a pure helper rather than a service. I should focus on what's more likely the intended finding for this PR—checking Effect Service Conventions, I want to look at how the new error is constructed in the XAiAcpExtension file. Checking through the rest: the rate-limited error creation looks fine without a cause since there's no underlying failure, the static factory usage for internal errors follows conventions, and the watchdog's catch-all error handling seems appropriate since it's intentionally meant to prevent the fiber from crashing. I want to grep the touched files for catchTag, Schema.is, Schema.Defect, and TaggedError usage to be thorough. This PR doesn't introduce anything new around errors, so I'm checking whether there's a genuine violation by scanning the GrokAdapter diff more closely, looking at the session runtime's model-setting interface and other provider-related pieces for anything problematic. Going through the remaining imports, they all look like allowed patterns: named imports for pure helpers from shared subpaths, namespace imports for effect modules, and contract types pulled in explicitly. The one thing that catches my eye is UsageService importing HostProcessEnvironment as a named import rather than a namespace import, which seems like it might deserve a closer look since it's a service tag. The named import pattern seems established. I'm noticing there's an oxlint rule against global process runtime access, which could flag process.env reads like the one in XAiAcpExtension—worth checking if that rule relates to hiding dependencies in module globals, even though it's outside the scope of the Effect service convention check. I notice the new code in XAiAcpExtension.ts checksprocess.platformdirectly twice to handle case-insensitive comparisons on Windows, which directly violates the repo's own lint rule banning raw platform checks in favor of the HostProcessPlatform service. This is a concrete introduced violation within scope. I should verify the actual head file content for those lines to confirm. I've confirmed process.platform is used directly in production server code, which should be banned by the repo's lint rule favoring HostProcessPlatform injection. That's odd since CI should catch this, so I want to check whether the file is excluded in the oxlint config and scan for other non-test source files using process.platform directly. I've confirmed thatt3code/no-global-process-runtimeis an error-level rule, and the only unsuppressed violations in the repo are the two new lines in XAiAcpExtension.ts from this PR—the runtime platform needs to come fromHostProcessPlatformrather than the module global. I also noticeisGrokPlanMarkdownPathis a plain function rather than Effect-based, which affects how I need to fix this. Properly fixing this requires threading the platform through, since the callerextractGrokPlanMarkdownFromToolCallDatais invoked from GrokAdapter in an Effect context—I'll suggest accepting platform as a parameter or reading it fromHostProcessPlatformin the Effect caller, flagged as a comment rather than an inline suggestion since it spans multiple hunks/files. I'm also noticinggrokPlanSessionPrefixes()readsprocess.envdirectly while UsageService in this same PR correctly usesHostProcessEnvironmentfor GROK_HOME—an inconsistency within the PR itself that reinforces the same underlying issue, even though the lint rule itself only covers platform/arch, not env vars. I'll fold this into the same comment as a secondary point alongside the primary platform finding. Let me check a few other things: the mutable closure forsessionAllowAllin GrokAdapter.ts looks like a behavior concern rather than a convention issue, themetatype change inAcpSessionRuntimeusingEffectAcpSchema.SetSessionModelRequest["_meta"]looks fine, andrecordTurnActivity's use ofEffect.fnwith try/finally around yields seems fine too. I want to verify whetherdiscoverGrokSkills'sEffect.fn.Returntyping correctly declares its error and requirement types, sinceresolveSpawnCommandmight need more context than justChildProcessSpawner—I should check its signature to be sure. I'm noting thatresolveSpawnCommandrelies onHostProcessPlatform, a Context.Reference with a default value, so it can be accessed viayield*anywhere without needing to provide it explicitly since references with defaults don't add to the requirements type. This points toward how to fix the XAiAcp issue. For extendingisGrokPlanMarkdownPath, I'm considering either passing platform/env as parameters or converting it to an Effect that pulls fromHostProcessPlatform. SinceextractGrokPlanMarkdownFromToolCallDatais already called within an Effect.gen block in GrokAdapter, making it Effect-based seems feasible but would touch multiple places, so I'll flag it with a no-diff comment instead. I want to check hostProcess.ts to confirm HostProcessPlatform is indeed set up as a Reference. There's anisHostWindowshelper confirming this pattern. My main finding is a concrete violation: directprocess.platformreads in XAiAcpExtension.ts bypass the repo's injectedHostProcessPlatformconvention, which the lint rule enforces as an error. I'm also considering whether to flag the similarprocess.env.HOME/USERPROFILE/GROK_HOMEusage ingrokPlanSessionPrefixes()since it falls under the same convention family. I'm weighing whether to combine these into one inline comment or split them — since they're in neighboring code and share the same fix (threadingHostProcessPlatform/HostProcessEnvironmentfrom the caller), I'll anchor a single comment at the platform lines and mention the env reads there too, to avoid noise from duplicate comments. I just need to confirm these lines are actually part of the diff so the inline comment position is valid. This is a clear violation of the repo's rule against hiding runtime dependencies in module globals within Effect code, so I'm setting the check result to failure and writing up the single inline comment before posting the review.
1. modify_pr — One convention issue found: new host-runtime reads in apps/server/src/provider/acp/XAiAcpExtension.ts bypass the injected HostProcess* references that this repo requires in Effect code.
Agent Credits: 239 credits