From 8f89c6023163091d2f55b089070f43c78f76b0bc Mon Sep 17 00:00:00 2001 From: ualtinok <94532+ualtinok@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:13:34 +0200 Subject: [PATCH] mason: release quota sync arrival wait during teardown The raw arrival signal can leave TestLifetime waiting on bodySettled after a test timeout, before fetch and environment restoration. Register arrival as a lifetime gate and stop the late body when teardown releases it without an interception. Keep all eight successful-path assertions and the 250 ms/20 ms deadlines unchanged. The original push-CI trigger was not naturally reproduced: 40 fresh processes each for the held-sync test and full quota-sweep file on a6efa386 and 026fe85c produced no held-sync failure. Repeat those matrices with this hardening also produced none (two unrelated full-file timeouts across 320 processes). A temporary missed-arrival control reproduced the 10s hook hang and downstream fetch/environment fallout while the request had already served 200 without joining a pool write. After hardening the same control reports only its original 5s body timeout; both follower tests pass. Production behavior is unchanged. Verified with pinned Bun 1.3.14 on linux,4c: Core build, OpenCode TypeScript 7.0.2 checks, four 80-process reproduction matrices, and final ordered held-sync/network-guard/API-lastUsed check (3 pass, 17 assertions). Investigation evidence and baseline failures are recorded in the uncommitted internal investigation artifact. --- packages/opencode/src/tests/quota-sweep.test.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/tests/quota-sweep.test.ts b/packages/opencode/src/tests/quota-sweep.test.ts index 71e65dfa..c1ad1d7c 100644 --- a/packages/opencode/src/tests/quota-sweep.test.ts +++ b/packages/opencode/src/tests/quota-sweep.test.ts @@ -881,7 +881,9 @@ test('quota poll serves its reading while runtime sync is held and dispose drain const f = await startBody({ quotaEnabled: false, fallbackUsed: 20 }) await f.startupSweep const held = lifetimes.gate() - const arrived = signal() + // A publication may never reach the spy. Release its arrival wait on teardown + // so a timed-out body can settle before the lifetime restores fetch and files. + const arrived = lifetimes.gate() const stallDeadline = () => new Promise((resolve) => setTimeout(() => resolve('blocked on sync'), 250), @@ -900,7 +902,7 @@ test('quota poll serves its reading while runtime sync is held and dispose drain staged.accounts[FALLBACK_ID]?.quotaErrorClearedAt ) { intercepted = true - arrived.resolve() + arrived.open() await held.wait } return sync() @@ -911,7 +913,10 @@ test('quota poll serves its reading while runtime sync is held and dispose drain ) lifetimes.deferCleanup(() => openSpy.mockRestore()) const request = f.request() - await arrived.promise + await arrived.wait + // Teardown also opens this gate after a timeout and stops the plugin. + // Do not continue into its account reads or requests without an interception. + if (!intercepted) return const result = await Promise.race([ request.then(() => 'served'), stallDeadline(),