Repository navigation
Effect Service Conventions: 1 issue found
1 finding
apps/server/src/orchestration/Layers/ProviderCommandReactor.ts(startup recovery of pending usage-limit resumes, lines ~1774-1798): the per-thread repair dispatch is not retried and itsEffect.catchCauseswallows interruption into a warning. Every other usage-limit dispatch in this file goes throughretryUsageLimitResumeDispatch, and the comparable startup reconciliation inserverRuntimeStartup.tsretries once and re-fails on interrupt. Suggested fix posted inline (retry once, propagate interrupts, keep per-thread isolation), plus tests for the retry-success and persistent-failure-continuation paths.
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: all changed apps/** and packages/** TypeScript/TSX files.
Checked and found clean:
- Imports: new modules use namespaced Effect subpath imports (
effect/DateTime,effect/Fiber,effect/Schedule,effect/unstable/sql/SqlClient); no consolidatedfrom "effect"imports were introduced.@t3tools/contractskeeps named imports as expected, and the new pure helpers (apps/server/src/provider/usageLimits.ts,packages/client-runtime/src/state/usageLimitResume.ts) are correctly consumed with named imports. - Service definition/layout: no new
Context.Servicetags, shapes,make/layerexports, or service file moves; nothing requires the canonical single-file ordering rules. - Dependency acquisition: no new
ManagedRuntime.make,runPromise/runPromiseExit,Layer.succeed, or service-instance parameters in production code. The changedEffect.runPromiseβharness.runEffectcall sites are test-harness only. The newusageLimitResumeFibersmap is scoped insidemake, not a module global. - Errors and predicates: no new error classes,
Schema.Defectusage, discriminator fields, orcatchIf/catchTagrecoveries were introduced; error metadata added to the session projection (lastErrorClass,retryAt) is normalized/bounded rather than raw payload data. - Change discipline: new tests accompany the behavior change (decider, projector, reactor, adapters, provider usage-limit helpers) rather than proving a mechanical refactor.
Note (not flagged): retryUsageLimitResumeDispatch retries indefinitely with a 30s-capped exponential schedule. That is acceptable on the fiber/worker paths, but reusing it verbatim on the startup path would block readiness, which is why the inline suggestion uses a bounded retry there.
π Agent activity β 6 tool calls
π I'm reviewing the diff for Effect service convention violations, checking the new usage limits helper files, migration, and tests to confirm imports follow the expected patterns. The reactor introduces a fiber map scoped within
make, which seems consistent with existing patterns, and I'm now examining whether the startup reconciliation logic properly preserves interruption for persistent failures rather than just logging a warning, since it retries transient per-entity repairs before catching the cause broadly for pending resumes. I notice the recovery dispatch for usage-limit-resume lacks the retry wrapper other dispatches use, unlikeretryUsageLimitResumeDispatchelsewhere β a plausible gap where startup recovery isn't retried and swallows interruption. I also spot a similar pattern ingetCommandReadModel'sEffect.catchCause, which logs a warning and falls back to an empty array, again potentially swallowing interruption at startup. I want to check the actual file to confirm line numbers, and also note the odd IIFE-based field-stripping insetThreadSessionErrorOnTurnStartFailureas a possible style concern. CheckingretryUsageLimitResumeDispatchmore closely, it uses a capped exponential schedule with infinite retries, but sinceEffect.retrydoesn't retry interruptions, that should be fine. I'll also glance at whetherproviderUsageLimitFromErrormixesnullandundefinedinconsistently, though that seems minor, and then pull up the startup block inProviderCommandReactorto verify everything.
1. git_tools β usage-limit-resume-recover
2. git_tools β hasInterruptsOnly
π I notice the startup recovery block swallows interrupts into a mere warning without retrying the recovery dispatch, unlike other usage-limit dispatches that use
retryUsageLimitResumeDispatch. This points to a convention: startup reconciliation repairing multiple independent entities should preserve interruption signals rather than downgrading them, retry transient per-entity repairs before declaring readiness, and isolate persistent failures so one bad entity doesn't block the rest. I'm also noting a related spot whereEffect.catchCauseongetCommandReadModel()similarly reduces interruption to a warning during layer startup, though it's a single global query rather than per-entity. Checking the existing test suite, I see it covers recovery success but not the transient-retry or persistent-failure-isolation paths, which confirms this is a real gap worth flagging alongside the primary finding. I'm also weighing whetherretryUsageLimitResumeDispatch's unbounded retry loop in the event-processing worker counts as a violation of the isolate-persistent-failure convention, but since that's the event path rather than startup, flagging it feels riskier and less clear-cut. I've also scanned imports and exports in ChatView.tsx and the client-runtime package.json and found nothing else worth noting there. The tests replacingEffect.runPromisecalls withharness.runEffectlook consistent with allowed test-harness patterns, and no new service definitions appear in the diff. That leaves one main finding to write up, so I want to pull up the exact surrounding lines forretryUsageLimitResumeDispatchand the related block further down to phrase the suggestion accurately.
3. browse_code β apps/server/src/orchestration/Layers/ProviderCommandReactor.ts
4. browse_code β apps/server/src/orchestration/Layers/ProviderCommandReactor.ts
π I'm drafting the review comment noting the startup recovery flow swallows interruption into a warning instead of using the retry wrapper that every other usage-limit dispatch relies on, and I'm suggesting wrapping the dispatch call to preserve interruption handling consistently. But I realize
retryUsageLimitResumeDispatchretries infinitely, and since this call sits inside aforEachthat's awaited before startup completes, an unbounded retry could stall readiness β so I should suggest a bounded retry schedule instead of a naive swap, though that complicates a simple inline suggestion. Still writing retry logic...
5. git_tools β Effect.retry({
π I found a matching precedent in serverRuntimeStartup.ts that retries once then catches the cause, preserving interrupts but logging a warning otherwise. I'm mirroring that same pattern for the inline suggestion at lines 1789-1796. I'm double-checking indentation levels against the surrounding lines so the suggestion fits cleanly into the diff, and confirming these lines are on the added side so they're commentable. I'll also briefly flag the similar catchCause swallowing interrupts at line 1765 as a secondary note in the review body rather than adding another inline suggestion. I'm deciding not to raise the unbounded retry loop as a separate finding since it's tangential to the startup reconciliation convention, and I'll note the missing retry-success/persistent-failure test coverage as a supplementary point. Now I'm assembling the review comment text and preparing the suggestion block with exact matching code lines before posting the review with a failing status.
6. modify_pr β One finding in the reactor's startup reconciliation of pending usage-limit resumes. Details inline.
Agent Credits: 106 credits
Token usage: 10 uncached input Β· 371,018 cache-read input Β· 101,332 cache-write input Β· 7,370 output
Agent Credits may also include non-token charges from external tools such as web research.