feat(wxc_common): add the sandbox execution interfaces (SandboxBackend / SandboxProcess / Runner)#554
Merged
Merged
Conversation
…d / SandboxProcess / Runner)
Introduce the shared, no-pty execution surface that the containment backends
and a future in-process library build on. Purely additive: no existing code
path uses these yet, so behavior is unchanged.
- `SandboxProcess` — a handle to a running sandboxed child: `take_stdin` /
`take_stdout` / `take_stderr`, `try_wait`, `id`, `kill` (process-tree), and
`wait` (drains any untaken stdio, honors `scriptTimeout`), plus stdout/stderr
closers for abandoning a backgrounded-descendant-held read without a kill.
- `SandboxBackend` — `validate` + `spawn(request, logger, StdioMode) ->
SandboxProcess` + a `diagnose_exit` hook; `StdioMode::{Pipes, Inherit}`.
- `Runner<B>` — the generic adapter bridging any `SandboxBackend` to the
run-to-completion `ScriptRunner` (spawn `Inherit`, then `wait`).
- `StreamCloser`, `group_kill` (Unix leader-first SIGKILL of the child's group),
and `wait_with_timeout` (adaptive 1ms->50ms backoff poll).
- `interruptible_reader` (Unix self-pipe + `poll`) and the Windows pipe helpers
in `process_util` (`InterruptiblePipeReader` / `PipeReadCanceller` /
`create_std_pipes`) for out-of-band-cancelable streaming reads.
- `FailurePhase::Timeout` so a timeout is distinguishable from other failures.
The library backends and executor binaries are migrated onto this surface in a
follow-up PR, and the importable `mxc-sdk` crate is built on top of it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
Merged
7 tasks
This was referenced Jun 24, 2026
Closed
Contributor
There was a problem hiding this comment.
Pull request overview
Adds new cross-backend, handle-based (“streaming”) sandbox execution interfaces to wxc_common as the foundational API layer for follow-up backend unification and the forthcoming mxc-sdk Rust library crate. This is additive scaffolding intended to enable spawning and controlling sandboxed processes without a PTY.
Changes:
- Introduces
SandboxProcess/SandboxBackendtraits plus a genericRunner<B>adapter to bridge to the existingScriptRunnerrun-to-completion model. - Adds Unix + Windows primitives for interruptible pipe reads/stdio handling (self-pipe+
pollon Unix;CancelIoEx-based cancellation for Windows pipes). - Extends
FailurePhasewith a dedicatedTimeoutphase and widenswxc_common’slibcdependency to all Unix targets.
Show a summary per file
| File | Description |
|---|---|
| src/core/wxc_common/src/sandbox_process.rs | New public streaming execution traits/utilities and Runner<B> bridge, including Unix timeout polling and group kill helper. |
| src/core/wxc_common/src/process_util.rs | Adds Windows pipe reader/writer types and an interruptible reader + StreamCloser implementation via CancelIoEx. |
| src/core/wxc_common/src/models.rs | Adds FailurePhase::Timeout to distinguish timeout termination from normal non-zero exits. |
| src/core/wxc_common/src/lib.rs | Wires new modules into the crate (sandbox_process, interruptible_reader) with appropriate platform gating. |
| src/core/wxc_common/src/interruptible_reader.rs | New Unix interruptible reader using self-pipe + poll and a StreamCloser canceller. |
| src/core/wxc_common/Cargo.toml | Expands libc dependency from Linux-only to all Unix targets to support new Unix-only modules/helpers. |
Copilot's findings
- Files reviewed: 6/6 changed files
- Comments generated: 3
Comment on lines
+209
to
+210
| /// [`wait`](SandboxProcess::wait), first cancelling its read so the join can't | ||
| /// block. When the stream was drained (a [`spawn_discard`] thread exists), fire |
Comment on lines
+248
to
+253
| // SAFETY: `kill(2)` with a plain pid / negative pgid — just integers. | ||
| unsafe { | ||
| libc::kill(pid, libc::SIGKILL); // leader first | ||
| libc::kill(-pid, libc::SIGKILL); // then its group | ||
| } | ||
| Ok(()) |
Comment on lines
+405
to
+410
| Err(e) if e.kind() == std::io::ErrorKind::TimedOut => ScriptResponse { | ||
| exit_code: -1, | ||
| error_message: format!("script timed out after {}ms", request.script_timeout), | ||
| failure_phase: FailurePhase::Timeout, | ||
| ..Default::default() | ||
| }, |
MGudgin
approved these changes
Jun 24, 2026
MGudgin
pushed a commit
that referenced
this pull request
Jun 24, 2026
This change adapts the Phase 2B strict-wire-model parser to two crates that landed on main after 2B was branched, surfaced when rebasing 2B onto current main: the new in-process `mxc-sdk` library crate (#556) and the `load_request_from_value` entrypoint (#554/#556). Details: - config_parser.rs: port `load_request_from_value` (added on main against the deleted `RawConfig` API) to 2B's wire model — deserialize into `wire::MxcConfig` and call `convert_wire_config`, matching its sibling `load_request_with_options`. - core/mxc-sdk/src/policy.rs: stop emitting `processContainer.name` (the wire `ProcessContainer` is strict and has no `name` field; the id is already carried at top-level `containerId`). Suppress the now-unused `container_id` in the Windows block. - sdk/src/sandbox.ts: likewise stop emitting `processContainer.name`; drop the now-unused `containerId` parameter from `buildProcessBaseContainerConfig`. Tests: - cargo test --workspace -> all pass (the 6 mxc-sdk parse failures from the rejected `name` field are resolved). - cargo fmt --check + cargo clippy --workspace -D warnings -> clean. - schema codegen + corpus (169/169) + schema-version gates -> green. - cd sdk && npm test -> 183 pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Generated-with: claude-opus-4.8
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
Part 1 of 3 splitting #524 ("mxc-sdk lib crate") into reviewable, compile-ordered PRs. This PR adds the shared, no-pty sandbox execution interfaces to
wxc_commonthat the containment backends and the new library crate build on. It is purely additive — no existing code path uses these yet, so behavior is unchanged.SandboxProcess— a handle to a running sandboxed child:take_stdin/take_stdout/take_stderr,try_wait,id,kill(process-tree), andwait(drains untaken stdio, honorsscriptTimeout), plus stdout/stderr closers for abandoning a backgrounded-descendant-held read without a kill.SandboxBackend—validate+spawn(request, logger, StdioMode) -> SandboxProcess+ adiagnose_exithook;StdioMode::{Pipes, Inherit}.Runner<B>— the generic adapter bridging anySandboxBackendto the run-to-completionScriptRunner(spawnInherit, thenwait).StreamCloser,group_kill(Unix leader-firstSIGKILLof the child's group), andwait_with_timeout(adaptive 1ms→50ms backoff poll).interruptible_reader(Unix self-pipe +poll) and the Windows pipe helpers inprocess_utilfor out-of-band-cancelable streaming reads.FailurePhase::Timeoutso a timeout is distinguishable from other failures.🔗 References
unify-backends), and the importablemxc-sdkcrate lands in Part 3 (mxc-sdk). Review in that order.🔍 Validation
cargo test -p wxc_common(macOS, toolchain 1.93): 268 pass.cargo fmt --all -- --checkandcargo clippy --all-targets -- -D warningsclean.cargo checkagainstx86_64-pc-windows-msvcandx86_64-unknown-linux-gnu; macOS consumer crates (seatbelt_common,mxc_darwin,mxc_pty) build unchanged (additive-safe).✅ Checklist
📋 Issue Type
Microsoft Reviewers: Open in CodeFlow