Skip to content

fix(web): preserve diff comment drafts on collapse

MacroscopeApp / Macroscope - Effect Service Conventions failed Aug 4, 2026 in 2m 32s

Effect Service Conventions: 1 issue found

apps/server/src/vcs/GitVcsDriverCore.ts — the new reviewDiffFileError helper hardcodes operation: "GitVcsDriver.getReviewDiffFileContents" and command: "git" for all failures in the new file-contents pipeline, including filesystem stages (realPath, stat, size limit, readFile, binary detection). Those non-git failures are reported as "Git command failed" and the failing stage is only visible in the free-form detail, unlike the rest of this module which encodes the stage in operation (e.g. ...getReviewDiffFileContents.revision, ...mergeBase). An inline comment with a suggested fix was posted.

The operation-mislabeling issue flagged in the prior run (assertWorkspaceBoundCwd reporting ReviewService.getDiffPreview for file-content rejections) is now resolved: the operation is threaded through the helper, the detail is derived from it, and ReviewService.test.ts covers the new attribution.

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.

Reviewed for the documented conventions:

  • Imports: ReviewService.ts, GitVcsDriverCore.ts, and GitVcsDriver.ts use effect/* subpath namespace imports, named imports from @t3tools/contracts, and namespace imports for local service modules (GitVcsDriver, VcsDriverRegistry, ServerConfig) — no violations.
  • Service definition: ReviewService keeps its inline interface in the Context.Service declaration, new methods are typed via ReviewService["Service"]["getDiffFileContents"] / GitVcsDriver["Service"], and make/layer ordering is unchanged.
  • Dependency acquisition: no new ManagedRuntime.make, runPromise, runPromiseExit, Layer.succeed, or service-instance parameters in production code. The only service-instance passing is the server.test.ts router stub (a legitimate test seam); DiffPanel.tsx consumes the RPC through the existing useAtomCommand React boundary.
  • Errors: new failures reuse existing Schema.TaggedErrorClass contracts (GitCommandError, VcsRepositoryDetectionError, VcsUnsupportedOperationError), preserve cause where an underlying failure exists, keep detail free of command output/credentials, and use Effect.mapError rather than catchTag/catchIf. The VcsRepositoryDetectionError operation discriminator now carries two values with messages derived from it, which matches the allowed single-service-error model.
  • Contracts/client-runtime: ReviewDiffFileContentsInput/Result schemas, the new RPC, and the createEnvironmentRpcCommand atom follow existing patterns.
  • Tests: backend behavior changed and focused tests were added at both the driver (GitVcsDriverCore.test.ts) and service (ReviewService.test.ts) levels, plus a router seam assertion — no core business logic mocked out.

🔍 Agent activity — 1 tool call

💭 I'm reviewing the diff across the service files to check the Effect service conventions. The previous run caught an issue with hardcoded operations, which the PR addressed by threading the operation through properly. Now I'm noticing the updated code uses a ternary conditional based on the operation to determine the detail message, and there's a convention note about avoiding encoding the same distinction twice with both a specific approach and something else. Looking at the actual implementation, I need to verify the imports style, error definitions, and that helper function reviewDiffFileError. The convention warns against creating helpers that are just thin constructor wrappers, but this one does add reusable context by setting operation, command, and working directory from the input — so it probably passes the bar of performing real normalization or adding reusable context. The detail fields include file paths like input.newPath, which is allowed since path context is considered real domain information. The validation errors for binary files don't include a cause, which is fine. Let me check the actual file to verify the imports and see if there are existing patterns I should be aware of. Looking at the new GitVcsDriverCore code to see if the error-construction helpers follow existing patterns in the file, and I'm noticing that reviewDiffFileError is just a thin wrapper around creating a GitCommandError with fixed operation and command values—which goes against the convention of not adding helpers that only pass arguments through to a constructor. The helper does add some reusable context though, so it might be acceptable, but there's a tension: all errors from this helper share the same operation name while the underlying executeGit calls have more specific suboperation names, and the different failure modes (binary file, outside workspace, size limit, not a file) are semantically distinct yet all use the same GitCommandError type—which is actually the existing driver convention anyway. The detail strings look fine since they're mostly static with path information, and while there's a slight oddity with command: "git" appearing in errors where no git command was actually executed (like in readWorkingTreeReviewFile using fileSystem), that's not a convention violation—I should check how other error constructions in the file handle this pattern. Looking at the GitCommandError contract to understand how fields are structured and how messages get derived. I'm noticing that reviewDiffFileError acts as a thin factory that gets reused across different failure scenarios—it does bundle useful context like the operation, command, and working directory, which seems to justify keeping it as a mapper. But there's a potential issue where command: "git" gets applied to filesystem errors, which feels a bit misleading even if it's not technically a convention violation. I'm also checking the naming pattern for spans like Effect.fn("readReviewFileAtRevision") against other spans in the file—the existing style uses unqualified names, so that's consistent. Now I need to verify how detail fields are populated across the codebase, particularly whether they include raw command arguments or stderr output, and whether the path context in readReviewFileAtRevision aligns with what's allowed elsewhere. There's also a scope mismatch I'm noticing: the new handler uses AuthReviewWriteScope for what appears to be a read-only method, so I should check how reviewGetDiffPreview is scoped to see if that's actually a convention issue. The client-runtime looks standard. Now I need to check the IPC EnvironmentApi addition in the contracts package — specifically the new getDiffFileContents method in the review section. If this interface member was added, any implementations like the electron or tauri bridge would need to be updated too, otherwise TypeScript would throw an error. Let me trace through who actually implements EnvironmentApi.review to see if those implementations have been updated. EnvironmentApi.review is just an interface change for ipc, likely implemented elsewhere. Now I need to check the GitVcsDriver.ts interface addition and any resulting errors, particularly around GitCommandError—whether the message is derived from detail and if cause is required. There's also an important convention to keep in mind: avoid encoding the same distinction twice using both a specific error tag and a single-value operation, which seems relevant to how VcsRepositoryDetectionError is being handled in ReviewService. Looking at the existing error patterns, reviewDiffFileError is a thin wrapper that creates errors with consistent context—operation, command, and working directory—which gets reused across multiple call sites, so it's worth keeping rather than inlining. The GitCommandError with command: "git" for filesystem failures is a bit of a mislabel since the actual problem isn't a git command failure but a file read issue, yet the operation field stays generic across distinct stages (path resolution, stat, size check, read, binary detection) even though other parts of the codebase use stage-specific operation names. The detail field does distinguish between these stages, but I'm wondering if that's just duplicating what the cause already captures. Looking at the web side, DiffPanel.tsx uses the existing useAtomCommand helper without adding any new runtime management, and the promise-based atom command from the React boundary looks fine. I should verify the interface additions in GitVcsDriver.ts are placed correctly and check the service definition. Everything checks out with the existing patterns. The service instance being passed in the server tests is fine, and the new schemas in the contracts file follow the right order. Now I'm weighing whether Effect.catchTags is the better choice here compared to catchIf or catchTag. The new code uses Effect.mapError without catchTag, which is acceptable. I'm also noting that Effect.orElseSucceed is already in use elsewhere. There's one thing I'm considering: the reviewDiffFileError helper fixes command: "git" on filesystem errors and uses a single generic operation across multiple stages, whereas the file's convention typically suffixes operations by stage. The check instructions emphasize capturing stable, serializable domain context like operation or stage, and mapping failures where that context is known rather than wrapping an entire pipeline in one generic error. The helper does mean all stage failures share the operation "GitVcsDriver.getReviewDiffFileContents," but the detail field carries stage-ish information as free-form text while preserving cwd and path context. Given that the check defaults to failure only for clear violations and this is more of a style preference, I'd say it's borderline acceptable. Actually, though—setting command: "git" for filesystem-based failures like realPath, stat, or readFile is factually incorrect. The derived error message says "Git command failed" when it's really a filesystem read failure, which is inaccurate structural context. This is analogous to a prior issue where wrong operation naming in error context was flagged and fixed. I think this deserves an inline comment as a legitimate, precise finding. Whether the check should fail or just report it neutrally depends on whether this counts as a clear convention violation from the guidelines. Looking at the relevant instruction about capturing stable, serializable domain context—the helper wraps distinct stages (git show binary detection, path escape, realPath failure, stat failure, size limit, read failure) into one generic error with a fixed operation, losing the stage information. Elsewhere in the same file, they use stage-suffixed operations like .hash, .revision, .repositoryRoot, .mergeBase, so this new code deviates from that pattern. That's a defensible finding. Since the check defaults to failure when there are any findings, I need to decide if this stage-loss issue is strong enough to warrant failing the check or if it's just worth a modest inline comment. The more concrete problem is that command: "git" is reported when no git command actually ran—filesystem failures are being labeled as git command failures. That's a clearer inaccuracy than the stage-loss issue. Given the explicit instruction that this check defaults to failure, posting a finding about the command mislabeling and setting the state to failure seems consistent. Now I need to locate where to add the comment. The helper function is being added at lines 2275–2286 in GitVcsDriverCore.ts, which corresponds to a new hunk in the diff starting around line 2272. I'll target the comment at lines 2281–2282 where the operation and command are defined. The issue is that the helper uses a fixed command: "git" and a generic operation value, which doesn't capture the actual stage context when filesystem errors occur. I could suggest threading the stage parameter into the helper, but that would require updating all ten call sites, making it not self-contained for an inline suggestion. I'll provide a unified diff instead to show the helper signature change and note that callers need updating.

1. modify_pr — One finding on the new Git review-diff file-contents path. See the inline comment.


Agent Credits: 92 credits