Repository navigation
Effect Service Conventions: 2 issues found
Two convention violations in the new teleport service code, both posted as inline review comments:
apps/server/src/teleport/TeleportService.ts(line 2140): startup reconciliation (recoverInterruptedTeleports, run during layer construction) wraps the whole recovery inEffect.catchCauseand reduces interruption to a warning instead of re-failing interrupts asserverRuntimeStartup.tsdoes.apps/server/src/teleport/importTransaction.ts(lines 398 and 460): per-entity startup repair swallows interruption and never retries a transient failure before readiness, so a single flaky dispatch can permanently leave a thread fenced atpresence: "importing".
Also still open from a prior run (not re-posted): Effect.catchTag("TeleportSchemaVersionError", ...) in apps/server/src/teleport/formats/codex.ts:342 and apps/server/src/teleport/formats/claude.ts:442 should use Effect.catchTags({ ... }).
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.
Verified as compliant:
TeleportServiceusesContext.Servicewith an inline interface, canonical file order (imports, tag,make,layer), and acquires every dependency from the environment (ServerSettingsService,OrchestrationEngineService,ProjectionSnapshotQuery,ProviderSessionDirectory,ProviderInstanceRegistry,ProviderService,Crypto,TeleportFormatRegistry).- No
ManagedRuntime.make/runPromise/ service-instance injection in production paths; service instances are supplied only through test layers. - New teleport errors in
packages/contracts/src/teleport.tsuseSchema.TaggedErrorClasswith structured attributes, derivemessagefrom those attributes, preserve realcausevalues, and are composed intoSchema.Unionerror channels for the RPC surface. - Namespace subpath imports (
effect/Effect,effect/Layer, ...) are used throughout the new modules;ws.tsandserver.tsconsume the service through theTeleportServicemodule namespace. - Startup pattern reference used for comparison:
apps/server/src/serverRuntimeStartup.tslines 333-377 (Effect.retry({ times: 1 })+Cause.hasInterrupts(cause) ? Effect.failCause(cause) : Effect.logWarning(...)).
🔍 Agent activity — 6 tool calls
💭 I'm checking the diff between commits and see the catchTag usages in codex.ts and claude.ts flagged in the prior review are still unchanged, so I shouldn't duplicate comments already posted about them. Now I'm reviewing TeleportService.ts for convention adherence—it uses Context.Service correctly with proper file ordering, errors are defined via Schema.TaggedErrorClass, and catchTags usages look appropriate. I'm also checking helper functions like nativeRevisionDivergenceError and alreadyInFlightError to see whether they're simple error constructors or do meaningful normalization work. I'm looking at how dispatch functions pass through reason and cause fields to confirm error context is preserved, and examining whether TeleportFormatRegistry's
make = Effect.sync(...)should instead be a plainLayer.succeedsince it's pure synchronous construction. Since prior review likely covered the same registry code without flagging it, I'll stay consistent and not flag it here either. Moving to TeleportService.ts, I'm checking thatmakeproperly acquires all its dependencies via yield* for settings, engine, snapshot query, directory, registry, provider service, crypto, and formats — which it does correctly. I'm also examining the startup reconciliation logic aroundrecoverInterruptedTeleports, checking whether it preserves interruption semantics properly rather than downgrading failures to warnings, since the convention calls for isolating persistent per-entity failures so they don't abort global startup. Now I notice the recovery pipeline ends with a catchCause handler that logs a warning — but catchCause swallows all causes including interruption, which is exactly the anti-pattern the convention warns against. The per-entity loops have the same issue, catching causes and warning without retrying first. This looks like a legitimate finding since it's a new file in scope for the PR, though I'm second-guessing myself since prior review runs didn't flag it — but that could just mean the reviewer missed it rather than it being acceptable. The global catch swallows interruption entirely, so it needs to preserve it—only catching real failures/defects and re-raising interruption, while the per-entity path should add a retry for transient failures before falling back to isolation. This maps to the catchCause block in TeleportService.ts handling the recovery-failed warning. I want to verify the exact line numbers by pulling the file at head before leaving an inline comment. I should also check recoverInterruptedImportTeleports in importTransaction.ts, since it uses the same catchCause-then-logWarning pattern per entity and likely has the identical interruption-swallowing issue. The other files—teleport.ts in apps/web and client-runtime, plus server.ts and http.ts—look fine on the import and layer wiring front. Now I'm second-guessing whether http.ts's named import of the TeleportService tag actually violates the namespace-import convention at service boundaries, since ws.ts uses the namespace form while http.ts imports just the tag directly. The convention seems to allow named imports for modules used only in limited ways, so this may not be a real violation. I won't dwell too much on the test import aliasing. The strongest issue remains the interruption-swallowing startup reconciliation, which genuinely fits the Effect Service Conventions concern worth flagging. Checking TeleportService.ts, the error mapping looks solid—cause is properly preserved when constructing TeleportDiscoveryError instances, though I want to double-check the mapError usage around dispatchTeleportSet. Looking further, catchTags and catchDefect are used appropriately in stopThreadProviderSession and requireNativeRevisionForTurn, and provideContext looks fine too. The bigger question is whether per-entity recovery in importTransaction should include retry logic per convention—that's a larger ask involving retry, readiness, isolation, and tests. I'll keep my comment focused on the interruption swallowing issue and just mention retry as a secondary note, then pull the specific line numbers to reference.
1. git_tools — catchCause
2. git_tools — catchTag(
💭 The catchTag issues were already flagged before, so I won't repost those. I'm moving on to check the startup reconciliation logic around lines 1890-2145, and also considering whether including
cause: String(cause)in log annotations violates the convention against copying arbitrary defect text into log payloads. That's a borderline case since the rule seems more targeted at reintroducing serialized cause fields alongside sanitized errors rather than plain log-only annotations — I'll skip flagging it and move on to reviewing the recovery section in full.
3. browse_code — apps/server/src/teleport/TeleportService.ts
💭 I wonder if there's an existing repository pattern the convention was distilled from, like the reconcile test that retries failed projections and continues after a persistent failure. Let me check that file for the retry-and-isolation pattern and how interruptions are preserved.
4. git_tools — retry|catchCause|hasInterrupt
💭 I've confirmed the repo's established pattern for startup reconciliation, which retries once and distinguishes interruption causes from other failures via logging. The new TeleportService recovery deviates from this by swallowing interruption at both the global boundary and per-entity boundaries, which is a legitimate inconsistency worth flagging. I want to post inline comments on the two TeleportService lines that swallow interruption without preserving it like the reference pattern does, keeping it to two focused comments rather than fragmenting feedback. I should also check whether importTransaction.ts's recoverInterruptedImportTeleports has the same catchCause issue before deciding if that needs its own comment.
5. git_tools — catchCause
💭 I'm identifying startup reconciliation functions that swallow interruptions without retrying before the system is ready — this matches the convention violation, so I'm flagging the global boundary in TeleportService.ts to preserve interrupts, and the per-entity recovery point in importTransaction.ts to preserve interrupts while also retrying transient failures. I'm noting that the in-flight post-commit steps in importTransaction.ts are deliberate best-effort work in a request path, not startup reconciliation, so I'll leave those out of scope and focus on just the two comments — the TeleportService line and the importTransaction line, checking that both land on diff lines since these are newly added files. Since fixing the interrupt-swallowing requires importing Cause and re-checking for interrupts before logging a warning, I realize an inline single-line suggestion won't be self-contained, so I'll provide a short unified diff instead noting the needed import, and do the same for the importTransaction.ts case which also needs a retry consideration. Now I'm drafting the actual comment text explaining that startup teleport recovery runs during layer construction and swallows interruption, meaning a shutdown mid-recovery gets reported as a mere warning while readiness continues, referencing how serverRuntimeStartup.ts handles this correctly by re-failing interrupts. I'm confirming that
Cause.hasInterruptsis indeed available since it's already used in serverRuntimeStartup.ts, and double-checking the exact indentation levels in both TeleportService.ts and importTransaction.ts to make sure my suggested diffs align correctly with the existing code structure. For the second comment, I'm building a diff that adds a retry attempt before the catch clause, and modifies the catch to check for interrupts—propagating the failure if interrupted, otherwise logging the recovery-skipped warning as before. I'm also noting the guidance about limiting unchanged context lines to at most one before the first change. Given these findings plus the unresolved catchTag issues from earlier, I'll mark the overall check state as "failure" and proceed to post the review.
6. modify_pr — Reviewed the new apps/server/src/teleport/** service code against the Effect service conventions. Two findings on startup reconciliation error handling. The Effect.catchTag usages in formats/codex.ts and formats/claude.ts flagged in a previous run are still present and unchanged; not re-posting those.
Agent Credits: 315 credits