88 *
99 * A second Bun 1.3.14 failure mode is a mid-file / post-suite segfault with a
1010 * *balanced* `workers_spawned === workers_terminated` count (exit 133 /
11- * Trace/BPT on macOS Silicon). Churn caps and afterAll settle were not enough
12- * under GHA load; running macOS CI *without* `--isolate` hung the suite past
13- * the 20-minute job ceiling. Keep isolate everywhere, skip Worker-spawning
14- * cases on darwin (platform-cap meta-test still runs), and keep OS-join settle
15- * in `worker-lifecycle` plus drain+settle in `afterEach` for local isolate runs.
11+ * Trace/BPT on macOS Silicon). Churn caps alone were not enough under GHA load;
12+ * running macOS CI *without* `--isolate` hung past the 20-minute job ceiling.
13+ * Keep isolate everywhere, skip Worker-spawning cases on darwin (platform-cap
14+ * meta-test still runs), and keep OS-join settle in `worker-lifecycle`.
1615 *
1716 * These cases hammer the exact failure window: fire-and-forget terminate must
1817 * still be joinable by drain, and repeated spawn → reset cycles must leave the
@@ -41,20 +40,21 @@ let testDir = "";
4140let previousHome : string | undefined ;
4241
4342/**
44- * Bun 1.3.14: Worker spawn in this file still segfaults the isolate process
45- * after green assertions (balanced counts) on macOS Silicon and ubuntu-latest
46- * (exit 133 / 132). Skip the hammer cases there ; win32 keeps full coverage.
43+ * Bun 1.3.14 macOS Silicon : Worker spawn in this file still segfaults the
44+ * isolate process after green assertions (balanced counts). Skip the hammer
45+ * cases on darwin ; win32/linux keep full coverage.
4746 */
48- const skipIsolateWorkerSpawn =
49- process . platform === "darwin" || process . platform === "linux" ;
47+ const skipDarwinWorkerSpawn = process . platform === "darwin" ;
5048
5149/** Spawn/reset iterations for the heavy churn case — platform-stressed carefully. */
5250function workerChurnCyclesForIsolate ( ) : number {
5351 if ( process . platform === "win32" ) return 8 ;
54- // Two cycles still segfaulted Bun 1.3.14 on macOS Silicon and ubuntu-latest
55- // under `--isolate` after a green suite (balanced worker counts). One cycle
56- // keeps a real spawn/reset proof without the churn that trips the runtime.
57- return 1 ;
52+ // Two cycles still segfaulted Bun 1.3.14 on macOS Silicon under `--isolate`
53+ // after a green suite (balanced worker counts, exit 133). One cycle keeps a
54+ // real spawn/reset proof without the churn that trips the runtime.
55+ if ( process . platform === "darwin" ) return 1 ;
56+ // Linux: short loop — eight cycles segfaulted with balanced counts on ubuntu CI.
57+ return 2 ;
5858}
5959
6060function seedArchived ( codexHome : string ) : void {
@@ -77,9 +77,6 @@ afterEach(async () => {
7777 await resetStorageCleanupPolicyJobForTestsAsync ( ) ;
7878 setStorageCleanupPolicyJobTestHooks ( null ) ;
7979 await drainStorageWorkers ( ) ;
80- // Bun 1.3.14: balanced-count segfault can hit mid-file (before afterAll) on
81- // macOS Silicon and ubuntu-latest. Brief settle — not a CI timeout bump.
82- if ( process . platform !== "win32" ) await Bun . sleep ( 250 ) ;
8380 if ( previousHome === undefined ) delete process . env . OPENCODEX_HOME ;
8481 else process . env . OPENCODEX_HOME = previousHome ;
8582 isolatedCodexHome ?. restore ( ) ;
@@ -90,7 +87,6 @@ afterEach(async () => {
9087
9188afterAll ( async ( ) => {
9289 await drainStorageWorkers ( ) ;
93- if ( process . platform !== "win32" ) await Bun . sleep ( 250 ) ;
9490} ) ;
9591
9692async function waitForLiveWorker ( timeoutMs = 10_000 ) : Promise < void > {
@@ -102,7 +98,7 @@ async function waitForLiveWorker(timeoutMs = 10_000): Promise<void> {
10298 throw new Error ( "no storage worker was ever spawned; this test would prove nothing" ) ;
10399}
104100
105- test . skipIf ( skipIsolateWorkerSpawn ) ( "drain joins a fire-and-forget terminate before the isolate boundary" , async ( ) => {
101+ test . skipIf ( skipDarwinWorkerSpawn ) ( "drain joins a fire-and-forget terminate before the isolate boundary" , async ( ) => {
106102 // Reproduces the old race: sync reset void-terminates (and used to deregister
107103 // immediately), then drain returned on an empty set while the thread exited.
108104 setStorageCleanupPolicyJobTestHooks ( { blockMs : 800 } ) ;
@@ -120,7 +116,7 @@ test.skipIf(skipIsolateWorkerSpawn)("drain joins a fire-and-forget terminate bef
120116 expect ( liveStorageWorkerCount ( ) ) . toBe ( 0 ) ;
121117} , { timeout : 30_000 } ) ;
122118
123- test . skipIf ( skipIsolateWorkerSpawn ) ( "repeated Windows-style spawn/reset cycles leave no live workers" , async ( ) => {
119+ test . skipIf ( skipDarwinWorkerSpawn ) ( "repeated Windows-style spawn/reset cycles leave no live workers" , async ( ) => {
124120 const cycles = workerChurnCyclesForIsolate ( ) ;
125121 for ( let i = 0 ; i < cycles ; i ++ ) {
126122 // Fresh CODEX_HOME each cycle so a prior worker's SQLite handle cannot
@@ -144,10 +140,11 @@ test.skipIf(skipIsolateWorkerSpawn)("repeated Windows-style spawn/reset cycles l
144140test ( "isolate worker churn stays platform-capped" , ( ) => {
145141 const cycles = workerChurnCyclesForIsolate ( ) ;
146142 if ( process . platform === "win32" ) expect ( cycles ) . toBe ( 8 ) ;
147- else expect ( cycles ) . toBe ( 1 ) ;
143+ else if ( process . platform === "darwin" ) expect ( cycles ) . toBe ( 1 ) ;
144+ else expect ( cycles ) . toBe ( 2 ) ;
148145} ) ;
149146
150- test . skipIf ( skipIsolateWorkerSpawn ) ( "terminateStorageWorker is joinable and idempotent across callers" , async ( ) => {
147+ test . skipIf ( skipDarwinWorkerSpawn ) ( "terminateStorageWorker is joinable and idempotent across callers" , async ( ) => {
151148 setStorageCleanupPolicyJobTestHooks ( { blockMs : 500 } ) ;
152149 seedArchived ( isolatedCodexHome ! . path ) ;
153150 const started = requestStorageCleanupPolicyRun ( {
0 commit comments