Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This is a substantial cross-component capability adding authenticated tunnel recovery, Cloudflare resource deletion, schema/concurrency changes, and server lifecycle behavior. The default-off cleanup mode limits immediate exposure, but the production networking, irreversible resource-management, and authentication-sensitive changes still require human review. You can add or adjust custom eligibility rules. Learn more. |
There was a problem hiding this comment.
Effect service conventions: four findings, all in newly added error-handling code (three Effect.catchTag usages and one startup Effect.catchCause). Details inline.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
One convention finding on the new retry predicate. Previously reported Effect.catchTag usages in ManagedEndpointReaper.ts, ManagedEndpointProvider.ts and the Effect.catchCause in server.ts are resolved in this head commit.
Posted via Macroscope — Effect Service Conventions
4831d73 to
6a0992d
Compare
There was a problem hiding this comment.
Reviewed the Effect service changes in this PR against the repository's service conventions. One convention violation found: a newly added Effect.catchTag in apps/server/src/cloud/http.ts. Everything else (the new ManagedEndpointReaper service definition, dependency acquisition via the environment, make/layer exports, structural failure discriminator on the runtime status, and interruption-preserving Cause.hasInterrupts handling in server.ts) matches the conventions.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6a0992d. Configure here.
|
Note 🤖 GPT-5.6 Sol responding on behalf of Theo The verified The focused HTTP suite passes with 33 tests. Server typecheck and scoped lint also pass. The current PR head is |
|
Note 🤖 GPT-5.6 Sol responding on behalf of Theo Fixed the five verified issues from this review round:
The focused HTTP suite passes with 41 tests. Server typecheck, scoped lint, formatting, and diff checks also pass. Route integration coverage was added for the queued recovery response. |
|
Note 🤖 GPT-6 Astra (preview) responding on behalf of Theo This was closed as part of an automated cleanup pass. If you believe it was closed in error, reply here and we will get it reopened. Closing in favor of #9386. It carries forward the original commits and adds the recovery-state fix. The remaining review and rollout checks belong there. We do not need two open PRs for this work. |

Cloudflare tunnels stayed allocated after their host went offline. Closed and down tunnels cost the same as active tunnels, so this left an increasing number of paid resources with no useful connection.
This change adds managed tunnel cleanup, with
RELAY_TUNNEL_CLEANUP_MODE=offas the default. For existing allocation records, the relay only deletes tunnels whose hosts registered recovery with the public key on their current environment link. It skips legacy and incomplete allocations. Expired same-namespace tunnels with no allocation record are orphans; the relay rechecks their Cloudflare status before deletion. Each sweep has page, deletion, and time limits, and it stops the deletion loop when Cloudflare returns a structured rate-limit response.When cleanup removes a tunnel, the host provisions a replacement and keeps the same public hostname. The endpoint URL does not change, so web, desktop, and mobile clients do not need new bindings. The host also watches repeated Cloudflare authorization failures, which covers a connector that stays alive after laptop sleep and wake.
Healthy startup does not provision a tunnel. A confirmed connector starts from its stored config when the saved loopback origin still matches. The host then registers recovery with the relay. Cloudflare ingress is updated only when the local origin changed. Registration retries transient failures with capped exponential backoff, while local connector startup retries do not repeat relay or Cloudflare work.
A valid legacy connector config without a stored tunnel ID requests recovery directly. The relay uses its allocation record to return a complete replacement config, which the host persists before starting the connector. The host does not parse the opaque connector token.
The rollout is relay first:
off.dry-runand inspect cleanup counters across several sweeps.The live Cloudflare sleep and wake test has not been run. Production deletion must stay disabled with
offordry-rununtil the disposable stage canary passes. For rollback, disable cleanup before downgrading any host, keep the recovery endpoints deployed while updated hosts remain in use, and retain the additive nullable migration.The focused server and relay tests cover registration, origin changes, connector recovery, unlink races, generation checks, cleanup eligibility, fairness, deletion caps, and rate limits. Scoped lint, formatting, and typechecks also pass.
Authored with GPT-5.6 Sol in Codex.
Note
High Risk
Touches cloud link persistence, tunnel lifecycle, relay allocation concurrency (generation), and optional production tunnel deletion; mis-timed cleanup rollout or race bugs could break remote reachability for linked environments.
Overview
Adds managed tunnel recovery so hosts can register loopback origin with the relay, replace tunnels deleted while offline, and auto-recover when
cloudflaredreports repeated Cloudflare authorization failures—without changing the public hostname.The server now persists a confirmed-origin marker (
CLOUD_ENDPOINT_CONFIRMED_ORIGIN), starts the connector on boot only when that marker matches the current config and port, and gates relay-config / link flows on successful tunnel recovery registration (with retries, longer provision timeouts, and serialized link-state updates).ManagedEndpointRuntimeexposes recovery request streams, classifies retryable spawn failures, and launchescloudflaredwith explicit logging flags.On the relay, a migration adds recovery/origin/generation fields to allocations;
RELAY_TUNNEL_CLEANUP_MODE(off/dry-run/enabled) controls periodic inactive-tunnel cleanup for hosts that registered recovery. Deploy workflow and docs describe rollout order (relay first, server builds, then dry-run → enabled).Reviewed by Cursor Bugbot for commit 185a29f. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add managed tunnel reaper and recovery flow for offline hosts
ManagedEndpointReaperservice that periodically sweeps and deletes orphaned managed tunnels, controlled byRELAY_TUNNEL_CLEANUP_MODE(off|dry-run|enabled, defaults tooff) in worker.tsregisterManagedEndpointRecoveryandrecoverManagedEndpointAPI endpoints backed by signed JWT proofs in Api.ts; the server runtime emits recovery requests when repeated tunnel authorization rejections are observed and consumes them to provision replacement tunnelsupdatedAt-based concurrency inManagedEndpointAllocationswith a numericgenerationcolumn; mutations now require a generation match and return the previous generation or null; addswithClaimedTunnelfor transactional row lockingorigin,generation,recovery_enabled_at, andrecovery_environment_public_keycolumns torelay_managed_endpoint_allocationsManagedEndpointAllocationsservice method signatures and return types change broadly (recordTunnel,recordDns,markReady,claimRelease,claimDeprovision,removeClaimednow returnEffect<number | null>orEffect<boolean>and requiregeneration);releaseonManagedEndpointProvidernow returnsEffect<boolean>instead ofvoid; all tunnel client ops inlayerCloudflareBindingsare capped at 8s timeoutMacroscope summarized 185a29f.