Skip to content

Orca v0.2.19

Choose a tag to compare

@github-actions github-actions released this 12 Jul 03:11

Orca v0.2.19

Patch release: prevent macOS sandboxed test runners from leaving child worker
processes behind when their cleanup signal is denied.

Incident And Root Cause

During a persistent Goal, a sandboxed pnpm ... vitest run reached Tinypool's
worker cleanup path. Node's ChildProcess.kill failed with EPERM, and macOS
unified logging recorded the matching policy denial:

Sandbox: node(31412) deny(1) signal children [node(31426)] signum:15

Both Orca macOS Seatbelt profiles allowed a process to signal itself, but not
its own children. Vitest stopped after the failed cleanup operation while its
worker processes remained alive.

System Evidence

The macOS Jetsam snapshot taken during the freeze showed:

  • 10 leftover Node workers using 3.90-4.16 GiB each, 40.51 GiB in total
  • the Orca native process using about 30.2 MiB
  • the npm Node wrapper using about 11.8 MiB
  • node as the largest process class while the system was under compressor
    pressure

This was not an Orca transcript-heap leak. The saved Orca session was about
608 KiB, and the native process remained small in the system snapshot. The
evidence does not establish why each abandoned worker grew to roughly 4 GiB;
it establishes that the sandbox denied the parent's cleanup signal and that
the workers remained active afterward.

Changes

  • Descendant cleanup: workspace-write and read-only Seatbelt profiles now
    include (allow signal (target children)).
  • Real behavior coverage: both profiles execute a child process, send it
    SIGTERM, and wait for it to exit.
  • Security contract: tests reject broad signal grants and the
    target others / target same-sandbox scopes.
  • Goal documentation: the Goal guide now explains that Goal turns use the
    normal shell sandbox and the same child-process cleanup boundary.

Security Boundary

The new permission is lineage-scoped. A sandboxed command can signal itself
and its own descendants, which is the minimum required for worker-pool process
managers. It still cannot signal an unrelated process or a process that merely
shares the same sandbox.

Regression Boundary

The v0.2.17..v0.2.18 production diff did not change Seatbelt or shell process
handling, and the incident session did not use the unknown-tool recovery added
in v0.2.18. This was a pre-existing macOS sandbox policy defect exposed by a
long Goal workload, not a regression in v0.2.18's DeepSeek tool correction.

Compatibility

No changes to CLI flags, slash commands, approval modes, Goal records, history
formats, provider configuration, MCP configuration, npm package layout, Linux
behavior, or public APIs.

Verification

Focused validation:

cargo test -p orca-tools child_process -- --nocapture
cargo test -p orca-tools -- --test-threads=1
cargo clippy -p orca-tools --all-targets
cargo fmt --all -- --check
git diff --check

A controlled Node smoke also spawned a child Node process inside the repaired
profile, called ChildProcess.kill("SIGTERM"), and observed the child exit with
SIGTERM. A separately owned process remained protected with EPERM.

Full release gate before tagging:

cargo check --workspace --all-targets
cargo test --workspace --all-targets -- --test-threads=1
cargo clippy --workspace --all-targets
npm --prefix site run build
npm --prefix site run check:seo
node scripts/release/test-stage-npm.mjs
node scripts/release/test-verify-published.mjs

Post-publish verification:

node scripts/release/verify-published.mjs --version 0.2.19 --repo echoVic/blade-deepseek --package @blade-ai/orca --bin orca

Upgrade

Install or pin the release with:

npm install -g @blade-ai/orca@0.2.19

or:

curl -fsSL https://orcaagent.dev/install.sh | \
  INSTALL_DIR=/usr/local/bin ORCA_VERSION=0.2.19 sh