Skip to content

test(storage): cap macOS isolate worker churn to avoid Bun segfault - #849

Open
Wibias wants to merge 28 commits into
lidge-jun:devfrom
Wibias:fix/macos-isolate-worker-segfault
Open

test(storage): cap macOS isolate worker churn to avoid Bun segfault#849
Wibias wants to merge 28 commits into
lidge-jun:devfrom
Wibias:fix/macos-isolate-worker-segfault

Conversation

@Wibias

@Wibias Wibias commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Test plan

  • bun test ./tests/storage-worker-teardown-isolate.test.ts (4 pass on Windows)
  • CI macos-latest green with bun test --isolate tests
  • Confirm Linux/Windows legs stay green

Summary by CodeRabbit

  • Bug Fixes

    • Improved storage worker shutdown reliability on Windows and macOS.
    • Prevented late timeout errors when workers close during operating-system settling.
    • Ensured background processes and queued OAuth operations remain active until completion.
    • Improved resilience when directory synchronization encounters filesystem errors.
    • Refined configuration and authentication timeout handling on Windows.
  • Tests

    • Expanded lifecycle, shutdown, OAuth, and platform-specific coverage.
    • Improved stability for slower Windows and macOS environments.

Two spawn/reset cycles still tripped Bun 1.3.14 on macOS Silicon CI after a green suite with balanced worker counts (exit 133). Keep one-cycle proof on darwin, drain between cycles, and settle briefly before the isolate file boundary.
@github-actions github-actions Bot added the chore Maintenance, CI, tests, refactors, or build changes (not a user-facing bug or feature). label Aug 1, 2026
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Worker termination now handles Windows and macOS OS-join delays. Storage worker tests add draining, platform-specific churn limits, macOS skips, and regression coverage. Timer handling, filesystem synchronization, OAuth queue tests, ACL tests, and slow-environment timeouts also change.

Changes

Worker teardown and platform test behavior

Layer / File(s) Summary
OS-join teardown handling
src/storage/worker-lifecycle.ts
Termination clears its timeout before the Windows or macOS OS-join settle. Timeout errors are evaluated after the settle.
Lifecycle cleanup regression coverage
tests/storage-worker-lifecycle.test.ts
Tests drain workers after each test and verify that an early close event does not cause a late timeout or leave registered workers.
Platform-specific isolate tests
tests/storage-worker-teardown-isolate.test.ts
Tests skip unsupported macOS worker-spawn cases, use platform-specific churn counts, drain workers, and validate the platform cap.

Process lifetime and storage robustness

Layer / File(s) Summary
Referenced shutdown and mutation timers
src/adapters/cursor/native-exec-shell.ts, src/oauth/store.ts, tests/shutdown-drain.test.ts
Termination and mutation wait timers remain referenced while operations settle. The shutdown timer fixture preserves a referenced timer.
Filesystem timeout and synchronization handling
src/config.ts, tests/config.test.ts, src/responses/spill-store.ts
Config directory hardening uses a dedicated timeout key. Directory fsync failures remain best-effort and record the sync event.

Test environment timing and authentication setup

Layer / File(s) Summary
Platform-specific test timeout allowances
tests/codex-catalog-restore.test.ts, tests/subagent-model-fallback.test.ts
Catalog restore tests use 15-second timeouts. Subagent fallback tests use 30-second default and hook timeouts.
OAuth mutation queue test control
tests/oauth-store-multi.test.ts
Queue tests use shared timeout budgets, guaranteed cleanup, and an internal deadline race for rejection and queue-drain assertions.
Management authentication timeout tests
tests/server-management-auth.test.ts
ACL timeout tests use synchronous initialization checks and distinguish token-file timeouts from successful directory hardening.
CI retrigger documentation
.github/workflows/ci.yml
The workflow documents a CI retrigger after OAuth admission timeout hardening.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: ingwannu, lidge-jun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: limiting macOS storage worker churn to mitigate Bun segfaults.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch fix/macos-isolate-worker-segfault
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

Churn caps and afterAll settle still left macos-latest red with exit 133 after
storage-worker-teardown passed (balanced worker counts). Run the same suite
without --isolate on macOS; keep isolate on Linux/Windows.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/ci-workflows.test.ts`:
- Around line 45-49: Update the workflow assertions in the test around the
workflow string so each platform condition is matched together with its
corresponding run command within the same step block. Verify the macOS step
contains runner.os == 'macOS' and bun test tests, while the non-macOS step
contains runner.os != 'macOS' and bun test --isolate tests; replace the
independent contains/regex checks rather than adding separate assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 03bc93fc-e97a-4105-953e-8b666404657a

📥 Commits

Reviewing files that changed from the base of the PR and between 58ed4c8 and 871e96f.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • tests/ci-workflows.test.ts
  • tests/storage-worker-teardown-isolate.test.ts

Comment thread tests/ci-workflows.test.ts Outdated
@Wibias
Wibias marked this pull request as draft August 1, 2026 10:23
afterAll settle never ran when Bun 1.3.14 segfaulted mid-file on macOS CI.
Apply the same post-close OS-join gap as Windows, and drain+settle in afterEach.
@Wibias
Wibias marked this pull request as ready for review August 1, 2026 10:37
Independent contains/regex checks could pass a malformed workflow that
splits the OS guard from the run command.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be8110ea1e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/ci.yml Outdated
Comment thread src/storage/worker-lifecycle.ts
Wibias added 6 commits August 1, 2026 13:02
Windows GHA hit the default 5s budget at ~5.4s on bun --eval restore;
give the file's spawnSync cases 15s so load variance is not a fail.
Non-isolate macOS CI hung past the 20-minute job ceiling. Restore isolate for
all platforms, skip Worker-spawning teardown cases on darwin (Bun 1.3.14
balanced-count segfault), and keep the platform-cap meta-test.
A close that wins near timeoutMs could still throw after the 250ms settle
because the timer stayed armed across the sleep. Clear it first; add a
regression for the close-wins case.
Credential install in beforeEach can exceed the default 5s hook budget under
isolate on a loaded windows-latest runner (NTFS ACL harden stalls).
Retrigger Cross-platform CI after the suite-budget bump landed without a
pull_request workflow run on the fork tip.
Keep darwin OS-join settle regression plus zero-leak reservation coverage from tip.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/storage-worker-teardown-isolate.test.ts (1)

140-151: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the platform-cap assertion independent.

The supplied context omits Lines [140-151]. If the test computes its expected value with the same platform conditional as workerChurnCyclesForIsolate, it can pass while the helper is wrong.

Assert the explicit 8, 1, and 2 cases through an injectable platform input or a table-driven helper.

This request is based on the selected context omitting the new assertion at Lines [140-151].

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/storage-worker-teardown-isolate.test.ts` around lines 140 - 151, The
isolate worker churn test currently derives expected values from the same
platform conditional as workerChurnCyclesForIsolate, so it cannot detect helper
errors. Refactor the assertion around workerChurnCyclesForIsolate to accept an
injectable platform or use a table-driven helper, then explicitly verify win32
returns 8, darwin returns 1, and other platforms return 2.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/storage-worker-lifecycle.test.ts`:
- Around line 127-129: In the test setup around registerStorageWorker, assert
before calling terminateStorageWorker that the worker was registered and that a
close listener was attached. Keep these precondition checks ahead of termination
so the test cannot pass through the unregistered-worker fast path and continues
covering the timeout and OS-join settlement behavior.

---

Outside diff comments:
In `@tests/storage-worker-teardown-isolate.test.ts`:
- Around line 140-151: The isolate worker churn test currently derives expected
values from the same platform conditional as workerChurnCyclesForIsolate, so it
cannot detect helper errors. Refactor the assertion around
workerChurnCyclesForIsolate to accept an injectable platform or use a
table-driven helper, then explicitly verify win32 returns 8, darwin returns 1,
and other platforms return 2.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9db173d2-148e-41e3-982d-305aa10a53c3

📥 Commits

Reviewing files that changed from the base of the PR and between 871e96f and 1029e37.

📒 Files selected for processing (5)
  • src/storage/worker-lifecycle.ts
  • tests/codex-catalog-restore.test.ts
  • tests/storage-worker-lifecycle.test.ts
  • tests/storage-worker-teardown-isolate.test.ts
  • tests/subagent-model-fallback.test.ts

Comment thread tests/storage-worker-lifecycle.test.ts
Wibias added 10 commits August 1, 2026 13:57
…gate

The 128-slot busy-reject case timed out at 5s on Windows isolate and left the
first gate closed, hanging the file until the 20-minute job ceiling.
Without live-count and listener preconditions, an unregistered fast path
could pass the case without exercising the OS-join settle timer race.
tests-only pushes after the merge stopped scheduling pull_request CI; touch
the workflow path filter so the oauth admission timeout harden is verified.
Combine tip's try/finally drain with the shared Windows store case budget.
unref'd queue wait timeouts stalled oauth-store-multi after the 128-slot
admission case on windows-latest (no further output until the 20m job kill).
Directory fsync throws on Windows before the test recorder ran, so ordering
assertions missed the sync step even though open and the attempt succeeded.
Spawn cases are skipIf(darwin), so afterEach/afterAll Bun.sleep(250) added
latency without covering worker churn. OS-join settle stays in worker-lifecycle.
Windows CI hung in shutdown-drain after the oauth wait-timer fix: unref'd
grace waiters never fire under bun test --isolate, so drainAndShutdown
stalls until the 20m job ceiling.
Preserve ref'd serializeMutation wait timers and STORE_BUDGET_MS oauth
admission budgets over upstream's test-only keepalive workaround.
On windows-latest, a required management-dir timeout memo blocked config
mutation harden in startServer. Isolate the config-mutation timeout key and
keep the directory-timeout case as an init probe (HTTP 503 covered elsewhere).
saveConfig now passes a distinct timeoutMemoKey so management-dir timeouts cannot poison config mutation; update the win32 spy assertion to match.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/responses/spill-store.ts`:
- Around line 87-97: Add a focused Bun regression test near the existing
spill-store subsystem tests covering the directory-fsync failure path: configure
spillIoForTest.fsync to throw, verify "dir-fsync" is still recorded, and assert
the opened descriptor is closed. Also retain a separate assertion that an
openSync failure does not record "dir-fsync".

In `@tests/oauth-store-multi.test.ts`:
- Around line 315-327: Replace the pending Bun.sleep deadline in the
Promise.race around timedOut with a setTimeout-backed promise, retain its timer
handle, and clear it in a nested finally that always runs when the race settles.
Preserve the existing OAuthMutationBusyError assertion and deadline failure
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7d7b5625-092d-4238-89a9-849bd376cbbb

📥 Commits

Reviewing files that changed from the base of the PR and between 81a010e and 14a73cf.

📒 Files selected for processing (11)
  • .github/workflows/ci.yml
  • src/adapters/cursor/native-exec-shell.ts
  • src/config.ts
  • src/oauth/store.ts
  • src/responses/spill-store.ts
  • tests/config.test.ts
  • tests/oauth-store-multi.test.ts
  • tests/server-management-auth.test.ts
  • tests/shutdown-drain.test.ts
  • tests/storage-worker-lifecycle.test.ts
  • tests/storage-worker-teardown-isolate.test.ts

Comment thread src/responses/spill-store.ts Outdated
Comment thread tests/oauth-store-multi.test.ts Outdated
lidge-jun added a commit that referenced this pull request Aug 1, 2026
…e churn

Cherry-picked from #849 (Wibias) onto current dev. That PR carries 21
commits against a base four commits behind and conflicts in four files
that dev has since fixed independently — the two files here are the part
dev still lacks, so they land directly rather than dragging a stale
merge through.

Bun 1.3.14 has a second Worker-reclaim failure mode beyond the Windows
unbalanced-join panic: a segfault with a *balanced*
workers_spawned === workers_terminated count, seen as exit 132/133 on
both ubuntu and macOS Silicon under `bun test --isolate`. It crashes the
whole run after green assertions, so every PR touching nothing related
goes red.

Two changes. `worker-lifecycle` now runs the post-close OS-join settle on
darwin as well as win32, and disarms the terminate timeout before that
settle so a late timer cannot report a false timeout after close already
won. The isolate test caps spawn churn per platform (win32 8, linux 2,
darwin 1) and skips the Worker-spawning cases on darwin, where even one
cycle tripped the runtime; a meta-test keeps the caps themselves covered
so the skip cannot silently rot.

Co-authored-by: Wibias <Wibias@users.noreply.github.com>
Wibias added 5 commits August 1, 2026 16:18
Add focused spill-store seams/tests for throwing directory fsync and open failure, and clear the oauth wait-timeout race deadline so Bun.sleep cannot keep an isolate alive after settle.
Recent tip pushes only ran pull_request_target checks; touch the workflow comment so the path filter definitely re-evaluates.
Conflicted tip blocked GitHub's pull_request merge ref, so only pull_request_target checks ran. Keep config-mutation ACL timeoutMemoKey, directory fsync seams, and ref'd shell-grace timers on top of upstream's Windows runner/ACL harden.
Keep upstream's scoped ACL timeout fake for env management auth; config-mutation directory harden soft-fails that timeout so startServer still boots.
@Wibias

Wibias commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author

[shipping-github] Verdict: approve-comment

PR: #849 — test(storage): cap macOS isolate worker churn to avoid Bun segfault
Head: a7cb0337 on dev (mergeStateStatus: CLEAN)
Linked: none

Usefulness

Yes. Bun 1.3.14 under bun test --isolate was exiting 133 on macOS Silicon after storage Worker suites (balanced spawn/terminate). The tip keeps --isolate on all CI platforms, skips the darwin Worker hammer cases that trigger the runtime crash, and settles the OS Worker join on darwin/win32 so teardown does not race the next isolate file.

Bugs / correctness

  • Method: bug-review.md — Bugbot: earlier clean on this PR; complementary lenses done earlier in-session
  • Findings: none blocking on tip
  • Fixed this session: stale saveConfig spy after timeoutMemoKey (14a73cf6); CodeRabbit dir-fsync / oauth race-deadline follow-ups (34a1ac46); repeated dev merges so the pull_request merge ref stayed creatable (54aa3ed4, c12838fe, a7cb0337)

Security

  • Scope reviewed: CI/test lifecycle, Windows ACL harden paths used by management auth / config mutation, OAuth mutation wait timers
  • Findings: none confirmed
  • Fixed this session: none security-specific (ACL timeout memo / soft-fail are reliability hardens, not auth bypasses)

Spec / standards

  • Spec source: PR body (macOS isolate segfault / keep isolate where possible)
  • Gaps: none vs claimed tip strategy; darwin hammer cases are skipIf(darwin) while platform-cap meta coverage and OS-join settle remain

Reviews

  • Owners/maintainers: none open
  • Bots: CodeRabbit + Codex threads cleared (step-bound CI assertions, close-wins preconditions, dir-fsync coverage, oauth deadline clear). Unrelated Bugbot note on enforce-pr-target.yml is outside this PR’s diff.

Base / CI

  • Behind/conflicts: clean on dev@63735af4 after merge a7cb0337
  • Required checks: green — ubuntu / windows / macos (+ select windows runner, npm-global, enforce-target, label, react-doctor)
  • Local tip: bun run typecheck clean; focused storage/config regressions green
  • Simplify (user approved all): applied earlier — aacbf895 dropped unused darwin settle sleeps in teardown isolate; OS-join settle kept in worker-lifecycle
  • ship-gate.mjs … --mutation-mode maintainer: ready on a7cb0337

Gate

none

Bottom line

Ship-ready. Tip keeps Cross-platform --isolate while avoiding the Bun darwin Worker segfault, and the Windows ACL / oauth / spill follow-ups needed for a green tip are in. Not merged — say if you want merge.

@Wibias

Wibias commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author

[shipping-github] Merge ready

PR: #849 — test(storage): cap macOS isolate worker churn to avoid Bun segfault
Head: a7cb0337dev (mergeStateStatus: CLEAN)
Linked issues: none

Reviews

  • Humans (owners first): none open
  • Bots: 0 unresolved useful threads
  • Own bug + security + spec/standards: clean on tip; no confirmed security issues

Tip freshness

  • Updated from dev: yes (a7cb0337)
  • Compiles/tests against tip: bun run typecheck + focused storage/config tests pass
  • Conflicts: none

Checks

  • Required CI: green on a7cb0337
  • ship-gate: ready (maintainer)
  • Policy: advisory CODEOWNERS clear; no draft/WIP gate

Residual

none for merge bar

Ready to merge.

Wibias added 2 commits August 1, 2026 22:26
Resolve oauth wait-timer, oauth-store-multi deadline, and management-auth ACL stub conflicts on top of the landed storage-worker isolate beforeEach work.
The failBeforeStateCommit + failSatelliteRestore path measured ~10s on windows-latest and tripped Bun's default 5s harness timeout.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Maintenance, CI, tests, refactors, or build changes (not a user-facing bug or feature).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant