Skip to content

fix(omp): keep active work timeline consistent

MacroscopeApp / Macroscope - Effect Service Conventions failed Aug 25, 2026 in 4m 29s

Effect Service Conventions: 4 issues found

Reviewed the Effect service modules introduced by this branch. Four convention violations found in new service code (inline comments could not be attached because of a GitHub error, so they are listed here; the review body was posted).

  • apps/server/src/mcp/PreviewMidsceneService.ts (L211-229): standalone PreviewMidsceneServiceShape interface retained instead of defining the service interface inline in the Context.Service declaration and referring to it as PreviewMidsceneService["Service"].
  • apps/server/src/mcp/PreviewMidsceneService.ts (L457-463): production make reads process.env directly, hiding an ambient dependency from make/layer; acquire it from the environment (HostProcessEnvironment) instead.
  • apps/server/src/provider/pi/PiRpcClient.ts (L20-57): PiRpcClientError stores an unstructured detail string as its only data with a free-form operation and no message getter (raw RPC error text is copied into detail), and clientError is a helper whose only behavior is new PiRpcClientError({ ... }). Model operation as a literal union with stable structural fields, derive message from them, keep the underlying value only as cause, and construct the error at the failure boundary.
  • apps/server/src/bundledSkills.ts (L57-74): registerBundledSkillsExtraRoot self-provides NodePath.layer, hiding the Path requirement from callers and preventing test substitution; and it uses Effect.catch with a Schema.is predicate to recover a single known tag, where Effect.catchTags({ CodexAppServerRequestError: ... }) is the intended form.

No findings for apps/server/src/mcp/preview-midscene/PreviewMidsceneRuntime.ts or apps/server/src/provider/Drivers/OmpDriver.ts, which follow the imports, tag/make/layer, and dependency-acquisition 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.

Scope and methodology:

  • The PR reports 13,822 changed files and 1.45M added lines against pingdotgg/main because the fork branch carries a squashed upstream sync commit (chore(upstream): squash sync pingdotgg/t3code main) plus a merge of it. Reviewing the merge-base diff wholesale is not meaningful, so the review targeted the modules the fork actually introduces on top of upstream (9e0ea47..3495ffa plus the Pi/Midscene/OMP feature commits).
  • Files examined: apps/server/src/provider/Drivers/OmpDriver.ts, apps/server/src/provider/pi/PiRpcClient.ts, apps/server/src/mcp/PreviewMidsceneService.ts, apps/server/src/mcp/preview-midscene/PreviewMidsceneRuntime.ts, apps/server/src/bundledSkills.ts, apps/server/src/provider/Services/PiAdapter.ts, plus repository-wide greps for ManagedRuntime.make, Layer.succeed, catchTag, runPromiseExit, and detail: Schema.String to distinguish new violations from established upstream patterns.
  • Confirmed each flagged file is absent from both the merge base (f61fa94) and current main (06de9e9), so every finding is introduced by this PR rather than inherited.

Deliberately not flagged:

  • Effect.runPromiseExit in PreviewMidsceneService.runBrokerPromise: a clearly named imperative bridge into Midscene's Promise-based agent/device API, not a dependency of another Effect service.
  • makePiRpcClient(transport): PiRpcTransport is a genuine port abstraction with a real test seam, not fake service injection.
  • ProviderDriverError({ detail: \Failed to build ... ${cause.message}` })inOmpDriver.ts: identical to all six sibling drivers on main`; changing only the new driver would be inconsistent repository-wide cleanup.
  • apps/server/src/provider/Services/PiAdapter.ts is a type-only alias over ProviderAdapterShape, matching the existing adapter directory layout rather than a compatibility re-export shim.

🔍 Agent activity — 23 tool calls

1. git_tools — f61fa94..3495ffa

💭 This diff is massive—1.8 million lines between the merge base and head, which seems off for a PR titled "codex/bundle-midscene-preview." I should query the PR files directly through the GitHub API instead of pulling the full diff.

2. github_api_read_only — repos/{owner}/{repo}/pulls/{pull_number}

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

💭 This PR looks like a fork sync with a massive, unusable diff spanning thousands of files — it's already closed, and the merge base is clearly outdated. The real intent behind it seems to be adding compatibility for "oh my pi," so I should dig into the actual commits by this author instead of relying on the diff.

4. github_api_read_only — repos/{owner}/{repo}/pulls/{pull_number}/commits?per_page=100

💭 This PR is actually a fork-sync with a huge diff dominated by an upstream squash, so I should isolate just the fork's genuine new work—the OMP provider bundling feature and its fixes—by diffing against the commit where the fork's tree merged with upstream, rather than the raw base comparison.

5. git_tools — 9e0ea47..3495ffa

💭 Reviewing 13k files fully isn't realistic for this closed fork PR, so I'll focus on the most relevant recent work instead—specifically the new OMP provider files and the pi provider service files. Let me pull the file list from the OMP provider commit to see what changed.

6. git_tools — ce6aa4b

💭 There's a new file, OmpDriver.ts, along with changes to PiAdapter.ts and PiProvider.ts. Given the PR's narrowed scope, I want to focus on the new Effect service code, so let me look at OmpDriver.ts first.

7. git_tools — ce6aa4b:apps/server/src/provider/Drivers/OmpDriver.ts

💭 This follows the ProviderDriver pattern used by other drivers, but I notice a potential convention violation: the error detail field copies cause.message directly to build the wrapper message, which goes against the guideline that the wrapper's message should be derived from stable structural attributes rather than the raw cause message. I want to check whether existing drivers like PiDriver or CodexDriver do the same thing—if it's inherited from a legacy pattern, this might be pre-existing rather than something I introduced. I'll look at the ProviderDriverError definition and compare with other drivers.

8. git_tools — Failed to build .* snapshot

9. git_tools — class ProviderDriverError

💭 This detail-copying pattern shows up in every driver across the repo, so OmpDriver is just following the existing convention rather than introducing something new. Since instructions say not to demand unrelated repo-wide cleanup and to treat this as legacy precedent, I'm weighing whether it still counts as a violation since it's technically a new file—but it matches all sibling implementations exactly. I want to check the fork-added pi provider service files too, looking for clearer convention violations in how they structure runtime layers, service parameters, and error handling patterns.

10. git_tools — ManagedRuntime.make|runPromiseExit|.runPromise

11. browse_code — apps/server/src/provider/pi/**

12. browse_code — apps/server/src/provider/pi/PiRpcClient.ts

💭 I'm noticing that PiRpcClientError stores an unstructured detail string as its only data instead of structured attributes with a derived message, and that detail sometimes just copies raw error text like the failed command output. The clientError helper is also flagged since it's just a thin wrapper that constructs the error from spread args, which the conventions explicitly discourage. And the operation field being a free-form string rather than a literal union is another point worth noting. For makePiRpcClient(transport), I consider whether the injected transport counts as an implementation dependency owned by the service, but since it's a genuine port abstraction with a real test seam using a fake transport, I decide not to flag it. Now I want to check PiAdapter.ts, PiProvider.ts, bundledSkills.ts, and PreviewMidsceneToolkit for similar Layer/service issues, and look at whether PiRpcClientError should have a message getter since it currently lacks one — that seems like a real gap if detail is meant to surface at a caller-visible boundary. I should look for other error classes in the repo to see if there's an established convention of TaggedErrorClass with operation and detail but no message, to judge whether this is consistent or an outlier.

13. git_tools — detail: Schema.String

💭 I notice PiRpcClientError has an empty class body with no message getter, unlike the repo's other error classes that derive messages from their attributes — that's a real deviation from convention. The clientError helper is also just a pure error factory, which the convention flags. Given the size of the fork, I'll narrow my review to a handful of new Effect-related files like PiAdapter.ts, PiProvider.ts, bundledSkills.ts, and PreviewMidsceneToolkit.

14. browse_code — apps/server/src/**/{bundledSkills,PreviewMidscene*,Omp*,Pi*}*.ts

💭 That PiAdapter.ts file is only 211 bytes, which suggests it might be a compatibility re-export shim left behind — exactly the kind of leftover the instructions say to delete rather than keep. I want to check its contents to confirm.

15. browse_code — apps/server/src/provider/Services/PiAdapter.ts

16. browse_code — apps/server/src/bundledSkills.ts

💭 I'm looking at bundledSkills.ts and noticing that registerBundledSkillsExtraRoot self-provides NodePath.layer internally instead of requiring Path from the environment, which hides the dependency from callers—this conflicts with the convention that service dependencies should be acquired from the environment rather than hidden in module internals. I'm also examining the function's client parameter, typed as a pick from CodexInitializationClient, effectively a service instance passed explicitly. Since this client is a per-session runtime object created by the caller rather than an environment-owned service, passing it directly may actually be legitimate rather than a violation. I want to check how CodexProvider or CodexSessionRuntime call into this to see if similar patterns exist upstream. I'm also looking at an error-handling block that catches errors and uses a schema predicate to recover one specific known error code before re-failing — this looks like the exact anti-pattern the convention warns against, where Effect.catchTags targeting the specific tagged error would be the correct approach instead of a schema-based Effect.catch. I want to verify whether the error channel is fully handled here (it's not, since it re-fails), and confirm that the private isCodexAppServerRequestError schema predicate isn't wrapped redundantly, which would be fine per convention. Next I plan to scan PiAdapter.ts, PiProvider.ts, and the PreviewMidsceneService/Runtime files for similar smells around ManagedRuntime and Layer.succeed usage, then broaden the search across the fork-added files for these patterns.

17. git_tools — ManagedRuntime.make|catchTag(|Layer.succeed(|runPromiseExit

💭 That grep was too broad given the scale, so I need to decide on findings and post them. One notable case is PreviewMidsceneService.ts using Effect.runPromiseExit inside runBrokerPromise -- this looks like a legitimate boundary since it's bridging Effect into midscene's Promise-based agent API, which expects a Promise-returning device interface. A named imperative adapter like this can be acceptable as long as it doesn't become a dependency of another Effect service, so I want to check that file's structure more closely since it's a fork-added, 17KB Effect service worth inspecting in scope.

18. browse_code — apps/server/src/mcp/PreviewMidsceneService.ts

💭 I'm noticing that PreviewMidsceneService.ts keeps a standalone PreviewMidsceneServiceShape interface alongside the Context.Service declaration, which goes against the convention of defining the service interface inline rather than retaining a separate Shape type. Some legacy files in the repo do have similar Shape types, but since this service is newly added in this PR's scope, the inline convention should apply here rather than following the older pattern. I'm also checking the use of Effect.runPromiseExit inside runBrokerPromise — it's bridging the Effect service into Midscene's Promise-based device interface for a third-party callback, which seems like a legitimate adapter pattern as long as it isn't consumed as a dependency by another Effect service. Now I want to see how makeWithEnvironment handles ServerSettings versus a default settings effect, so I'm looking at the layer and make definitions toward the end of the file to confirm whether ServerSettings is actually pulled from the environment.

19. git_tools — ^export const (make|layer)

20. browse_code — apps/server/src/mcp/preview-midscene/PreviewMidsceneRuntime.ts

💭 PreviewMidsceneRuntime.ts looks good with its inline interface and layered service setup, unlike PreviewMidsceneService.ts which still keeps the separate shape type. I'm also noticing make reaches into process.env directly rather than pulling from an environment service, which violates the convention against hiding dependencies in module globals — the repo already has a HostProcessEnvironment service meant for this. So I'm compiling my findings: the standalone interface that should be inlined, the raw process.env read that should use HostProcessEnvironment, an error class in PiRpcClient.ts with unstructured detail and no derived message, and something in bundledSkills.ts worth flagging too. Before finalizing though, I need to verify these files actually exist in the PR's changed scope rather than pre-existing upstream code — checking whether PreviewMidsceneService.ts, PiRpcClient.ts, and bundledSkills.ts were present at the merge base commit f61fa94, since the fork branch added several of these via da2de7e and 870e5eb. I should grep the merge base tree for these exact paths to confirm before flagging anything.

21. browse_code — apps/server/src/{bundledSkills.ts,mcp/PreviewMidsceneService.ts,provider/pi/PiRpcClient.ts,provider/Drivers/OmpDriver.ts}

22. browse_code — apps/server/src/mcp/PreviewMidscene*

💭 Since all four files are newly introduced, every line falls within the diff, so inline comments should work fine. I'm mapping out exact line ranges to reference, starting with the interface definition around lines 211-229 in PreviewMidsceneService.ts. For the process.env usage around lines 457-462, I'll flag the relevant line specifically. In PiRpcClient.ts I want two comments: one on the error class structure (lines 20-27) and one on the clientError factory helper (lines 51-57). For bundledSkills.ts, I'm splitting into two comments as well—one on the Effect.provide layer usage and another on the Effect.catch/Schema.is pattern spanning lines 66-73. I'm also weighing whether to flag the OmpDriver pattern where the message is derived from cause—it's a repo-wide convention across sibling drivers, so raising it risks demanding an unrelated consistency change rather than addressing something introduced by this PR specifically. I decide to skip the OmpDriver note since it's a deliberate shared shape across drivers, and flagging just this one instance would push for inconsistent treatment. I'm trimming my inline comments down from six to five, and double-checking exact line numbers and code shapes in bundledSkills.ts to make sure my references are accurate—confirming the resolveBundledSkillsRoot() call with Effect.provide(NodePath.layer) sits at line 60, and the Effect.catch block spans 66-73, while the service instance parameter at line 58 doesn't need comment since it's per-session. I'm also considering whether the review should default to a failing state given the number of legitimate findings. Now I'll draft a concise diff-style suggestion for the PiRpcClientError message and confirm the inline comment line numbers align with the diff's RIGHT-side positions for the new file, then compose and post the final review body.

23. modify_pr — ## Effect service conventions This branch adds several new Effect service modules (apps/server/src/mcp/PreviewMidsceneService.ts, apps/server/src/mcp/preview-midscene/PreviewMidsceneRuntime.ts, apps/server/src/provider/pi/*, apps/server/src/bundledSkills.ts, apps/server/src/provider/Drivers/OmpDriver.ts). PreviewMidsceneRuntime.ts and OmpDriver.ts follow the conventions; four issues below are worth fixing in the new service code. Note: the PR is 13.8k files against main because the fork branch carries a squashed upstream sync, so only the fork-introduced service modules were reviewed.

💭 The inline comments didn't attach, probably because the PR is closed or the diff is too large, but the review body went through fine. I'll report the findings in the check summary instead and won't retry, given the clear convention violations found — this is a failure state.


Agent Credits: 517 credits