From 5933b1821aaf9e79be1bcf86714f64f30f1cdc79 Mon Sep 17 00:00:00 2001 From: ualtinok <94532+ualtinok@users.noreply.github.com> Date: Tue, 20 Oct 2026 22:53:10 +0200 Subject: [PATCH] mason: drain quota publications before failed-storage fixture swap The explicit quota refresh returns before native quota publication finishes. recordQuota's atomic config rename can recreate the pool JSON between the helper's rm and mkdir. Join startup work and the existing scoped runtime quota-publication drain while keeping the plugin live and the sidebar read blocked. Unchanged base reproduced EEXIST in 2/200 four-way Linux invocations. The identical fixed loop had 0 EEXIST, but shared-runner RPC/deadline failures affected 27/200 invocations; the fixed serial loop had one pre-swap RPC failure in 100 invocations. A controlled held-rename probe passed both helper branches and confirmed EISDIR after the swap. Bun 1.3.14; OpenCode typecheck passed with TypeScript 7.0.2. No assertions, deadlines or production behavior changed. --- packages/opencode/src/tests/index.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/opencode/src/tests/index.test.ts b/packages/opencode/src/tests/index.test.ts index 9dbd9eb6..cd708bca 100644 --- a/packages/opencode/src/tests/index.test.ts +++ b/packages/opencode/src/tests/index.test.ts @@ -7623,6 +7623,7 @@ describe('auth.loader', () => { // Establish the plugin's actual route before testing a quota-only write. const response = await loaded.fetch(MESSAGES_URL, EMPTY_POST) expect(response.status).toBe(200) + await plugin.__fallbackRefreshReady await drainSidebarWrites() expect((await getSidebarState()).activeId).toBe('fallback-1') if (clearExistingRouting) { @@ -7663,6 +7664,9 @@ describe('auth.loader', () => { actionId: 'quota-refresh', }) expect(refreshed.ok).toBe(true) + // Quota polls return before publishing to the pool config. Drain those + // writes so a pending rename cannot recreate the file during the swap. + await plugin.__scopedRuntime.drainQuotaPublications() // Replace the shared pool config JSON file with a directory so later // account reads fail instead of returning an outdated snapshot. const accountFile = migratedPool?.paths.config