[Proposal] Use native stdio streams in the Node SDK - #1220
Closed
Branden Bonaby (bbonaby) wants to merge 4 commits into
Closed
Branden Bonaby (bbonaby) wants to merge 4 commits into
Branden Bonaby (bbonaby) wants to merge 4 commits into
Conversation
Move blocking stream, process-control, timeout, and state-aware execution work onto native threads and expose callback-driven completion through mxc_ffi. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bbe1ffbf-7cf8-48a0-8e3b-956f1d634e6c
Transfer caller-owned native pipe endpoints for the four pipe-backed streaming backends and expose them through the SDK and C ABI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bbe1ffbf-7cf8-48a0-8e3b-956f1d634e6c
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bbe1ffbf-7cf8-48a0-8e3b-956f1d634e6c
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bbe1ffbf-7cf8-48a0-8e3b-956f1d634e6c
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Copilot started reviewing on behalf of
Branden Bonaby (bbonaby)
September 19, 2026 00:40
View session
Collaborator
Author
|
Closing because this PR was opened prematurely without the user's authorization. The branch remains available for continued work. |
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Wrapper omissions break native streaming, stdin errors can incorrectly fail waits, and both npm lockfiles violate CI integrity rules.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 2
Open (7)
Regenerate package lockfile with public npm registry · New Regenerate integration lockfile with public npm registry · New Ignore normal stdin EPIPE during waitAsync · New Delegate take_native_stdio in OneShotSandboxProcess · New Delegate take_native_stdio in DaclGuardedProcess · New Delegate take_native_stdio in TelemetryProcess · New Delegate take_native_stdio in ProcessWithWarnings · New
What changed in this PR
Reworks Node SDK streaming to transfer native stdio handles while Rust retains process lifecycle control.
Changes:
- Adds native stdio ownership and lifecycle coordination across Rust, FFI, and Node.
- Adds streaming tests and raises the minimum Node.js version to 24.21.0.
- Updates documentation, dependencies, and CI environments.
| File | Description |
|---|---|
src/ffi/mxc_ffi/src/lib.rs |
Exposes event-loop streaming FFI. |
src/ffi/mxc_ffi/src/io_coordinator.rs |
Implements native lifecycle C APIs. |
src/ffi/mxc_ffi/Cargo.toml |
Adds engine dependency. |
src/ffi/mxc_ffi/build.rs |
Tracks the new FFI source. |
src/core/wxc_common/src/sandbox_process.rs |
Adds native stdio abstractions. |
src/core/wxc_common/src/process_util.rs |
Adds Windows handle duplication. |
src/core/wxc_common/src/interruptible_reader.rs |
Adds Unix descriptor duplication. |
src/core/wxc_common/src/exec_stream.rs |
Exposes exec native endpoints. |
src/core/mxc-sdk/src/sandbox.rs |
Forwards native stdio access. |
src/core/mxc_engine/src/lib.rs |
Exports and integrates coordination. |
src/core/mxc_engine/src/io_coordinator.rs |
Implements lifecycle coordination. |
src/core/mxc_engine/Cargo.toml |
Adds channel dependency. |
src/Cargo.toml |
Registers workspace dependency. |
src/Cargo.lock |
Updates Rust dependency resolution. |
src/backends/seatbelt/common/src/seatbelt_runner.rs |
Transfers Seatbelt endpoints. |
src/backends/process_container/common/src/dispatcher.rs |
Updates process wrapper delegation. |
src/backends/process_container/common/src/base_container_runner.rs |
Adds native handles and timeout state. |
src/backends/process_container/common/src/appcontainer_runner.rs |
Adds native handles and timeout state. |
src/backends/isolation_session/common/src/sandbox.rs |
Updates one-shot wrapper delegation. |
src/backends/bubblewrap/common/src/bwrap_runner.rs |
Transfers Bubblewrap endpoints. |
sdk/node/tests/unit/streaming-binding.test.ts |
Tests native binding ownership. |
sdk/node/tests/unit/sandbox-process.test.ts |
Tests lifecycle behavior. |
sdk/node/tests/integration/package.json |
Updates integration dependencies. |
sdk/node/tests/integration/package-lock.json |
Refreshes integration lock data. |
sdk/node/tests/integration/native-streaming.test.ts |
Adds native streaming integration coverage. |
sdk/node/src/sandbox-process.ts |
Implements Node process lifecycle API. |
sdk/node/src/bindings/streaming.ts |
Adopts native handles as streams. |
sdk/node/README.md |
Documents the Node requirement. |
sdk/node/package.json |
Raises the Node engine version. |
sdk/node/package-lock.json |
Refreshes SDK lock data. |
docs/isolation-session/state-aware-rust.md |
Documents state-aware streaming. |
docs/architecture.md |
Updates SDK and FFI architecture. |
.github/workflows/Versioning.Checks.Job.yml |
Updates versioning CI Node runtime. |
.github/workflows/SDK.Unit.Test.Job.yml |
Updates unit-test Node runtime. |
.github/workflows/SDK.Integration.Test.Job.yml |
Updates integration-test Node runtime. |
.github/workflows/Package.NpmSdk.Job.yml |
Updates packaging Node runtime. |
.github/workflows/Package.Lock.Check.Job.yml |
Updates lock-check Node runtime. |
.azure-pipelines/templates/SDK.Unit.Test.Job.yml |
Updates Azure unit-test runtime. |
.azure-pipelines/templates/SDK.Integration.Test.Job.yml |
Updates Azure integration runtime. |
.azure-pipelines/templates/Package.NpmSdk.Job.yml |
Updates Azure packaging runtime. |
.azure-pipelines/templates/Package.Lock.Check.Job.yml |
Updates Azure lock-check runtime. |
.azure-pipelines/templates/IsolationSession.TestBundle.Build.Job.yml |
Updates test-bundle Node runtime. |
Files not reviewed (2)
- sdk/node/package-lock.json: Generated file
- sdk/node/tests/integration/package-lock.json: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+380
to
+381
| "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/node/-/node-24.13.4.tgz", | ||
| "integrity": "sha1-5U90zq5oOL/1eoFLfTH1BCoPkHQ=", |
Comment on lines
+23
to
+24
| "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@koromix/koffi-android-arm64/-/koffi-android-arm64-3.2.1.tgz", | ||
| "integrity": "sha1-Lc55jTZp0re1bpwCqKaidKvWx8Y=", |
| this.rejectWait = reject; | ||
| }); | ||
| void this.waitPromise.catch(() => {}); | ||
| this.input?.on('error', (error) => void this.finish(undefined, asError(error))); |
Comment on lines
+315
to
+317
| fn stdin_closer(&self) -> Option<Box<dyn StreamCloser>> { | ||
| self.inner.stdin_closer() | ||
| } |
Comment on lines
+781
to
+783
| fn stdin_closer(&self) -> Option<Box<dyn wxc_common::sandbox_process::StreamCloser>> { | ||
| self.inner.stdin_closer() | ||
| } |
Comment on lines
+527
to
+529
| fn stdin_closer(&self) -> Option<Box<dyn wxc_common::sandbox_process::StreamCloser>> { | ||
| self.inner.stdin_closer() | ||
| } |
Comment on lines
+648
to
+650
| fn stdin_closer(&self) -> Option<Box<dyn wxc_common::sandbox_process::StreamCloser>> { | ||
| self.inner.stdin_closer() | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


📖 Description
Replace callback-driven byte coordination with direct native stdio ownership in the Node SDK. Rust retains process lifecycle control, while Node adopts Windows
HANDLEs throughwindowsHandleand Unix file descriptors throughnet.Socket.Streaming remains limited to process-backed backends that expose transferable native endpoints. The Node SDK now requires Node.js 24.21.0 or later.
🔗 References
🔍 Validation
cargo fmt --all -- --checkcargo check -p mxc_engine -p mxc_ffix86_64-unknown-linux-gnumxc_engineandmxc_ffilifecycle testsThe native streaming integration workload was not run on this development machine.
✅ Checklist
Cargo.lock, thedependency-feed-checkcheck passes (see docs/pull-requests.md)📋 Issue Type
Microsoft Reviewers: Open in CodeFlow