From ce6ad38f66b44f165d8f635c2e0d61acecba373f Mon Sep 17 00:00:00 2001 From: Rhys Sullivan <39114868+RhysSullivan@users.noreply.github.com> Date: Sun, 25 Oct 2026 14:25:55 -0700 Subject: [PATCH] Give the cap-eviction scenario an idle window it can cross the cap in The scenario opens sessions one at a time and needs cap + 1 (25) resident at once, but each session idles out MCP_SESSION_TIMEOUT_MS after it opened. At 3s, 25 opens took the whole window on a CI runner (80-125ms each). When they ran over, early sessions idled out as new ones opened, the cap was never crossed, and the scenario timed out. Raise the e2e idle timeout to 8s in CI and the e2e default, and document the constraint next to the cap. --- .github/workflows/ci.yml | 4 +++- e2e/setup/mcp-session-timeouts.ts | 6 +++++- e2e/setup/resident-runtime-cap.ts | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5faa155563..fa2c40c093 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -310,7 +310,9 @@ jobs: - name: Run cloud shard if: matrix.target == 'cloud' env: - MCP_SESSION_TIMEOUT_MS: "3000" + # Long enough for the cap-eviction scenario to hold more sessions + # resident than the e2e cap (see e2e/setup/resident-runtime-cap.ts). + MCP_SESSION_TIMEOUT_MS: "8000" # Still 18x shorter than production, but long enough for a cold Vite # resume route to compile under a fully loaded CI runner. MCP_PAUSED_SESSION_IDLE_TIMEOUT_MS: "30000" diff --git a/e2e/setup/mcp-session-timeouts.ts b/e2e/setup/mcp-session-timeouts.ts index 3cf2846435..4e2acb05bc 100644 --- a/e2e/setup/mcp-session-timeouts.ts +++ b/e2e/setup/mcp-session-timeouts.ts @@ -1,4 +1,8 @@ -const DEFAULT_E2E_MCP_SESSION_TIMEOUT_MS = 3_000; +// Expiry coverage waits on this, so it stays far below production's five +// minutes. Its floor is the cap-eviction scenario: it opens sessions one at a +// time and needs cap + 1 of them resident at once, so that many opens must +// finish inside this window (see resident-runtime-cap.ts). +const DEFAULT_E2E_MCP_SESSION_TIMEOUT_MS = 8_000; // Keep expiry coverage fast while leaving enough room for a cold browser route // to compile under CI contention. Production allows nine minutes. const DEFAULT_E2E_MCP_PAUSED_SESSION_IDLE_TIMEOUT_MS = 30_000; diff --git a/e2e/setup/resident-runtime-cap.ts b/e2e/setup/resident-runtime-cap.ts index 6e3d8223f0..b84e17b591 100644 --- a/e2e/setup/resident-runtime-cap.ts +++ b/e2e/setup/resident-runtime-cap.ts @@ -18,4 +18,12 @@ // expect), that is not a correctness bug — eviction is designed to be // transparent, restoring on the next call — but it means this constant needs // to grow: raise it here, never by special-casing a scenario against it. +// +// The idle timeout bounds it from the other side. The scenario opens sessions +// one at a time while each one idles out MCP_SESSION_TIMEOUT_MS after it opened, +// so cap + 1 opens must finish inside that window or residency never reaches +// the cap. An open costs about 80-125ms on a CI runner, and more on slower +// machines: 25 opens took the whole of the old 3s window, and the scenario +// failed whenever they ran over. Growing this constant means growing that +// timeout too (mcp-session-timeouts.ts and the cloud shard env in ci.yml). export const E2E_MCP_RESIDENT_RUNTIME_SOFT_CAP = 24;