Repository navigation
Effect Service Conventions: 1 issue found
apps/server/src/skills/SkillInventory.test.ts:14—import { layerTest as serverSettingsLayerTest } from "../serverSettings.ts"aliases a service module export and erases the module namespace. Import the module as a namespace (import * as ServerSettings from "../serverSettings.ts") and callServerSettings.layerTest(...), as the other server tests do.
No other convention violations found in the changed scope.
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 reviewed in scope:
apps/server/src/skills/SkillInventory.ts— namespacedeffect/*subpath imports; dependencies (FileSystem,Path,ServerSettingsService) acquired from the environment viayield*and reflected in the declaredEffect.fn.Returnrequirements; no service instances passed as parameters, noManagedRuntime/runPromise, no module-global state.apps/server/src/skills/http.ts— thinHttpApiBuilder.grouphandler delegating to the discovery effect; no hidden runtime or dependency injection.apps/server/src/server.ts— layer wiring only.packages/contracts/src/skillInventory.ts,packages/contracts/src/environmentHttp.ts,packages/contracts/src/index.ts— schema-only additions; no new error classes, so the error/predicate conventions do not apply.packages/client-runtime/src/state/skillInventoryHttp.ts— mirrors the existingthreadSnapshotHttp.ts/shellSnapshotHttp.tspattern, resolves the optional signer viaEffect.serviceOption, no runtime boundary misuse.apps/web/src/components/settings/SkillsSettings.tsxandSkillsSettings.logic.ts—runtime.runPromiseis used only inside a React effect (a legitimate application boundary); logic module is pure.apps/web/src/routes/settings.skills.tsx,routeTree.gen.ts,SettingsSidebarNav.tsx— routing/nav only.
🔍 Agent activity — 1 tool call
💭 Looking at the changed files across the Effect service setup, I'm checking whether SkillInventory.ts follows the conventions—it uses namespace imports and is structured as a plain Effect function rather than a service, which seems acceptable based on the original plan. I'm also verifying the application boundaries, like the web component's use of
runtime.runPromisein React, which is fine. I notice some patterns likeEffect.orDieon getSettings that hide errors, though that's not explicitly listed as a convention violation. I need to examine the actual repository to confirm whether ServerSettingsService exists as a Context.Service and whether serverSettings exportslayerTest, then trace through thediscoverClaudeSkillscall signature to make sure it's being used correctly. I need to verify that ServerSettingsService is a proper Context.Service and check how it's being used as a type in the Effect.fn.Return requirements, then look at the serverSettings.ts file to see the service definition and layer test. I'm noticing the test file uses a renamed import of the layer export, which violates the convention about erasing module namespaces at service boundaries. The guideline suggests importing the local service module as a namespace instead, though the convention seems to be cut off mid-explanation about how this should apply in test files. I'm noticing the test file is using a named import with an alias forlayerTest, which directly contradicts the repo's established pattern of importing the entire module and accessing it through the namespace. This is exactly the kind of anti-pattern the linting rules are meant to catch, and it's happening in the changed code itself. Looking at the other potential issues:SkillInventory.tsis just a collection of helper functions rather than a proper Context.Service, which technically doesn't match the architectural intent described in the plan, but flagging it as a violation feels like overreach since the check is meant to catch service construction patterns, not force architectural redesigns. TheEffect.orDieusage and client-runtime imports appear fine. The web component is callingruntime.runPromise, which I should verify against the conventions. Checking the error handling in the UI whereerrorMessage(cause)extractscause.message— that's a UI concern, not an error class issue, so it doesn't directly violate the convention about deriving wrapper messages from structural attributes. The skills HTTP layer usesEnvironmentOrchestrationSnapshotErrorsas an error channel but the handler never actually fails, which is acceptable. I need to verify the naming convention for the HTTP layer against other similar layers in the repo and confirm the imports and environment setup are correct. I'm noticing that HttpApiBuilder.group accepts handlers directly without needing Effect.succeed, though wrapping them isn't technically a convention violation. Let me look at how other server HTTP group layers handle this to see what the established pattern is. The pattern difference betweenEffect.fnUntracedandEffect.succeedis minor stylistically and doesn't warrant flagging. The more significant issue is the aliased import in the test—the ServerSettings service module'slayerTestis imported with a rename that obscures the namespace, which could be a service consumer boundary concern. Looking at the broader codebase, most tests useimport * as ServerSettings from "../serverSettings.ts", which clearly violates the stated rule. SkillInventory.ts imports{ ServerSettingsService }directly without an alias, and while that's a mild deviation from the strict rule requiring namespace imports at service boundaries, it's widespread legacy code. Given the guidance to avoid demanding unrelated repository-wide cleanup, I'll focus on the explicit alias violation rather than the named import pattern. I should also verify whetherderiveProviderInstanceConfigMapis exported and check the service requirement type. Now I'm examining how other endpoints handle settings-read failures — specifically whether the repo commonly usesEffect.orDieto convert typed errors into defects, since the current endpoint declareserror: EnvironmentOrchestrationSnapshotErrorsbutdiscoverGlobalSkillInventoryusesEffect.orDieon settings failure, which would hide that typed error. I need to check what error type getSettings returns to see if the orDie call is actually necessary, so I'm looking at the serverSettings.ts file around the make/getSettings definition. I'm wondering whether usingorDieto convert the structuredServerSettingsErrorinto a defect violates the Effect service conventions, since it would cause the HTTP endpoint to return an unstructured 500 instead of the declared error. The instructions focus on defining errors rather than prohibiting specific error handling patterns, so there's no explicit rule against it—I'll skip flagging this as a violation and move on to checking the client side. Now I'm looking at the import ofManagedRelayDpopSignerin the skillInventoryHttp file to see how this service tag is being used elsewhere in the codebase. The new client-runtime file follows the same pattern as its sibling files, which is fine. Looking at SkillsSettings.tsx, there are some issues but nothing related to Effect-service conventions—though one thing stands out:SkillHarnessGroupsreturns an array from a component, which React allows in version 18+, so that's not a concern for us. The main issue I'm finding is with an aliased import that's been cut off. I'm looking at an import alias likeimport { layer as serverSettingsLayerTest }that's erasing the module namespace. The convention explicitly flags this pattern—at service boundaries, we should import the local service module as a namespace and use its public shape. This is a concrete violation of that rule, even though it's in a test file. The check defaults to failure when there are no findings, but since I have a real violation here, I need to decide whether to report it and mark the check as failed or weigh whether this minor issue warrants that outcome. Let me scan for other significant violations. The missing Context.Service forSkillInventoryServiceisn't actually required by the conventions—other server code uses free functions likediscoverClaudeSkillssimilarly. The React component importingruntimeand callingruntime.runPromisein an effect is fine at the application boundary. The contracts file doesn't need a service. And importing a pure helper function with a named import from a Layers module is allowed. So the alias issue is the main finding, and given the check's default-to-failure stance with findings, I should report it as a failure. I'm weighing whether this import style violation in the test file warrants a failure or neutral status. The convention is explicitly stated and applies to tests too, based on how other tests in the repo are structured. Given that the instructions say violations may fail the check, I'll mark it as a failure with a precise comment about the namespace import pattern.
1. modify_pr — Effect service conventions review of the new skills service, HTTP layer, contracts, and client-runtime helper. One finding: an aliased service-module import in the new server test. Everything else (namespaced effect/* subpath imports, environment-based dependency acquisition via yield* ServerSettingsService, runPromise confined to the React boundary, schema-only contracts) matches the conventions.
Agent Credits: 102 credits