Repository navigation
Effect Service Conventions: 2 issues found
apps/server/src/vcs/GitVcsDriverCore.ts
- Lines 1124-1142 — the new
defaultBranchCache/originExistsCachekey on the rawcwd, unlike the sibling caches in this module which key onnormalizeRepositoryPathsCacheKey(cwd)orrepositoryPaths.gitCommonDir. Lookups instatusDetailsand invalidations fromwithListRefsInvalidationcan therefore use different keys for the same directory, and repository-level state (origin URL,refs/remotes/origin/HEAD) is not invalidated across worktrees of the same repository. - Lines 2825-2832 — the PR changes backend behavior (status default branch and origin existence are now cached for 5 minutes and refreshed only through this invalidation hook) without any focused test in
apps/server/src/vcs/GitVcsDriverCore.test.tscovering cache reuse or post-mutation invalidation.
Both findings were posted as inline review comments.
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: the single changed file apps/server/src/vcs/GitVcsDriverCore.ts plus its directly affected call sites (statusDetails, withListRefsInvalidation, initRepoWithListRefsInvalidation, invalidateListRefsSnapshot) and the existing test suite apps/server/src/vcs/GitVcsDriverCore.test.ts.
Conventions verified as satisfied (no findings):
- Imports are subpath namespaces (
import * as Cache from "effect/Cache",import * as Duration from "effect/Duration"); no consolidated named imports from"effect"were introduced. - Service definition shape is unchanged; the driver still returns
GitVcsDriver.GitVcsDriver.of({...})and members are typed viaGitVcsDriver.GitVcsDriver["Service"][...]. - No new service-instance parameters,
Layer.succeedruntime-backed implementations,ManagedRuntime.make,runPromise, orrunPromiseExitwere added; the caches are constructed insidemakewithyield*, so dependencies remain in the Effect environment. - No error/predicate model changes; existing
GitCommandErrorconstruction sites are untouched. - No file moves, re-export shims, or removed comments/invariants.
🔍 Agent activity — 1 tool call
💭 Looking at the diff to understand how Cache is being used in GitVcsDriverCore.ts and checking where it's imported from and whether it follows the project's conventions. I'm noticing that the cache lookup functions reference some const arrow functions defined later in the generator, but since the Cache stores lazy lookup functions that only get invoked at retrieval time, the temporal dead zone won't be an issue—by the time Cache.get calls them, those consts will already be initialized. Now I need to check whether the behavior actually changed: the old approach computed the default branch via a symbolic ref lookup and prefix stripping, while the new one calls resolveDefaultBranchName directly. That's a potential behavior difference, so I should look at the relevant code sections to understand what's happening. I need to check how the cache key normalization works across different caches. The existing repositoryPaths cache normalizes the working directory through normalizeRepositoryPathsCacheKey, but the new caches are using the raw cwd as their key directly. Looking at the invalidation point around line 2825 where invalidateListRefsSnapshot is called with cwd, I should verify whether that function resolves gitCommonDir and what cwd value gets passed for the status cache operations. The cache key mismatch between normalized and raw cwd could cause invalidation to miss, which is a correctness bug. But the review scope is specifically about Effect service conventions, not general correctness issues. I'm evaluating whether this violates any stated conventions — the use of Effect.gen in invalidateStatusStaticCaches might not align with simpler patterns like Effect.all or Effect.andThen, though that's not explicitly listed as a convention. The bigger question is whether the behavior change from the new default branch resolution logic and the 5-minute TTL constitute a staleness issue that requires focused test coverage. I'm thinking through which conventions apply here—the caching approach keeps dependencies out of module globals which is good, but there's a potential correctness issue where cache keys use raw
cwdstrings while the repository paths cache normalizes them, meaningensureRemoteandfetchRemoteinvalidation calls might pass different string formats than whatstatusDetailsuses, leading to cache misses or stale data. The PR title mentions "stable lookups" and there's precedent in the file for normalizing cache keys, but that's more of a correctness bug than a convention violation. However, the real convention issue is that this PR changes backend behavior—adding five-minute caching for default branch and origin existence—without adding tests, which violates the "Change discipline" convention requiring focused tests when backend behavior changes. I should check if there are existing tests forGitVcsDriverstatus details that could be updated, and whether the diff shows any test modifications. I should check if the existing tests in GitVcsDriverCore.test.ts have assertions around command counts for statusDetails, since the caching behavior being added might affect those counts and potentially break tests. Let me search for any symbolic-ref related test assertions. I'm looking at the test coverage for statusDetails with the default branch—specifically lines 886-898 where symbolic-ref gets set before calling status. The concern is that caching could interfere if refs change mid-test within the same driver instance. Now I'm weighing whether this PR violates the "focused tests" convention: since statusDetails behavior is changing, I need to determine if focused tests are actually required here. The cache invalidation on mutating operations seems reasonable, but there's a real gap—no new tests cover the cache behavior itself or its invalidation logic. That's a concrete violation under the change discipline rule. I'm also noticing the cache keys aren't normalized while sibling caches are, which could cause invalidation misses if the cwd is spelled differently, though that's more of a correctness issue than a convention violation. There's also the magic number 2_048 used inline instead of a named constant like REPOSITORY_PAT, which is inconsistent with the codebase style. Let me verify thatresolveDefaultBranchNameis semantically equivalent to the oldparseDefaultBranchFromRemoteHeadReflogic—if it is, then caching is the only behavioral change. I also need to check whether the caches actually work in this environment sinceCache.makeWithdepends onexecuteGit, which requiresChildProcessSpawnerfrom the context. In Effect, the cache lookup effects should have their requirements satisfied by the construction context. There's also a potential temporal dead zone issue:defaultBranchCacheis created at line 1124 but referencesresolveDefaultBranchNamedeclared later at 1216 as a const. The lookup arrow captures the binding lazily, so it should be fine sinceCache.makeWithdoesn't invoke immediately. The TypeScript scoping is valid—block-scoped variables used before declaration inside function bodies don't trigger errors. However, the missing tests are a real issue: the Change discipline explicitly requires focused tests when backend behavior changes, and caching the status and origin-existence results for 5 minutes is definitely an observable behavior change. Consumers will see stale values after operations likegit remote addperformed outside the driver or afterinitRepo, which doesn't invalidate these caches. Additionally,initRepoWithListRefsInvalidationdoesn't invalidate the new caches either, which is an inconsistency worth flagging. worktree-specific cache invalidation might not work properly since the default branch is stored at the repository level, not per-worktree. I need to check howinvalidateListRefsSnapshotkeys its entries to see if it accounts for the git common directory. The real issue here is thatinvalidateListRefsSnapshotnormalizes usinggitCommonDirwhile the new status cache keys off the rawcwd, creating an inconsistency that breaks cross-worktree invalidation. Looking at the listed conventions though, this doesn't actually violate any of them—not the import rules, service definitions, error handling, or dependency constraints. The only relevant rule is requiring focused tests when backend behavior changes, so I need to decide whether that's enough to fail the check, which defaults to failure anyway. The missing test coverage is legitimate: there's a concrete behavior change with the new five-minute caching and invalidation logic that has zero tests. That's exactly what the convention list explicitly requires. I should also flag the key-normalization bug since it's an observable correctness defect in the invalidation path that the PR introduces—a test would catch it. I'll post two inline comments: one on the cache lines about the unnormalized keys, and another explaining why tests are needed for this behavior change. gestion. I'll skip the diff and just post the comment without a code suggestion since the fix spans multiple sites. For the second comment on line 2829, I'll request a focused test for cache reuse and invalidation behavior, checking that the tests in GitVcsDriverCore.test.ts cover this scenario. Let me verify that statusDetails caching also affects statusDetailsRemote and statusDetailsLocal — they share the core implementation, so the change applies consistently. I'll keep both comments concise.
1. modify_pr — Two findings on the new status caches in apps/server/src/vcs/GitVcsDriverCore.ts: the cache keys are not normalized/repo-scoped the way the sibling caches in this module are, and the new caching behavior lands without any focused test.
Agent Credits: 62 credits