diff --git a/crates/openshell-driver-mxc/README.md b/crates/openshell-driver-mxc/README.md index 70027f6bc..fa50a8fcd 100644 --- a/crates/openshell-driver-mxc/README.md +++ b/crates/openshell-driver-mxc/README.md @@ -108,6 +108,35 @@ the demo Windows host and follow `mxc-demo-runbook.md` inside it. The script prints a SHA256 manifest so the operator can sanity-check what landed before moving it. +## Real-MXC test lane + +Three tasks drive real `wxc-exec.exe` hardware; all are **skip-safe** — any test +or scenario that requires an absent binary or backend prints a SKIP reason and +exits 0 rather than failing. + +| Task | What it runs | When to use | +|---|---|---| +| `windows:test:mxc-real:x64` | `tests/wxc_exec_real.rs` — Tier-2 invoker tests with `--ignored --test-threads=1` | Pre-merge on any Windows host that has `wxc-exec`; dry-run tests always pass; enforcement tests probe-gate themselves | +| `windows:e2e:mxc` | `examples/run-mxc-e2e.ps1` — Tier-3 scenario runner, real binary, probe-gated | Demo box / nightly; needs the gateway + CLI binaries in the script directory | +| `windows:e2e:mxc:mock` | Same runner with `-Mock` — wiring-only, no real `wxc-exec` needed | Any Windows host (CI, dev machine); validates wiring and the network-reject scenario | + +**Probe script:** `examples/probe-mxc-host.ps1` emits a JSON capability report +(OS build, wxc-exec path/version, dry-run exit code, per-backend trial result, +and a `verdicts` object). Run it before the real-MXC lane to understand what +will PASS vs SKIP on a given host: + +```powershell +powershell -NoProfile -ExecutionPolicy Bypass ` + -File crates/openshell-driver-mxc/examples/probe-mxc-host.ps1 +``` + +**Skip semantics:** tests in `wxc_exec_real.rs` are marked +`#[ignore = "requires real wxc-exec"]` — the standard `windows:test:x64` suite +never runs them. `OPENSHELL_WXC_EXEC_PATH` overrides the default +`C:\mxc\wxc-exec.exe` lookup. See `docs4gtb/mxc-box-capabilities.md` for the +empirical capability snapshot of the development box (build 26200, processcontainer +velocity keys not enabled, isolation_session absent). + ## Deferred work - **Interactive exec/connect/forward** → `adapt-openshell-gateway-windows` diff --git a/crates/openshell-driver-mxc/examples/e2e-policies/fs-empty.yaml b/crates/openshell-driver-mxc/examples/e2e-policies/fs-empty.yaml new file mode 100644 index 000000000..8be1dec9c --- /dev/null +++ b/crates/openshell-driver-mxc/examples/e2e-policies/fs-empty.yaml @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# fs-empty.yaml — Empty filesystem policy (default-deny) scenario. +# +# No paths are granted. With processcontainer (AppContainer), every write is +# denied by the OS without any host ACL configuration — genuine default-deny. +# This scenario is processcontainer-only (isolation_session has no deny primitive). +# Used by the fs-default-deny-empty scenario in run-mxc-e2e.ps1. +version: 1 + +filesystem_policy: + include_workdir: false + read_only: [] + read_write: [] diff --git a/crates/openshell-driver-mxc/examples/e2e-policies/fs-readonly.yaml b/crates/openshell-driver-mxc/examples/e2e-policies/fs-readonly.yaml new file mode 100644 index 000000000..7fd2d0864 --- /dev/null +++ b/crates/openshell-driver-mxc/examples/e2e-policies/fs-readonly.yaml @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# fs-readonly.yaml — Read-only grant + read-write share scenario. +# +# The read_only path is a prepared directory whose content the agent can read +# but not write; the read_write path is DemoDir (host-visible share). +# Used by the fs-readonly scenario in run-mxc-e2e.ps1. +version: 1 + +filesystem_policy: + include_workdir: false + read_only: + - "C:/work/openshell-mxc-e2e-ro-src" + read_write: + - "C:/work/openshell-mxc-e2e" diff --git a/crates/openshell-driver-mxc/examples/e2e-policies/fs-rw.yaml b/crates/openshell-driver-mxc/examples/e2e-policies/fs-rw.yaml new file mode 100644 index 000000000..38dafa5ed --- /dev/null +++ b/crates/openshell-driver-mxc/examples/e2e-policies/fs-rw.yaml @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# fs-rw.yaml — Filesystem read-write grant scenario. +# +# Grants read-write access to the DemoDir (substituted at runtime). +# Used by the fs-rw-positive-negative scenario in run-mxc-e2e.ps1. +version: 1 + +filesystem_policy: + include_workdir: false + read_only: [] + read_write: + - "C:/work/openshell-mxc-e2e" diff --git a/crates/openshell-driver-mxc/examples/e2e-policies/network-reject.yaml b/crates/openshell-driver-mxc/examples/e2e-policies/network-reject.yaml new file mode 100644 index 000000000..47844069b --- /dev/null +++ b/crates/openshell-driver-mxc/examples/e2e-policies/network-reject.yaml @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# network-reject.yaml — Network policy rejection scenario. +# +# A filesystem grant plus a network_policies rule. On isolation_session the +# driver rejects sandbox create at map time with invalid_argument naming the +# network rule (M1 not yet landed). On processcontainer with egress_proxy +# disabled, network policy is also rejected. +# +# This scenario requires NO live backend — it passes even on this box and in +# mock mode because the rejection happens in the policy mapper before wxc-exec +# is invoked. It is the only scenario that never SKIPs. +version: 1 + +filesystem_policy: + include_workdir: false + read_only: [] + read_write: + - "C:/work/openshell-mxc-e2e" + +network_policies: + test_rule: + name: test-network-reject + endpoints: + - host: api.example.com + port: 443 + protocol: rest + enforcement: enforce + access: read-only diff --git a/tasks/windows.toml b/tasks/windows.toml index c7a2e51f9..59c2a8f2c 100644 --- a/tasks/windows.toml +++ b/tasks/windows.toml @@ -63,3 +63,18 @@ run_windows = "powershell -NoProfile -ExecutionPolicy Bypass -File tasks/scripts description = "Run Windows MSVC checks, release builds, x64 tests, and unsupported-driver contract tests" run = "echo 'windows:* tasks require a Windows MSVC host' && exit 1" run_windows = "powershell -NoProfile -ExecutionPolicy Bypass -File tasks/scripts/windows-msvc.ps1 ci all" + +["windows:test:mxc-real:x64"] +description = "Run real-wxc-exec Tier-2 integration tests (skip-safe: tests print SKIP when binary/backend absent)" +run = "echo 'windows:* tasks require a Windows MSVC host' && exit 1" +run_windows = "cargo test -p openshell-driver-mxc --test wxc_exec_real --target x86_64-pc-windows-msvc -- --ignored --test-threads=1" + +["windows:e2e:mxc"] +description = "Run MXC Tier-3 e2e scenario runner against real wxc-exec (probe-gated; skip-safe on hosts without the binary)" +run = "echo 'windows:* tasks require a Windows MSVC host' && exit 1" +run_windows = "powershell -NoProfile -ExecutionPolicy Bypass -File crates/openshell-driver-mxc/examples/run-mxc-e2e.ps1" + +["windows:e2e:mxc:mock"] +description = "Run MXC Tier-3 e2e scenario runner in mock/wiring-only mode (no real wxc-exec required)" +run = "echo 'windows:* tasks require a Windows MSVC host' && exit 1" +run_windows = "powershell -NoProfile -ExecutionPolicy Bypass -File crates/openshell-driver-mxc/examples/run-mxc-e2e.ps1 -Mock"