Audience: MXC developers
Below is our guidance for how to report issues, propose new features, and submit contributions via Pull Requests (PRs).
The MXC team carries out development in the open. When the team finds issues we file them in this repository. When we propose new ideas or think up new features, we file new feature requests. When we work on fixes or features, we create branches and work on those improvements. And when PRs are reviewed, we review them in public.
The point of doing all this work in public is to ensure that we are holding ourselves to a high degree of transparency, and so that the community sees that we apply the same processes and hold ourselves to the same quality bar as we do to community-submitted issues and PRs.
The team triages new issues regularly. During triage, the team uses labels to categorize, manage, and drive the project workflow. Issues are categorized into one of four types — Bug, Feature, Documentation, or Task — and all new issues receive the Needs-Triage label until a team member has reviewed them.
If you file issues or create PRs, please keep an eye on your GitHub notifications. Issues and PRs that remain unanswered for several days after a request for information may be closed.
Repository administrators, maintainers, and writers can comment /investigate
on an issue to request an evidence-backed classification. The workflow posts one
public comment identifying the issue as a bug, documentation gap, or design
decision, with a recommended next step.
When the report lacks enough information to reach a classification, it explicitly mentions the issue author and requests reproduction steps, expected and actual behavior, MXC version, OS/build, and sanitized logs. It does not create a PR for that outcome.
For a small, unambiguous documentation or test-only change, it may also create one draft PR. It never merges, releases, assigns owners, changes labels, or updates an existing PR. It does not create PRs for production code, schemas, generated SDK files, containment behavior, CI, dependencies, versioning, or security-sensitive work.
Do not use /investigate for a security report. Follow
SECURITY.md instead.
Please do not report security vulnerabilities through public GitHub issues. Instead, please report them to the Microsoft Security Response Center (MSRC). See SECURITY.md for full details.
⚠️ When reporting BSODs or security issues, do not attach memory dumps, logs, or traces to GitHub issues. Send them tosecure@microsoft.comreferencing the GitHub issue. For application crashes, include a Feedback Hub link if possible.
Please follow this simple rule to help us eliminate any unnecessary wasted effort and ensure an efficient use of everyone's time:
👉 If you have a question, think you've discovered an issue, would like to propose a new feature, etc., then find or file an issue BEFORE starting work to fix or implement it.
Before filing a new issue, search existing open and closed issues. It is likely that someone else has found the problem you're seeing, and someone may be working on or have already contributed a fix.
If no existing item describes your issue or feature, please file a new one.
We provide four issue templates under .github/ISSUE_TEMPLATE/. Pick the one that matches your situation:
| Category | When to use | Template |
|---|---|---|
| 🐛 Bug Report | Something is broken or behaving unexpectedly | Bug_Report.yml |
| 🚀 Feature Request / Idea | A proposal for new functionality or an improvement | Feature_Request.yml |
| 📚 Documentation Issue | Docs are incorrect, incomplete, or confusing | Documentation_Issue.yml |
| 📋 Task | An actionable work item that doesn't fit the above | Task.yml |
Complete the information requested in the template. The more information you provide, the more likely your issue will be understood and addressed. Helpful information includes:
- The platform you're on (Windows / Linux / macOS) and architecture (x64 / ARM64).
- Which containment backend is involved.
- The MXC version or commit you're using.
- Detailed reproduction steps — what exact JSON config, command, or SDK call triggers the issue.
- Prefer pasted text (command output, error messages, JSON snippets) over screenshots.
- If you intend to implement the fix or feature yourself, say so in the issue! Otherwise we may pick it up or label it
Help-Wanted.
⚠️ Do not post "+1", "me too", or similar comments — they add noise to an issue.
If you're affected by an issue but don't have new information to add, upvote the original issue by hitting its 👍 reaction. That way we can measure impact.
For those willing to help fix issues or implement features:
Some issues are quick and simple to describe. Once a team member has agreed with your approach, skip ahead to "Fork, Clone, Branch, and Create your PR" below.
Some changes require careful thought and a written design before implementation. For these, we'll request a short design document — typically a markdown file under docs/ or a detailed comment on the issue describing the proposed configuration schema changes, runner behavior, or SDK API surface. Driving towards agreement in writing, before any code is written, often results in simpler code and less wasted effort.
Human-facing Markdown documentation includes one visible audience marker immediately below its title:
> **Audience:** MXC consumersfor people configuring, embedding, or operating MXC.> **Audience:** MXC developersfor repository design, architecture, build, test, and maintenance material.> **Audience:** MXC consumers and developerswhen a document genuinely serves both groups.
Do not add these markers to legal text, GitHub templates or workflow prompts, or agent instruction files.
Place developer-only documentation under the appropriate docs/development/
subdirectory. Keep consumer and mixed-audience documentation in the main
docs/ tree, and keep implementation-specific READMEs beside the code or tests
they describe.
New, in-development features use their permanent JSON locations in the mutable
development contract. They may still require the binary's --experimental
runtime authorization until graduation; that gate is independent of JSON
placement. If you're adding a new feature, follow the step-by-step checklist in
docs/development/guides/authoring-a-new-feature.md, which
walks through the schema, Rust, and test-config changes required. The schema
versioning model and promotion path from experimental to stable are described
in docs/development/architecture/versioning.md.
Issues that are ready for development but have no owner are labeled Help-Wanted. If you're looking for a place to start, those are a good entry point.
This project requires contributors to sign the Microsoft Contributor License Agreement (CLA). You will be prompted by the CLA bot the first time you open a PR; once you have signed it, you do not need to do so again.
Once you've discussed your proposed change with a team member and agreed on an approach:
- Fork the repository if you haven't already.
- Clone your fork locally.
- Create a feature branch.
- Open a Draft Pull Request early.
- Work on your changes and push them to the branch.
- Build and validate locally (see below) before marking the PR ready for review.
src/ Rust workspace (wxc-exec, lxc-exec, mxc-exec-mac, mxc_common, etc.)
sdk/ TypeScript SDK (@microsoft/mxc-sdk)
docs/ Schema and configuration documentation
tests/ Test collateral (examples, configs, scripts)
schemas/ JSON schemas (stable + dev)
.azure-pipelines/ 1ES Pipeline Templates configuration
MXC has a Rust core (under src/) and a TypeScript SDK (under sdk/node/). The full project layout and commands are documented in the README. The short version:
Windows — build.bat:
build.bat :: Release build for current architecture
build.bat --debug :: Debug build
build.bat --all :: Release build for both x64 and ARM64
build.bat --with-microvm :: Include NanVix micro-VM binariesLinux — ./build.sh:
./build.sh # Release build
./build.sh --debug # Debug build
./build.sh --rust-only # Only Rust binaries, skip SDK
./build.sh --with-hyperlight # Build with the Hyperlight micro-VM backend (x86_64 only)macOS — ./build-mac.sh (requires Xcode Command Line Tools):
./build-mac.sh # Release build for native architecture (seatbelt backend)
./build-mac.sh --debug # Debug build
./build-mac.sh --all # Build for both aarch64 and x86_64
./build-mac.sh --rust-only # Only Rust binaries, skip SDKThe macOS build produces an unsigned mxc-exec-mac binary; codesigning and notarization happen at release time.
Individual components:
# Rust workspace (from src/)
cargo build --release --target x86_64-pc-windows-msvc
cargo build --release --target aarch64-pc-windows-msvc
cargo build --release -p lxc # Linux only — builds lxc-exec
cargo build --release -p mxc_darwin --target aarch64-apple-darwin # macOS only — builds mxc-exec-mac
# SDK (from sdk/node/)
npm install && npm run buildDependency upgrades produced by commands such as npm install, npm update,
and npm audit fix may change one of these lockfiles:
sdk/node/package-lock.jsonsdk/node/tests/integration/package-lock.jsonscripts/versioning/package-lock.jsontests/playground/package-lock.json
Microsoft developers resolve npm packages through an internal 1ES feed. That
feed can write internal ms-feed-* tarball URLs and SHA-1 integrity values into
a lockfile. Because this is a public repository, committed lockfiles must
instead use https://registry.npmjs.org URLs that external contributors can
access and SHA-512 integrity values.
After an npm command changes a lockfile through the internal feed, normalize it from the repository root using PowerShell 7.3 or later:
pwsh -File .\scripts\normalize-npm-package-lock.ps1 `
.\sdk\node\package-lock.jsonRun the script once for each changed lockfile. It downloads affected tarballs
through the internal feed, verifies their existing integrity value, computes
SHA-512, and restores the public npm registry URL. It makes no changes when a
lockfile already contains public URLs. CI checks every tracked
package-lock.json. Resolved dependencies must either be repository-relative
file:/path references or HTTPS artifacts from registry.npmjs.org; npmjs
artifacts must have a valid SHA-512 integrity value. Installed package records
must declare their source; workspace source and bundled-package records are
handled explicitly.
Before submitting a PR, run the linters and formatters that already exist in the repo:
# Rust (from src/)
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warningsThe Rust style guidelines used in this repo are documented in .github/instructions/rust.instructions.md.
Testing is a key component in the development workflow. We expect contributors to add or update tests alongside their changes.
# Rust unit tests (from src/)
cargo test --workspace
cargo test -p mxc-sdk --lib # Consolidated library unit tests
cargo test -p mxc-sdk --lib -- config_parser # Filter by test name
# SDK unit and integration tests (from sdk/node/)
npm test
npm run test:integration
# Rust end-to-end tests against the built binaries (from src/)
cargo test -p mxc-sdk --test 'wxc_e2e_tests_*' # Invokes MXC binaries directly
cargo test -p mxc-sdk --test 'wxc_e2e_tests_*' -- --ignored # Include stress testsPowerShell and shell helper scripts that drive the executor end-to-end live under tests/scripts/ and require a local build. See the README and the SDK README for more.
When the change is ready, mark the Draft PR as Ready for Review. The PR template asks you to confirm CLA acceptance and to update .github/copilot-instructions.md if your change affects build commands, project architecture, or key conventions.
PR builds don't run automatically — Microsoft ADO policy requires a Microsoft employee to comment /azp run to start the MXC-PR-Build pipeline. See pull request builds for details.
Reviewers will look for:
- Correctness and security — MXC is a sandboxing system, so containment policy changes get extra scrutiny.
- Tests covering the new or changed behavior.
- Documentation updates when behavior covered by existing docs changes (e.g.,
docs/schema.mdfor schema changes, the relevant backend doc indocs/for runner changes,sdk/node/README.mdfor SDK API changes). - Code style consistent with the rest of the repo.
It may take several review cycles. The result should be solid, testable, conformant code that is safe to merge.
Once your PR has been reviewed and approved, a maintainer will merge it into main. Your PR will be automatically closed when the merge completes.
Thank you in advance for your contribution!