Skip to content

fix(provider): resolve skills and slash commands against the workspac…

MacroscopeApp / Macroscope - Effect Service Conventions failed Aug 22, 2026 in 2m 52s

Effect Service Conventions: 2 findings

Two change-discipline findings on the new workspace-scoped provider capability surface.

  • apps/server/src/ws.ts — the new providers.workspaceSkills RPC handler introduces backend behavior (worktree-vs-project root resolution, unknown-project error, unknown-thread tolerance, fan-out to the two new registry methods) with no focused tests; only existing registry mocks were extended.
  • apps/server/src/provider/Drivers/ClaudeDriver.ts — removing the makeClaudeCapabilitiesCacheKey import leaves that helper in ClaudeHome.ts with no production caller (only ClaudeHome.test.ts still references it); it should be deleted with the cache-key change.

No Effect service-structure violations were found: namespace/named import usage, Effect.fn service methods, dependency acquisition inside the driver scope (FileSystem.FileSystem, Path.Path), reuse of the existing OrchestrationGetSnapshotError with cause preserved at the RPC boundary, and the new atom family taking the shared connectionAtomRuntime all match the conventions.

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 beyond the diff: apps/server/src/provider/Drivers/ClaudeSkills.ts, apps/server/src/provider/Drivers/ClaudeHome.ts, apps/server/src/provider/Layers/ProviderRegistry.ts, apps/server/src/provider/Services/ProviderRegistry.ts, apps/server/src/server.test.ts, apps/web/src/state/projects.ts, packages/contracts/src/orchestration.ts.

Checks performed and cleared:

  • No consolidated from "effect" imports in touched code; Effect modules imported from subpaths as namespaces.
  • New driver methods acquire FileSystem/Path from the instance's Effect scope (yield* FileSystem.FileSystem) and provide them into the sub-effect; no service instances are passed as constructor parameters, no ManagedRuntime.make, runPromise, or runPromiseExit introduced, and no new Layer.succeed hiding runtime-backed APIs.
  • No per-feature Atom runtime created: createProviderSkillsEnvironmentAtoms receives the application-owned connectionAtomRuntime, matching state/projects.ts.
  • Error handling at the new RPC reuses the declared OrchestrationGetSnapshotError from the RPC's error union, keeps cause, and derives its message from input identifiers rather than stringifying the cause; no new redundant discriminator fields or error-construction helper wrappers were added.
  • Effect.orElseSucceed uses in the driver and handler intentionally handle the whole error channel (documented degrade-to-snapshot behavior), which is permitted rather than a catchTag/catchIf misuse.
  • The pre-existing ProviderRegistryShape interface and the Services//Layers/ split were not flagged: they are legacy structure the PR only extends, and demanding that refactor here would be unrelated repository-wide cleanup.

🔍 Agent activity — 17 tool calls

💭 I'm reviewing the changed files against conventions—checking that the new provider skills state files use atom families correctly, verifying the contracts schema imports, and examining the provider driver, registry shape, and layer structure in the server package. Since ProviderRegistryShape is a pre-existing interface just being extended with methods rather than created fresh, flagging it for the "inline Context.Service declaration" rule feels like unrelated legacy cleanup rather than something this PR introduced—same logic applies to the existing split between Services/ and Layers/ modules. I want to actually open these files to verify imports and error definitions, including checking how ws.ts constructs its OrchestrationGetSnapshotError. I'm checking whether OrchestrationGetSnapshotError already stores a structured message attribute or just an unstructured string, and whether this usage matches existing patterns elsewhere in the file rather than introducing a new violation. I'm also noting that Effect.orElseSucceed(() => null) silently swallows thread-lookup errors, though that isn't an explicit convention violation, and that ClaudeDriver provides FileSystem and Path service instances via closures captured from discoverClaudeSkills, which could run against the rule against hiding dependencies in module globals or closures.

1. browse_code — apps/server/src/provider/Drivers/ClaudeDriver.ts

2. browse_code — apps/server/src/provider/Services/ProviderRegistry.ts

💭 I'm weighing whether the pre-existing ProviderRegistryShape pattern counts as legacy structure the PR is just extending, versus something a strict reviewer would flag for adding new members inconsistent with convention—since the guidance targets PRs that create, move, refactor, or consume an Effect service, and this one does consume and extend the registry. I'm now scanning other files for consistency: checking whether ClaudeSkills.ts is new or pre-existing, verifying discoverClaudeSkills' dependency signature, looking at the new ws.ts handler against similar existing handlers like OrchestrationGetSnapshotError, and noting the error-swallowing pattern in getThreadShellById. I'm also checking the RPC import style in contracts/src/rpc.ts to confirm named schema imports match established conventions. I'm reviewing ProviderRegistry.ts's new functions and their use of Effect.fn and Ref.get, then checking the caching in ClaudeDriver and the orElseSucceed pattern in discoverSlashCommandsForCwd, which intentionally handles the whole error channel much like a catch-all is appropriate elsewhere. I'm also verifying ProviderInstance's interface shape and the client-runtime imports in providerSkills.ts, then checking whether discoverClaudeSkills' return type matches the no-error effect signature declared for ProviderInstance. Now I want to see if Effect is imported anywhere unused in the new client-runtime file, and compare other atom families like state/projects.ts for consistency before opening ClaudeSkills.ts itself.

3. browse_code — apps/server/src/provider/Drivers/ClaudeSkills*.ts

4. git_tools — OrchestrationGetSnapshotError

💭 OrchestrationGetSnapshotError already exists with a message field, so reusing it stays consistent with the repo's conventions. I want to check ClaudeSkills.ts to confirm the driver method's declared error-free effect actually matches this usage.

5. browse_code — apps/server/src/provider/Drivers/ClaudeSkills.ts

6. browse_code — apps/server/src/provider/Layers/ProviderRegistry.ts

💭 This looks consistent with the existing style. Now I want to check the ws.ts handler and its imports, and see whether CodexDriver also needs skills support, though that's not strictly required. Let me look at the ws.ts region for the new handler and its surrounding conventions.

7. git_tools — providersWorkspaceSkills

8. browse_code — apps/server/src/ws.ts

💭 This aligns with the existing ws.ts patterns already in place. I'm now checking whether this PR needs focused tests since it changes backend behavior—new RPC handler, new driver methods, and a cache keying change—but the diff only touches test mocks without adding actual test coverage, which is worth flagging given the convention that backend behavior changes require focused tests. Looking closer, there's an existing test file covering skill discovery but nothing testing the new per-cwd wiring, so a missing-tests finding is plausible though harder to pin to a specific line. I'm weighing whether that's a strong enough finding versus checking other candidates, like how ChatView passes computed slash commands and skills down to ChatComposer—that flow looks fine since it's standard React prop passing, not an effects issue. I'm also checking the new contracts type and the client-runtime atom family module, confirming it reuses the shared connection runtime rather than spinning up a separate one, consistent with other state modules like projects.ts. Now I want to make sure every place that constructs a ProviderRegistry mock object has been updated to match the new shape, so I'm searching for other occurrences of the maintenance capabilities function to see if any test utilities were missed.

9. git_tools — getProviderMaintenanceCapabilitiesForInstance:

10. browse_code — apps/web/src/state/projects.ts

💭 I'm checking server.test.ts around line 636 to see if it builds a full ProviderRegistryShape object literal that would now fail type checking with the new fields, or if it's just a partial cast that's unaffected.

11. browse_code — apps/server/src/server.test.ts

💭 Layer.mock accepting partial input is expected mock behavior, not a violation. I'm now weighing whether the lack of focused tests for the new RPC handler, registry methods, driver methods, and cache changes counts as a real finding under the "backend behavior changes require tests" convention, since that guidance explicitly calls for test coverage using test implementations. I also want to check whether makeClaudeCapabilitiesCacheKey is still referenced anywhere after being removed from ClaudeDriver's imports — if it's now dead code, that mirrors the "don't leave compatibility shims" principle and should be flagged.

12. git_tools — makeClaudeCapabilitiesCacheKey

💭 I notice makeClaudeCapabilitiesCacheKey is now dead code, only referenced by its own test since the PR made it unused elsewhere. It's a legitimate cleanup nit, but I'm weighing whether leaving an orphaned helper plus its tests really counts as a clear convention violation versus just something worth flagging since it falls within the changed file's scope.

13. browse_code — apps/server/src/provider/Drivers/ClaudeHome.ts

💭 The orphaned helper is a minor dead-code issue from the refactor, but it's not tied to the specific conventions listed, so I'm leaning toward not failing the check on it—maybe a soft note at most. I want to focus more seriously on whether the missing-tests convention actually applies here, since backend behavior changes matter more. Given the new RPC handler, registry methods, and driver cwd cache all changed without new tests, and the guidance explicitly says to require focused tests when backend behavior changes, this feels like a legitimate finding worth enforcing rather than a mechanical refactor exception. Let me double-check the file list via the API to confirm there really aren't tests covering this elsewhere in the diff.

14. github_api_read_only — repos/{owner}/{repo}/pulls/{pull_number}/files?per_page=100

💭 There's no new test coverage for the new backend behavior. I'm weighing whether the ProviderRegistryShape interface and the Services/Layers file layout violate current conventions, but since these reflect pre-existing legacy structure rather than something introduced by this change, I don't think they should be flagged as new findings. The clearest issue is the missing focused tests for the backend behavior change — the new RPC handler with its resolution logic, the new registry methods, and the cwd-keyed cache are all untested beyond mock updates. I want to check whether server.test.ts already tests similar RPC methods through providerRegistry, and whether ProviderRegistry.test.ts covers the discoverSkillsForInstance fallback, to see how straightforward adding a test here would actually be.

15. browse_code — apps/server/src/provider/**/ProviderRegistry.test.ts

16. git_tools — WS_METHODS.(filesystemBrowse|projectsReadFile|serverRefreshProviders)

💭 Given the existing pattern of focused tests in server.test.ts and ProviderRegistry.test.ts, the new RPC and registry methods lacking tests is a legitimate convention violation, and since the check defaults to fail on clear violations, I'm leaning toward flagging this as a failing finding. I'll post an inline comment on the ws.ts handler noting the missing test coverage for the new RPC and fallback behavior, along with a suggested fix. I'm also considering a secondary note about the now-orphaned makeClaudeCapabilitiesCacheKey helper in ClaudeHome.ts, which is only used by its own test file now that its real usage was removed — I can attach that comment to the nearby import line in the diff since that file itself isn't touched. I'm now deciding between failing with two findings or treating one as just a suggestion. Since the customer's conventions explicitly require focused tests when backend behavior changes, I'll set the review state to failure with the missing-tests issue as the primary finding, and the dead helper as a secondary, minor note. I need to pinpoint exact diff line numbers for both comments before writing them out. For the first comment, I want to flag that the new workspace-root resolution logic and registry discovery calls lack a focused test, suggesting a case using the existing provider registry mock seam plus a fallback test for the empty-array case. For the second, I'll note that a cache-key helper is now unused outside its own test and should be deleted along with that test. Then I'll finalize the review as a failure.

17. modify_pr — Reviewed the new provider capability service surface (ProviderInstance.discoverSkillsForCwd / discoverSlashCommandsForCwd, ProviderRegistry.discoverSkillsForInstance / discoverSlashCommandsForInstance, the providers.workspaceSkills RPC and the client atom family) against the Effect service conventions. Imports, Effect.fn usage, dependency acquisition (yield* FileSystem.FileSystem / Path.Path inside the driver scope), error modelling at the RPC boundary and the atom family reusing the shared connectionAtomRuntime all look consistent with the existing patterns — no service-injection, hidden-runtime, or error-shape violations found. Two findings on change discipline, noted inline.


Agent Credits: 120 credits