From ecd4ca50623800290f5c005b73c18803dfed8749 Mon Sep 17 00:00:00 2001 From: Shailendra Singh Date: Tue, 22 Sep 2026 20:11:36 -0700 Subject: [PATCH 1/3] docs(windows): add runtime architecture overview Signed-off-by: Shailendra Singh --- architecture/README.md | 45 +++-- architecture/windows.md | 259 ++++++++++++++++++++++++++ crates/openshell-driver-mxc/README.md | 10 +- 3 files changed, 294 insertions(+), 20 deletions(-) create mode 100644 architecture/windows.md diff --git a/architecture/README.md b/architecture/README.md index 706db67b1f..e51cc4c607 100644 --- a/architecture/README.md +++ b/architecture/README.md @@ -2,16 +2,17 @@ OpenShell runs autonomous AI agents in sandboxed environments with explicit policy, credential, identity, and network boundaries. The target architecture is -built around three stable runtime components: the **CLI**, the **Gateway**, and -the **Supervisor**. +built around stable user, control-plane, and runtime boundaries. Most runtimes +place the runtime boundary in the **Supervisor**; driver-controlled runtimes such +as Windows MXC enforce it through platform-native isolation and host services. The CLI, SDK, and TUI provide user-facing access. The gateway is the authenticated control plane: it owns API access, durable state, policy and settings delivery, provider configuration and attachments, and relay -coordination. The supervisor runs inside every sandbox workload and is the local -security boundary. It launches the agent as a restricted child process and -enforces policy where process identity, filesystem access, network egress, and -runtime credentials are visible. +coordination. In supervisor-based runtimes, the supervisor runs inside the +sandbox workload and launches the agent as a restricted child process. A +driver-controlled runtime owns the equivalent lifecycle and enforcement duties +without embedding the standard supervisor. Infrastructure-specific work sits behind integration boundaries. Compute, credentials, control-plane identity, and sandbox identity each have a driver or @@ -42,6 +43,7 @@ flowchart TB subgraph INFRA["Integrated Infrastructure"] RUNTIME["Docker / Podman / Kubernetes / VM"] + MXC["Windows MXC"] SECRETSTORE["Eg: Keychain / Secret Service / Vault / Kubernetes Secrets"] IDP["Eg: mTLS / OIDC / Local identity"] WORKLOADID["Eg: SPIFFE / Gateway-issued workload identity"] @@ -54,6 +56,11 @@ flowchart TB AGENT["Restricted agent process"] end + subgraph WINDP["Windows MXC Data Plane"] + MXCAGENT["MXC-isolated agent process"] + MXCPROXY["Host policy proxy (ProcessContainer only)"] + end + CLI -->|"gRPC / HTTP"| GW SDK -->|"gRPC / HTTP"| GW TUI -->|"gRPC / HTTP"| GW @@ -70,10 +77,13 @@ flowchart TB SIDENT -->|"gRPC / UDS"| SIDRV CDRV --> RUNTIME + CDRV --> MXC CRDRV --> SECRETSTORE CPIDRV --> IDP SIDRV --> WORKLOADID RUNTIME -->|"provisions workload"| SUP + MXC -->|"driver-controlled launch"| MXCAGENT + MXCAGENT -. "governed egress" .-> MXCPROXY SUP -->|"outbound control, config, logs, relay"| GW SUP -->|"spawn + restrict"| AGENT @@ -93,8 +103,8 @@ flowchart TB | Credentials subsystem | Logical provider and credential resolution. Secret storage and platform-native credential access belong to credentials drivers. | | Control-plane identity | Authentication and authorization for users, operators, and API clients. External identity verification belongs to identity drivers. | | Sandbox identity | Workload identity for supervisors and sandbox-to-sandbox authorization. Identity issuance or verification belongs to sandbox identity drivers. | -| Supervisor | Sandbox-local security boundary. It prepares isolation, fetches config, injects credentials, runs relay endpoints, starts the proxy, and launches restricted agent processes. | -| Policy proxy | Mandatory egress path for agent traffic. It enforces destination, binary identity, SSRF, TLS/L7, and endpoint-bound provider credential injection. | +| Supervisor | Sandbox-local security boundary for supervisor-based runtimes. It prepares isolation, fetches config, injects credentials, runs relay endpoints, starts the proxy, and launches restricted agent processes. Driver-controlled runtimes must enforce supported behavior and explicitly define or reject unsupported behavior. | +| Policy proxy | Mandatory path for policy-governed egress. It enforces destination, binary identity, SSRF, TLS/L7, and endpoint-bound provider credential injection. | ## Integrating with the Ecosystem @@ -111,10 +121,12 @@ operations. They should stay thin, preserve native behavior by default, and report platform lifecycle events back through the shared contracts. -The supervisor owns OpenShell sandbox semantics. Filesystem policy, process -privilege reduction, network proxying, endpoint-bound credential injection, -security logging, and gateway relay behavior should remain -consistent across runtimes. +The supervisor owns OpenShell sandbox semantics on supervisor-based runtimes. +Driver-controlled runtimes own the corresponding platform-specific semantics +and must explicitly define or reject policy they cannot enforce. Filesystem +policy, process privilege reduction, network proxying, endpoint-bound credential +injection, security logging, and gateway relay behavior should remain consistent +where the runtime advertises those capabilities. This keeps OpenShell usable in local single-player setups, Kubernetes deployments, VM-backed sandboxes, and future third-party environments. A new @@ -142,9 +154,11 @@ The compute-driver capability contract identifies whether a driver reports runtime readiness. Most drivers use the supervisor session model above. A driver that sets `driver_reports_runtime_readiness` may self-report readiness without a supervisor session. Every driver receives the canonical create-time -policy in `DriverSandboxSpec`; drivers without a supervisor use the existing -sandbox configuration API for later revisions. The Windows MXC driver reports -its own readiness and does not expose interactive connect or governed egress. +policy in `DriverSandboxSpec`; drivers without a supervisor may use the sandbox +configuration API when they advertise live-update support. The Windows MXC +driver reports its own readiness, does not support live updates, and does not +expose interactive connect. ProcessContainer can establish governed egress at +create time; IsolationSession rejects governed network policies. The gateway delivers desired state; the sandbox applies it locally. Policy, settings, provider attachments, and credential bindings flow from the gateway @@ -173,6 +187,7 @@ that crate's `README.md`. | [Compute Runtimes](compute-runtimes.md) | Docker, Podman, Kubernetes, VM, sandbox images, and runtime-specific responsibilities. | | [Build](build.md) | Build artifacts, CI/E2E, docs site validation, and release packaging. | | [Google Vertex AI Provider](google-vertex-ai-provider.md) | Implementation reference for the `google-vertex-ai` provider, from CLI through gateway to sandbox. | +| [Windows](windows.md) | Windows/MXC runtime architecture, policy enforcement, networking, relay, audit, and trust boundaries. | | [Windows MSVC Build](windows-msvc-build.md) | Build-only native Windows MSVC lane (x64/ARM64) and unsupported-runtime behavior on Windows. | ## `rfc/` vs `architecture/` diff --git a/architecture/windows.md b/architecture/windows.md new file mode 100644 index 0000000000..3f514b3fa6 --- /dev/null +++ b/architecture/windows.md @@ -0,0 +1,259 @@ +# Windows + +OpenShell runs natively on Windows as an MSVC-built CLI and gateway with the +Microsoft MXC compute driver linked into the gateway process. MXC is a +driver-controlled runtime: it applies the canonical policy, launches the agent, +and reports readiness without running the standard `openshell-sandbox` +supervisor inside the workload. + +This document describes the stable Windows boundaries. See +[Gateway](gateway.md) for control-plane behavior, +[Compute Runtimes](compute-runtimes.md) for the shared driver contract, +[Security Policy](security-policy.md) for the canonical policy model, and the +[MXC driver README](../crates/openshell-driver-mxc/README.md) for configuration +and operational details. + +## Runtime Architecture + +The Windows CLI uses the same public gateway API as other platforms. The +gateway owns authentication, persistence, effective-policy composition, +provider attachment, and public sandbox status. The in-process +`MxcComputeBackend` owns MXC configuration, `wxc-exec` lifecycle, host-side +network enforcement, relay state, and runtime watch events. + +The following diagram shows the Windows-specific control and data paths. The +MXC isolation boundary contains the agent and optional supervisor relay; the +gateway-side proxy and ETW consumer remain on the host. + +```mermaid +flowchart LR + CLI["OpenShell CLI"] -->|"gRPC / HTTP"| GW["OpenShell gateway"] + + subgraph HOST["Windows host"] + GW -->|"in-process ComputeDriver"| DRV["MXC driver"] + DRV -->|"ContainerConfig + lifecycle commands"| WXC["wxc-exec"] + PROXY["Per-sandbox CONNECT proxy"] + ETW["Sandboxing ETW consumer"] -->|"attributed events"| OCSF["OCSF trail"] + GW -->|"dynamic forward request"| DRV + end + + subgraph MXC["MXC isolation boundary"] + PC["ProcessContainer"] + ISO["IsolationSession"] + RELAY["openshell-supervisor-relay"] + AGENT["Agent process"] + PC --> AGENT + PC -. "optional wrapper" .-> RELAY + RELAY --> AGENT + ISO --> AGENT + ISO -. "optional wrapper" .-> RELAY + end + + WXC --> PC + WXC --> ISO + PC -. "ProcessContainer governed egress only" .-> PROXY + DRV <-->|"inherited stdin/stdout control channel"| RELAY + WXC -. "OS Sandboxing events" .-> ETW +``` + +`crates/openshell-driver-mxc/src/grpc.rs` adapts the shared `ComputeDriver` +service to the in-process backend. This is a contract boundary, not a network +hop. MXC requests no additional gateway callback listener and does not +authenticate a sandbox principal because there is no standard supervisor +session. + +## Backend Semantics + +The selected backend changes both lifecycle and enforceable policy. Backend +selection belongs to gateway startup configuration, not to an individual +sandbox request. + +| Property | `process_container` | `isolation_session` | +|---|---|---| +| Runtime model | One-shot AppContainer process; default backend | Persistent MXC session used to run one configured process | +| Driver lifecycle | Launch and monitor `wxc-exec` | `provision` -> `start` -> `exec`; stop/delete issue `stop` and `deprovision` | +| Filesystem | Read-only/read-write grants with default-deny behavior | Explicit grant-only compatibility mode; not equivalent to ProcessContainer default deny | +| Portable UI policy | Supported completely | Every explicit `ui` section is rejected before provisioning | +| Governed network policy | Supported through the host proxy when enabled | Rejected because the backend cannot enforce the loopback-only proxy path | +| Supervisor relay and dynamic forwarding | Optional | Optional | + +Neither backend implements interactive `sandbox connect` or interactive exec +through the standard supervisor protocol. The MXC `StartSandbox` operation is +also unsupported: create performs the initial launch, and a stopped workload is +not restarted in place. + +## Create and Policy Flow + +The gateway composes the effective `SandboxPolicy` before calling the driver and +includes it in `DriverSandboxSpec.policy`. The MXC driver validates and maps that +typed policy before it publishes a registry entry or invokes `wxc-exec`, so an +unsupported policy cannot leave a partially provisioned sandbox. + +The create path is: + +1. The gateway resolves the canonical command, environment, working directory, + effective policy, and attached provider state. +2. The gateway checks driver capabilities. In particular, it rejects an + explicit UI policy when the configured MXC backend does not advertise full + UI support. +3. `MxcComputeBackend::validate_sandbox_create` validates MXC-specific workload + inputs and calls `EmbeddedPolicyMapper`. +4. The mapper produces the MXC filesystem, UI, and network configuration. Any + loss item classified as an error rejects creation; warnings and informational + items do not block mapping. +5. The driver starts any required host proxy, stages public proxy CA material, + launches `wxc-exec`, and publishes lifecycle events through the shared watch + stream. + +The production mapping in +`crates/openshell-driver-mxc/src/policy.rs` and +`crates/openshell-driver-mxc/src/policy_map/` treats policy areas as follows: + +| Policy area | Windows enforcement | +|---|---| +| Filesystem | `read_only` and `read_write` become MXC path grants. `include_workdir` adds the resolved working directory as read-write. The mapper normalizes separators but does not translate Linux-rooted locations into Windows paths. ProcessContainer supplies the default-deny boundary; IsolationSession supplies only the requested grants. | +| Network | An explicit network policy requires governed egress on ProcessContainer. The mapper gives MXC loopback-only egress and returns the complete network policy to a per-sandbox host CONNECT proxy. MXC denies direct Internet access; the proxy evaluates destinations, ports, TLS/L7 rules, credential bindings, and binary rules against the configured agent command as its static process identity. Network middleware configuration is rejected because the host proxy does not receive the gateway middleware registry. IsolationSession rejects network policy. | +| UI | ProcessContainer maps graphical UI, directional clipboard access, and input injection into MXC's top-level `ui` object. An absent section maps to the restrictive UI posture. Within an explicit section, omitted fields deny. IsolationSession rejects even an empty explicit section. | +| Process | MXC supplies the Windows process-isolation boundary, but the mapper has no portable equivalent for `run_as_user` or `run_as_group`; callers must not treat those fields as enforced Windows identity controls. The canonical command, environment, and working directory are launch inputs rather than process-policy grants. | +| Landlock | MXC has no equivalent for the Linux Landlock compatibility mode, including `hard_requirement`. The mapper reports a non-blocking warning; Windows filesystem assurance comes from the selected MXC backend's native semantics, not Landlock. | + +The driver reports `supports_live_policy_updates = false`. The gateway therefore +rejects mutations that would change a running MXC sandbox's effective policy or +provider bindings before persistence. Filesystem, UI, network, and credential +changes require sandbox recreation. + +## Governed Egress and Credentials + +Governed egress uses a split enforcement model. MXC blocks direct Internet +traffic and permits host loopback; a unique authenticated proxy listener holds +the full OpenShell network policy. The driver injects standard proxy variables +for proxy-aware clients and stages only public CA certificates under an +authorized sandbox path. The ephemeral CA private key remains in host-proxy +memory. + +The loopback grant is broader than the proxy listener: a governed sandbox can +reach other host services bound to loopback. Per-sandbox proxy credentials +prevent another sandbox from using the OpenShell proxy, but they do not isolate +unrelated host-loopback services or authenticate individual processes within +one sandbox. + +Two gateway-wide ProcessContainer compatibility settings can deliberately +broaden this boundary. `pc_network_allow` permits unrestricted outbound TCP, and +`pc_allow_local_network` enables MXC local-network access. These are operator +configuration choices, not sandbox policy grants, and they must not be treated +as policy-governed egress. + +Provider credentials cross a narrower boundary than ordinary environment +variables: + +1. The gateway stages a create-scoped `ProviderCredentialState` in an + in-process handoff keyed by sandbox ID. +2. The driver consumes that state exactly once, including on validation + failure, and places only revision-scoped placeholders and non-secret provider + environment in the MXC child configuration. +3. The host proxy retains resolver state and substitutes credentials only for + endpoints authorized by the attached provider profile and policy. + +The gateway rejects expiring static provider credentials because MXC has no +live credential refresh channel. Dynamic token grants remain request-time +host-proxy operations. +Provider state that requires credential resolution also requires governed +egress; creation fails closed when the proxy path is unavailable. + +## Relay and Dynamic Forwarding + +Either MXC backend can launch `openshell-supervisor-relay` as a generic wrapper +around the configured agent. The driver computes this wrapping before it enters +the backend-specific lifecycle. The driver and relay exchange newline-delimited +JSON over inherited stdin and stdout, so control traffic does not require +sandbox network access. Startup validates the relay protocol version, transfers +the command and environment after the relay announces readiness, and waits for +the configured target port before publishing runtime readiness. + +Dynamic `openshell forward service` requests use a dedicated MXC path because +there is no `ConnectSupervisor` session. The gateway calls the driver's +`ForwardSink`; the driver creates an authenticated host-loopback listener and +multiplexes `forward_open`, `forward_read`, `forward_write`, and +`forward_close` operations over the inherited control channel. A fresh nonce +authenticates each host-side forward. This capability does not add interactive +shell or general exec support. + +The implementation boundary spans +`crates/openshell-driver-mxc/src/control_channel.rs`, +`crates/openshell-driver-mxc/src/relay.rs`, and +`crates/openshell-supervisor-relay/`. + +## Readiness, Lifecycle, and Persistence + +MXC advertises `driver_reports_runtime_readiness = true`. The gateway therefore +accepts the driver's `Ready=True` event without waiting for a supervisor +session. Direct launches on either backend become ready after the process +starts; relay-wrapped launches additionally require the relay and +target-readiness handshakes. + +The driver serializes startup against stop and delete with a per-sandbox +lifecycle gate. Stop and delete signal the owned process and wait for confirmed +termination before reporting success. IsolationSession delete also +deprovisions the MXC session. Process exit, mapping failure, relay failure, and +MXC invocation errors produce watch or platform events that the gateway folds +into persisted public status. + +Runtime ownership is not durable. The registry, process handles, proxy handles, +relay channels, and IsolationSession IDs live in gateway memory. A restarted +gateway cannot recover or reconcile an existing MXC workload, so Windows MXC +does not provide restart durability. + +## Audit Boundary + +When enabled, `crates/openshell-driver-mxc/src/etw_consumer.rs` starts a +gateway-owned real-time session for the Windows Sandboxing ETW provider. The +consumer attributes events to a sandbox using the driver-owned `wxc-exec` PID +and kernel process start key, then follows identity, activity, and correlation +links emitted by the provider. It never uses command text as ownership evidence; +records without matching generation evidence remain unattributed and are +dropped after the bounded late-event window. + +The ETW callback copies records into a bounded non-blocking queue. Overflow, +unattributed records, and a session that observes sandbox activity but no +provider events generate explicit coverage-gap warnings or findings. Structured +events flow through the shared OCSF builders. Command-line data and credentials +must not appear in OCSF fields, messages, or raw ETW diagnostics. The optional +gateway-local JSONL sink is specific to the Windows/MXC path; see +[Security Policy](security-policy.md#security-logging) for the logging contract. + +## Supported and Unsupported Runtime Surface + +Native Windows gateway builds link the MXC compute driver. Docker, Podman, +Kubernetes, and VM compute features install explicit Windows rejection stubs; +they do not silently fall back to an unisolated runtime. MXC also rejects GPU +requests and `agent_socket_path` because it has neither GPU integration nor the +standard in-sandbox supervisor. + +The supported Windows artifacts and cross-architecture build boundary are +documented in [Windows MSVC Build](windows-msvc-build.md). An x64 host can +cross-check and cross-build ARM64, but native runtime tests and MXC +qualification must execute on the matching architecture. + +## Validation and Qualification + +Windows validation separates source correctness from host capability: + +- Mapper parity and matrix tests validate deterministic policy translation and + fail-closed loss handling without requiring MXC. +- The architecture-specific `windows:*` tasks check, lint, build, and run + workspace and unsupported-driver contract tests for x64 and ARM64. +- Mock MXC E2E validates gateway, CLI, driver, lifecycle, and policy wiring but + is not evidence of OS enforcement. +- Real-`wxc-exec` tests validate the installed schema and selected filesystem, + UI, network, and lifecycle behavior. A probe-gated skip is useful + diagnostic output, not qualification evidence. +- Strict platform qualification requires native architecture, a live required + backend, policy E2E scenarios, workload scenarios, and hash-bound artifacts. + The machine-validated contract lives in the + [MXC qualification directory](../crates/openshell-driver-mxc/qualification/README.md). +- Workload qualification scenarios exercise relay behavior, including dynamic + forwarding, on the backends selected by the scenario. + +The [MXC driver README](../crates/openshell-driver-mxc/README.md#real-mxc-test-lane) +defines the test tiers, host prerequisites, and qualification entry points. +These checks validate only the runtime available on the tested host. diff --git a/crates/openshell-driver-mxc/README.md b/crates/openshell-driver-mxc/README.md index 678632210f..5ac54d534d 100644 --- a/crates/openshell-driver-mxc/README.md +++ b/crates/openshell-driver-mxc/README.md @@ -48,11 +48,11 @@ backend = "process_container" default_configuration_id = "composable" pc_least_privilege = false pc_capabilities = [] -# processContainer only: launch openshell-supervisor-relay instead of -# the per-sandbox command directly, giving the driver a control -# channel into the sandbox (launch handshake, dynamic `openshell forward -# service` bridging). target_port is the launched command's own listening -# port; 0 disables spawner wrapping (default -- the command runs directly). +# Either backend: launch openshell-supervisor-relay instead of the per-sandbox +# command directly, giving the driver a control channel into the sandbox +# (launch handshake, dynamic `openshell forward service` bridging). target_port +# is the launched command's own listening port; 0 disables spawner wrapping +# (default -- the command runs directly). pc_relay_spawner_path = "" pc_relay_target_port = 0 # processContainer only: env-inheritance tier for the launched process From 735bba9dad5c6b4b1ab52b1be18bcb0772cbb6b5 Mon Sep 17 00:00:00 2001 From: Shailendra Singh Date: Tue, 22 Sep 2026 21:11:20 -0700 Subject: [PATCH 2/3] docs(windows): consolidate build documentation Signed-off-by: Shailendra Singh --- .../build-openshell-mxc-windows/SKILL.md | 3 +- .../build-openshell-mxc-windows/reference.md | 5 +- CONTRIBUTING.md | 44 +++- architecture/README.md | 1 - architecture/windows-msvc-build.md | 209 ------------------ architecture/windows.md | 11 +- 6 files changed, 48 insertions(+), 225 deletions(-) delete mode 100644 architecture/windows-msvc-build.md diff --git a/.agents/skills/build-openshell-mxc-windows/SKILL.md b/.agents/skills/build-openshell-mxc-windows/SKILL.md index 13ae8f19f8..58771d12f7 100644 --- a/.agents/skills/build-openshell-mxc-windows/SKILL.md +++ b/.agents/skills/build-openshell-mxc-windows/SKILL.md @@ -32,7 +32,8 @@ The Windows build lane is implemented by these tracked files: | `tasks/rust.toml`, `tasks/test.toml`, and `tasks/markdown.toml` | Windows routing for compiler-bearing checks, explicit Unix-only test skips, and Markdown dependency setup. | | `tasks/scripts/windows-msvc.ps1` | PowerShell wrapper that enters the Visual Studio developer environment and invokes Cargo. | | `.github/workflows/windows-msvc.yml` | Opt-in PR lint and test plus advisory main/manual cache seeding and dependent binary builds on native x64 and ARM64 runners. | -| `architecture/windows-msvc-build.md` | Design notes and validation contract. | +| `CONTRIBUTING.md` | Human-facing Windows build prerequisites and command summary. | +| `architecture/windows.md` | Stable Windows/MXC runtime and cross-architecture boundaries. | | `.agents/skills/build-openshell-mxc-windows/` | This skill and companion reference material. | Use the code that is already in the repo. Do not generate a parallel Windows diff --git a/.agents/skills/build-openshell-mxc-windows/reference.md b/.agents/skills/build-openshell-mxc-windows/reference.md index bc278664dc..09139dac53 100644 --- a/.agents/skills/build-openshell-mxc-windows/reference.md +++ b/.agents/skills/build-openshell-mxc-windows/reference.md @@ -9,8 +9,9 @@ maintaining the existing build-only Windows MSVC lane. |---|---| | `tasks/windows.toml` | Mise task definitions for `windows:*`. | | `tasks/scripts/windows-msvc.ps1` | Visual Studio environment discovery, rustup target setup, Cargo invocation, logs, artifact report. | -| `.github/workflows/windows-msvc.yml` | PR/merge-queue lint and test plus main/manual cache seeding and dependent binary builds on native x64 and ARM64 runners. | -| `architecture/windows-msvc-build.md` | Human-readable design contract. | +| `.github/workflows/windows-msvc.yml` | Opt-in PR lint and test plus advisory main/manual cache seeding and dependent binary builds on native x64 and ARM64 runners. | +| `CONTRIBUTING.md` | Human-readable Windows build prerequisites and commands. | +| `architecture/windows.md` | Stable Windows/MXC runtime and cross-architecture boundaries. | ## Commands diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 931d97500f..74d1e200a9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -361,14 +361,42 @@ just this crate does not require `LIBCLANG_PATH`: cargo build -p openshell-prover --target x86_64-pc-windows-msvc --features bundled-z3 ``` -### Windows full build - -To build the full set of Windows binaries, including `openshell-gateway.exe` -and `openshell.exe`, use the `windows:build:x64` mise task instead of a -single-crate `cargo build`. It downloads the pinned prebuilt Z3 release by default. A -full build also compiles crates that use `bindgen` (e.g. the MXC driver on -Windows), so it requires `libclang.dll`; if LLVM is not on the default search -path, set `LIBCLANG_PATH` to the directory containing `libclang.dll`: +### Windows build and validation + +Use the platform-native `windows:*` mise tasks for Windows MSVC development. +The lane supports x64 and ARM64 and builds `openshell-gateway.exe`, +`openshell.exe`, and `openshell-supervisor-relay.exe`. It does not enable +Docker, Kubernetes, Podman, or VM-backed execution on Windows. + +Install Visual Studio C++ Build Tools, a compatible Windows SDK, Rust through +rustup, mise, and the Visual Studio LLVM tools used by `bindgen`. Run every task +with `--skip-tools`; mise orchestrates the commands but does not install the +Windows compiler toolchain. + +| Task | Purpose | +|---|---| +| `windows:lint:` | Run Clippy for the Windows-supported workspace on the selected target architecture. | +| `windows:build:` | Build the three Windows release executables. | +| `windows:test:` | Run the workspace suite natively; the target must match the host architecture. | +| `windows:test:unsupported:` | Run the focused unsupported-driver contracts. | +| `windows:test:mxc-real:` | Run the probe-gated real-`wxc-exec` integration suite on the matching host. | +| `windows:artifacts` | Report sizes and SHA256 hashes for release artifacts. | +| `windows:ci` | Run the aggregate x64-host check, build, test, contract, and artifact workflow. | + +The task definitions in [`tasks/windows.toml`](tasks/windows.toml), the +PowerShell implementation in +[`tasks/scripts/windows-msvc.ps1`](tasks/scripts/windows-msvc.ps1), and the +hosted workflow in +[`.github/workflows/windows-msvc.yml`](.github/workflows/windows-msvc.yml) are +the executable sources of truth. See +[`architecture/windows.md`](architecture/windows.md) for the stable Windows/MXC +runtime and enforcement boundaries. + +To build x64 locally, use `windows:build:x64` instead of a single-crate Cargo +build. It downloads the pinned prebuilt Z3 release by default. A full build also +compiles crates that use `bindgen`, including the MXC driver, so it requires +`libclang.dll`. If LLVM is not on the default search path, set `LIBCLANG_PATH` +to the directory containing `libclang.dll`: ```powershell $env:LIBCLANG_PATH='C:\Program Files\Microsoft Visual Studio\2022\\VC\Tools\Llvm\x64\bin' diff --git a/architecture/README.md b/architecture/README.md index e51cc4c607..7f30c9a8b1 100644 --- a/architecture/README.md +++ b/architecture/README.md @@ -188,7 +188,6 @@ that crate's `README.md`. | [Build](build.md) | Build artifacts, CI/E2E, docs site validation, and release packaging. | | [Google Vertex AI Provider](google-vertex-ai-provider.md) | Implementation reference for the `google-vertex-ai` provider, from CLI through gateway to sandbox. | | [Windows](windows.md) | Windows/MXC runtime architecture, policy enforcement, networking, relay, audit, and trust boundaries. | -| [Windows MSVC Build](windows-msvc-build.md) | Build-only native Windows MSVC lane (x64/ARM64) and unsupported-runtime behavior on Windows. | ## `rfc/` vs `architecture/` diff --git a/architecture/windows-msvc-build.md b/architecture/windows-msvc-build.md deleted file mode 100644 index cd5fbd0615..0000000000 --- a/architecture/windows-msvc-build.md +++ /dev/null @@ -1,209 +0,0 @@ -# Windows MSVC Build Design - -This page records the design decisions for the native Windows MSVC build lane. -It provides the native build lane and validates the in-process MXC compute -driver. It does not make Windows a Docker, Kubernetes, Podman, or VM runtime host. - -## Goals - -- Compile the OpenShell gateway and CLI for `x86_64-pc-windows-msvc` and `aarch64-pc-windows-msvc`. -- Keep the Linux and macOS build paths unchanged. -- Preserve gateway configuration parsing for all existing compute driver names. -- Build and test the in-process MXC driver on supported Windows hosts. -- Use the ordinary in-process compute-driver composition path; MXC receives the - canonical sandbox policy through `DriverSandboxSpec` and advertises that it - reports runtime readiness. -- Return clear unsupported errors when a Windows gateway is configured to use Docker, Kubernetes, Podman, or VM. -- Keep dedicated `windows:*` validation tasks while allowing the repository-wide - `pre-commit` task to delegate compiler-bearing Rust checks to the native - Windows MSVC environment. - -## Non-Goals - -- Do not support Docker Desktop, WSL, Hyper-V, Podman machine, Podman Desktop, Kubernetes, or VM-backed sandbox execution on Windows. -- Do not ship Windows standalone binaries for Docker, Kubernetes, Podman, or VM drivers. -- Do not implement named-pipe driver IPC, Windows services, MSI packaging, Credential Manager integration, or DPAPI integration in this lane. - -## Unsupported Driver Strategy - -The gateway composition crate installs platform-specific registration stubs on -Windows. These registrations preserve config-file selection and reject -unsupported drivers with a clear error without depending on their runtime -crates. - -Each stub follows its corresponding `compute-driver-*` Cargo feature. -`compute-driver-mxc` independently links and registers MXC, so a gateway built -with only that feature has only the MXC registration. The default -`in-tree-compute-drivers` alias enables all five features and preserves the -existing MXC plus unsupported-driver registrations. The focused Windows -contract tasks cover default, protocol-only, MXC-only, Docker-stub-only, and -MXC plus Docker-stub compositions. - -The Windows lane does not build, release, package, or smoke-test standalone -driver binaries for Docker, Kubernetes, Podman, or VM. Those binaries are Linux -or macOS deliverables only. - -The Kubernetes Secrets and Vault packages are also excluded as top-level -Windows workspace targets because their standalone driver binaries use Unix -domain sockets. Their libraries remain in the gateway dependency graph, so the -gateway's credential-driver configuration and in-process behavior still compile -on Windows. - -| Driver | Windows build behavior | Runtime behavior | -|---|---|---| -| Docker | Driver crate excluded; gateway registration stub retained. | Gateway construction returns unsupported. | -| Kubernetes | Driver crate excluded; gateway registration stub retained. | Gateway construction returns unsupported. | -| Podman | Driver crate excluded; gateway registration stub retained. | Gateway construction returns unsupported. | -| VM | Driver crate excluded; gateway registration stub retained. | Gateway construction returns unsupported. | -| MXC | Driver links into the native gateway and runs in Windows validation. | `process_container` is default-deny; grant-only `isolation_session` requires explicit configuration. | - -This keeps Windows behavior explicit without carrying runtime dependencies or -creating misleading Windows driver artifacts. - -## Mise Lane - -The GitHub Actions workflow runs Clippy for the Windows-supported workspace and -e2e crates plus Rust tests for pull-request mirror branches labeled `test:windows`. -Merge queues do not run this workflow. On -pushes to `main`, a cache-seed job runs the same lint and test commands before a -dependent job builds the release binaries. Manual dispatches exercise the same -seed-then-build path. The binaries remain CI validation artifacts and are not -uploaded or published. - -Each job restores and saves a dedicated Rust cache containing the Cargo -registry and dependency build artifacts, including artifacts from failed runs. -The seed job and pull-request job use the same Cargo target and sccache -namespaces. The release build waits for the seed job, then restores its newly -warmed cache rather than compiling concurrently from a cold cache. - -Windows validation is exposed through `tasks/windows.toml`: - -| Task | Purpose | -|---|---| -| `windows:check:x64` | Check the x64 MSVC gateway/CLI build graph. | -| `windows:check:arm64` | Check the ARM64 MSVC gateway/CLI build graph. | -| `windows:lint:x64` | Run Clippy over the Windows-supported workspace for x64 MSVC. | -| `windows:lint:arm64` | Run Clippy over the Windows-supported workspace for ARM64 MSVC. | -| `windows:build:x64` | Build release x64 `openshell-gateway.exe` and `openshell.exe`. | -| `windows:build:arm64` | Build release ARM64 `openshell-gateway.exe` and `openshell.exe`. | -| `windows:test:x64` | Run native x64 workspace tests with the nextest CI profile and server test support, while excluding unsupported Windows packages as top-level test targets. | -| `windows:test:arm64` | Run the same suite natively on ARM64. | -| `windows:test:unsupported:x64` | Run focused gateway-composition tests for unsupported driver contracts. | -| `windows:test:unsupported:arm64` | Run the same focused contracts natively on ARM64. | -| `windows:test:mxc-real:arm64` | Run the native real-MXC developer suite; missing hardware remains skip-safe. | -| `windows:test:mxc-gb300:arm64` | Run the required real-MXC subset on native ARM64 and fail on any required skip. | -| `windows:qualify:mxc:gb300:contract` | Validate the static NVBug 6643699 scope matrix on any development host. | -| `windows:qualify:mxc:gb300` | Execute the complete native GB300 ARM64 gate and produce hash-bound evidence. | -| `windows:ci` | Run check, build, test, unsupported-contract tests, and artifact reporting. | - -The Windows tasks call `tasks/scripts/windows-msvc.ps1`. The wrapper discovers -Visual Studio's `VsDevCmd.bat` with `vswhere` or by enumerating installed -release directories, validates the requested compiler and ARM64 Spectre -libraries, adds rustup MSVC targets, preserves an inherited `RUSTC_WRAPPER` -when the command is available, and keeps build artifacts under the normal -Cargo target tree. If the wrapper command is unavailable, it warns and clears -the setting so local builds continue without compiler caching. -On Windows, the generic `rust:check`, `rust:lint`, and `test:rust` tasks call -the same wrapper with the host-native MSVC target. The wrapper preserves the -Unix Cargo commands on Linux and macOS, excludes unsupported Windows runtime -packages, and runs the server test-support suite separately. Windows Clippy -continues to deny all warnings except unused imports, dead code, and unused -async functions caused by cfg-gated Windows stubs. Repository-wide pre-commit -skips only Linux-specific installer, build-environment shell-helper, and -packaging-asset tests; its -cross-platform Python, Markdown, license, and documentation checks still run. -Test tasks require the Rust target architecture to match the Windows host, so -an ARM64 test result is native coverage rather than x64 emulation coverage. -By default it enables the `z3-sys` prebuilt-release feature and pins Z3 4.16.0. -On a clean target directory, `z3-sys` downloads the official static library for -the selected Windows architecture instead of compiling Z3 through -CMake/MSBuild. GitHub Actions supplies its read-only workflow token for the -release lookup, and the Cargo target cache preserves the extracted library for -subsequent runs. When `Z3_LIBRARY_PATH_OVERRIDE` points at a directory -containing `libz3.lib`, the wrapper uses that system Z3 instead and requires -`Z3_SYS_Z3_HEADER` to point at the full path to `z3.h`. Local clean builds use -the unauthenticated GitHub API unless `READ_ONLY_GITHUB_TOKEN` is set. - -GitHub Actions layers the Cargo target cache with sccache's GitHub Actions -backend. The target cache lets Cargo skip intact dependency builds; sccache -recovers cacheable Rust compiler outputs when source changes invalidate part of -that target tree. CI enables client-side mode and normalizes the checkout root -for stable compiler cache keys. The target-cache action runs its metadata step -with `RUSTC_WRAPPER` cleared so cache maintenance does not depend on sccache. -Hosted jobs use an isolated `RUSTUP_HOME` containing the pinned toolchain so -unused toolchains in runner images cannot change the target-cache restore key. - -The lane uses `mise run --skip-tools windows:*` because Windows Rust comes from -rustup and linking comes from Visual Studio Build Tools. Mise orchestrates the -tasks; it does not own the Windows toolchain. - -ARM64 validation requires the Visual Studio ARM64 MSVC tools, ARM64 -Spectre-mitigated libraries, host-native Clang tools, CMake tools, and an -ARM64-capable Windows SDK. Clang provides `libclang.dll` for `bindgen` and -`clang-cl.exe` for ARM64 crypto dependencies. During x64-to-ARM64 check/build, -the wrapper discovers and adds the Visual Studio-bundled Ninja to `PATH` for -native dependencies. Z3 uses the official prebuilt ARM64 static library, so it -does not inherit compiler settings from those native dependencies. Artifact -hashing uses .NET SHA256 directly because module autoloading in the -mise-launched Windows PowerShell process is not guaranteed. - -The wrapper defaults Cargo compilation to four jobs. Set -`OPENSHELL_WINDOWS_BUILD_JOBS` to a positive integer to override that limit. -A host-local mutex serializes wrapper-owned Cargo commands so concurrent -pre-commit tasks do not multiply the compiler process count. -The wrapper does not set `CL` or `_CL_`: those variables are also consumed by -`clang-cl`, where MSVC's `/MP` option can be interpreted as an input file and -break ARM64 crypto dependency builds. - -## CI Shape - -The x64 GitHub Actions jobs run on `windows-2025`; native ARM64 jobs run on -`windows-11-arm`. Pull-request mirrors labeled `test:windows` execute the matching -architecture-specific tasks: - -```powershell -mise run --skip-tools windows:lint: -mise run --skip-tools windows:test: -``` - -Pushes to `main` and manual dispatches first seed the shared caches with those -same lint and test commands. Both seed and build jobs use job-level -`continue-on-error: true`, so Windows job failures do not fail the main/manual -workflow. Opt-in PR jobs still report failures normally. After the seed job -finishes, a separate job executes: - -```powershell -mise run --skip-tools windows:build: -``` - -The server test-support suite includes the unsupported-driver contract test, so -CI does not run the focused test task a second time. The focused task remains -available for local diagnosis. - -The hosted workflow uses architecture-specific cache namespaces and does not -cache Cargo-installed binaries. - -The local aggregate `windows:ci` task can still cross-build ARM64 on an x64 -host. Hosted tests use architecture-matched runners, so ARM64 test results are -native rather than emulated coverage. - -## Validation Contract - -The generic real-MXC lanes are diagnostics and deliberately remain skip-safe. -They cannot establish hardware qualification when a prerequisite or backend is -absent. GB300 release evidence uses the separate fail-closed contract in -[`crates/openshell-driver-mxc/qualification/`](../crates/openshell-driver-mxc/qualification/README.md). -That matrix separates native Windows ARM64 evidence from x64-only NemoClaw and -Windows lanes, and records all hardware-dependent exclusions explicitly. - -A successful Windows build report should include: - -- x64 and ARM64 `cargo check` status. -- x64 and ARM64 release build status for `openshell-gateway.exe` and `openshell.exe`. -- x64 test summary. -- Native ARM64 test summary when validation runs on an ARM64 host. -- Focused unsupported-driver contract test status. -- Artifact size and SHA256 for each Windows binary. - -Warnings from Linux-only dead code are acceptable in the native Windows lane when -they come from code paths intentionally disabled on Windows. diff --git a/architecture/windows.md b/architecture/windows.md index 3f514b3fa6..2aa5f586b4 100644 --- a/architecture/windows.md +++ b/architecture/windows.md @@ -229,10 +229,13 @@ they do not silently fall back to an unisolated runtime. MXC also rejects GPU requests and `agent_socket_path` because it has neither GPU integration nor the standard in-sandbox supervisor. -The supported Windows artifacts and cross-architecture build boundary are -documented in [Windows MSVC Build](windows-msvc-build.md). An x64 host can -cross-check and cross-build ARM64, but native runtime tests and MXC -qualification must execute on the matching architecture. +The Windows release-profile build lane produces `openshell-gateway.exe`, +`openshell.exe`, and `openshell-supervisor-relay.exe` for x64 and ARM64 as +validation artifacts; the hosted workflow does not publish them. An x64 host +can cross-check and cross-build ARM64, but native runtime tests and MXC +qualification must execute on the matching architecture. See +[Windows build and validation](../CONTRIBUTING.md#windows-build-and-validation) +for contributor prerequisites and commands. ## Validation and Qualification From 63108db9d1f612cc410c59ed941f04bad7ad2b1c Mon Sep 17 00:00:00 2001 From: Shailendra Singh Date: Wed, 23 Sep 2026 11:31:49 -0700 Subject: [PATCH 3/3] docs(windows): address architecture review feedback Signed-off-by: Shailendra Singh --- .agents/skills/build-openshell-mxc-windows/SKILL.md | 5 +++-- .../skills/build-openshell-mxc-windows/reference.md | 6 ++++++ CONTRIBUTING.md | 13 ++++++++++--- architecture/windows.md | 11 ++++++----- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/.agents/skills/build-openshell-mxc-windows/SKILL.md b/.agents/skills/build-openshell-mxc-windows/SKILL.md index 58771d12f7..a7d30f63f7 100644 --- a/.agents/skills/build-openshell-mxc-windows/SKILL.md +++ b/.agents/skills/build-openshell-mxc-windows/SKILL.md @@ -121,6 +121,7 @@ The lane targets a Windows host with Visual Studio Build Tools and rustup. | Windows SDK | `where.exe rc.exe` from a Developer PowerShell | Install an SDK containing target libraries and ARM64 tools. | | Rust via rustup | `rustc --version` | Add each target being validated: `x86_64-pc-windows-msvc` and/or `aarch64-pc-windows-msvc`. The wrapper also adds the selected target. | | mise | `mise --version` | Used as a task runner only. | +| cargo-nextest | `cargo nextest --version` | Required by `windows:test:*` and `windows:ci`. Install the pinned version with `mise install --locked github:nextest-rs/nextest` before running tasks with `--skip-tools`. | | Git | `git --version` | Needed for checkout and sync work. | | PowerShell | `$PSVersionTable.PSVersion` | Windows PowerShell 5.1 works; PowerShell 7 is quieter with mise shell hooks. | @@ -262,8 +263,8 @@ crypto dependency builds. |---|---| | `windows:check:x64` | `cargo check --workspace` for `x86_64-pc-windows-msvc`, excluding unsupported Windows packages as top-level workspace targets. | | `windows:check:arm64` | `cargo check --workspace` for `aarch64-pc-windows-msvc`, with the same top-level exclusions. | -| `windows:build:x64` | Release-builds `openshell-gateway.exe` and `openshell.exe` for x64. | -| `windows:build:arm64` | Release-builds `openshell-gateway.exe` and `openshell.exe` for ARM64. | +| `windows:build:x64` | Release-builds `openshell-gateway.exe`, `openshell.exe`, and `openshell-supervisor-relay.exe` for x64. | +| `windows:build:arm64` | Release-builds `openshell-gateway.exe`, `openshell.exe`, and `openshell-supervisor-relay.exe` for ARM64. | | `windows:test:x64` | Runs native x64 workspace tests with `--no-fail-fast`, excluding unsupported Windows packages as top-level workspace targets. | | `windows:test:arm64` | Runs native ARM64 workspace tests with `--no-fail-fast` and the same package exclusions. Rejects non-ARM64 hosts. | | `windows:test:unsupported:x64` | Re-runs focused `openshell-gateway` tests for unsupported Windows driver behavior. | diff --git a/.agents/skills/build-openshell-mxc-windows/reference.md b/.agents/skills/build-openshell-mxc-windows/reference.md index 09139dac53..4ab0358d87 100644 --- a/.agents/skills/build-openshell-mxc-windows/reference.md +++ b/.agents/skills/build-openshell-mxc-windows/reference.md @@ -15,6 +15,12 @@ maintaining the existing build-only Windows MSVC lane. ## Commands +Install the pinned test runner once before using test-bearing tasks: + +```powershell +mise install --locked github:nextest-rs/nextest +``` + Use `--skip-tools` for all Windows mise tasks: ```powershell diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74d1e200a9..74beb5c6fe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -369,9 +369,16 @@ The lane supports x64 and ARM64 and builds `openshell-gateway.exe`, Docker, Kubernetes, Podman, or VM-backed execution on Windows. Install Visual Studio C++ Build Tools, a compatible Windows SDK, Rust through -rustup, mise, and the Visual Studio LLVM tools used by `bindgen`. Run every task -with `--skip-tools`; mise orchestrates the commands but does not install the -Windows compiler toolchain. +rustup, mise, and the Visual Studio LLVM tools used by `bindgen`. Test-bearing +tasks also require the pinned `cargo-nextest` tool. Install it once through +mise: + +```powershell +mise install --locked github:nextest-rs/nextest +``` + +Run every task with `--skip-tools`; mise orchestrates the commands but does not +install the Windows compiler toolchain. | Task | Purpose | |---|---| diff --git a/architecture/windows.md b/architecture/windows.md index 2aa5f586b4..bcbe9b6220 100644 --- a/architecture/windows.md +++ b/architecture/windows.md @@ -74,7 +74,7 @@ sandbox request. | Driver lifecycle | Launch and monitor `wxc-exec` | `provision` -> `start` -> `exec`; stop/delete issue `stop` and `deprovision` | | Filesystem | Read-only/read-write grants with default-deny behavior | Explicit grant-only compatibility mode; not equivalent to ProcessContainer default deny | | Portable UI policy | Supported completely | Every explicit `ui` section is rejected before provisioning | -| Governed network policy | Supported through the host proxy when enabled | Rejected because the backend cannot enforce the loopback-only proxy path | +| Governed network policy | Supported through the host proxy when enabled | Rejected because the backend cannot enforce the loopback-only proxy path; without an explicit network policy, the backend retains MXC's default-allow egress | | Supervisor relay and dynamic forwarding | Optional | Optional | Neither backend implements interactive `sandbox connect` or interactive exec @@ -112,7 +112,7 @@ The production mapping in | Policy area | Windows enforcement | |---|---| | Filesystem | `read_only` and `read_write` become MXC path grants. `include_workdir` adds the resolved working directory as read-write. The mapper normalizes separators but does not translate Linux-rooted locations into Windows paths. ProcessContainer supplies the default-deny boundary; IsolationSession supplies only the requested grants. | -| Network | An explicit network policy requires governed egress on ProcessContainer. The mapper gives MXC loopback-only egress and returns the complete network policy to a per-sandbox host CONNECT proxy. MXC denies direct Internet access; the proxy evaluates destinations, ports, TLS/L7 rules, credential bindings, and binary rules against the configured agent command as its static process identity. Network middleware configuration is rejected because the host proxy does not receive the gateway middleware registry. IsolationSession rejects network policy. | +| Network | An explicit network policy requires governed egress on ProcessContainer. The mapper gives MXC loopback-only egress and returns the complete network policy to a per-sandbox host CONNECT proxy. MXC denies direct Internet access; the proxy evaluates destinations, ports, TLS/L7 rules, credential bindings, and binary rules against the configured agent command as its static process identity. Network middleware configuration is rejected because the host proxy does not receive the gateway middleware registry. IsolationSession rejects explicit network policy; without one, it retains MXC's default-allow egress. | | UI | ProcessContainer maps graphical UI, directional clipboard access, and input injection into MXC's top-level `ui` object. An absent section maps to the restrictive UI posture. Within an explicit section, omitted fields deny. IsolationSession rejects even an empty explicit section. | | Process | MXC supplies the Windows process-isolation boundary, but the mapper has no portable equivalent for `run_as_user` or `run_as_group`; callers must not treat those fields as enforced Windows identity controls. The canonical command, environment, and working directory are launch inputs rather than process-policy grants. | | Landlock | MXC has no equivalent for the Linux Landlock compatibility mode, including `hard_requirement`. The mapper reports a non-blocking warning; Windows filesystem assurance comes from the selected MXC backend's native semantics, not Landlock. | @@ -194,9 +194,10 @@ target-readiness handshakes. The driver serializes startup against stop and delete with a per-sandbox lifecycle gate. Stop and delete signal the owned process and wait for confirmed termination before reporting success. IsolationSession delete also -deprovisions the MXC session. Process exit, mapping failure, relay failure, and -MXC invocation errors produce watch or platform events that the gateway folds -into persisted public status. +deprovisions the MXC session. Process exit, relay failure, and MXC invocation +errors produce watch or platform events that the gateway folds into persisted +public status. Policy mapping failures reject the create request before the +driver publishes a registry entry, so they do not produce lifecycle events. Runtime ownership is not durable. The registry, process handles, proxy handles, relay channels, and IsolationSession IDs live in gateway memory. A restarted