From 2de19c07d2256f96aa8585c35f9f9f174849156d Mon Sep 17 00:00:00 2001 From: "Paul Campbell (AgOS)" Date: Tue, 15 Sep 2026 11:05:00 -0700 Subject: [PATCH 1/4] Document isolated session runtime Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 97c31f3f-0c7b-43e8-b979-6418dcb7fedc --- README.md | 23 ++++- docs/mxc-compatibility-evidence.md | 139 +++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 docs/mxc-compatibility-evidence.md diff --git a/README.md b/README.md index 7ba28568..584b58e1 100644 --- a/README.md +++ b/README.md @@ -60,12 +60,20 @@ the read-only application directory the workspace. ### `clawctl` -`clawctl` exposes package readiness and launcher version information: +`clawctl` owns setup and the isolated-session operations: | Command | Behavior | |---|---| -| `clawctl setup` | On a session-capable Windows build, provision the isolated agent session, install its bundled Node.js runtime, and confirm packaged `app\openclaw.mjs` exists. | -| `clawctl setup --no-isolation` | On a session-capable Windows build, prepare the host runtime without provisioning the isolated session. It still refuses unsupported Windows builds. | +| `clawctl setup` | On a session-capable Windows build, prepare the bundled Node.js runtime, confirm packaged `app\openclaw.mjs` exists, and provision or reuse the owned isolated session. It also configures gateway sign-in recovery without starting a gateway. | +| `clawctl setup --no-isolation` | Prepare the host runtime without provisioning the isolated session. It still refuses a Windows build that cannot host one. | +| `clawctl setup --fresh [--force]` | Remove this installation's owned session and package-local state, then run setup again. Without `--force`, incomplete external cleanup stops before local state is erased. `--force` is valid only with `--fresh`; it preserves an explicit warning when cleanup of owned external resources cannot be confirmed, but still stops if bounded local deletion fails. | +| `clawctl status` | Report the recorded isolated-session state without changing it. Use `clawctl gateway-service status` to inspect the gateway. | +| `clawctl teardown [--force]` | Stop and deprovision the owned session and remove its setup state. The MSIX remains installed. | +| `clawctl pwsh` | Open an interactive PowerShell session inside the agent session. | +| `clawctl collect-logs [--output ]` | Create a redacted host-and-agent diagnostics ZIP. | +| `clawctl gateway-service start` | Start the OpenClaw gateway in the isolated session. Requires setup. | +| `clawctl gateway-service status` | Inspect the gateway without starting it. | +| `clawctl gateway-service stop` | Stop the gateway while retaining the session and its data. | | `clawctl --version` | Print the packaged launcher version. | Bare `clawctl`, `clawctl -h`, and `clawctl --help` print help without changing @@ -93,13 +101,20 @@ Commands such as `doctor`, `gateway`, and `uninstall` belong to the OpenClaw CLI and must be invoked through `openclaw`. `setup` extracts the architecture-specific runtime archive from the immutable -MSIX into the package's writable LocalState: +MSIX into the invoking user's writable LocalState: `%LOCALAPPDATA%\Packages\\LocalState\OpenClaw\NodeJS\node-v-win-`. Extraction is idempotent, versioned, and serialized across concurrent setup processes, including different Windows sessions. Setup validates existing runtimes before reuse, replaces invalid runtimes, and validates extraction before publishing it. +On a session-capable machine, setup also provisions an explicitly owned agent +session. The agent has a separate profile, so setup prepares that profile's +bundled Node.js runtime and command environment as well. Run setup before +using `openclaw`, `clawctl pwsh`, or gateway-service start. See +[MXC compatibility evidence](docs/mxc-compatibility-evidence.md) for the +session model, routing, gateway health criteria, and diagnostics limits. + The launcher places Node.js in a Windows job configured with `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`. The launcher remains alive while Node.js runs; if the launcher exits or is terminated, Windows terminates Node.js and diff --git a/docs/mxc-compatibility-evidence.md b/docs/mxc-compatibility-evidence.md new file mode 100644 index 00000000..bcf906c2 --- /dev/null +++ b/docs/mxc-compatibility-evidence.md @@ -0,0 +1,139 @@ +# MXC session runtime and operational evidence + +This document describes the packaged isolated-session implementation and the +observable guarantees it makes. It does not describe an external MXC protocol +as a stable public API. + +## Runtime boundary and MXC seam + +The launcher owns a small session contract in +`OpenClaw.Launcher\Mxc\IMxcSessionClient`. `MxcCliSessionClient` is the current +implementation: it invokes the pinned `@microsoft/mxc-sdk` CLI and confines +its preview wire details to `MxcWireProtocol` and `MxcWireModels`. The rest of +the launcher depends on the project-owned contract, so the CLI transport can +be replaced by the official .NET SDK without changing lifecycle, routing, or +gateway callers. + +`OpenClaw.SessionProtocol` is separate from that backend seam. It is the +versioned, launcher-to-guest request/result contract used for execution, +inspection, runtime installation, and collection. A backend execution request +uses a controlled `cmd.exe` command line only to start the staged helper; the +requested executable and argument vector are JSON data rather than interpolated +into that command line. + +## Session ownership and routing + +`clawctl setup` is the required lifecycle entry point. It writes package-local +setup state and records the session that this installation owns in +`session.json`. Ownership is never inferred from a machine account or profile: +unrelated agent accounts may exist, and teardown must remain safe and +idempotent. When MXC reports that this recorded provision is missing, setup +reprovisions a replacement for this installation and removes only a gateway +record that names that explicitly stale session; it neither adopts unrelated +machine agents nor disturbs a gateway record for any other session. `clawctl teardown [--force]` removes +only the recorded owned session and local setup state; it does not uninstall +the package. + +`clawctl setup --fresh` explicitly authorizes a reset of this installation. +It captures a redacted pre-reset report, performs the normal owned teardown, +then clears only the contents of the package-owned state roots before running +the ordinary setup route. It refuses unpackaged execution, never follows +reparse points, and stops without a wipe or replacement setup when teardown is +incomplete. It does not onboard OpenClaw or start the gateway. + +`openclaw` uses `OPENCLAW_SESSION` to select a route: + +| Value | Result | +|---|---| +| Unset | Use the isolated session when the MXC backend reports support; otherwise run directly on the host. | +| `0`, `false`, `off`, or `no` | Run directly on the host. | +| `1`, `true`, `on`, or `yes` | Require the isolated session. A session failure is reported; the launcher does not silently fall back to the host. | + +Unrecognized values are rejected rather than interpreted as disabled. +`clawctl status` is read-only: it reports recorded ownership and observed +state without provisioning or starting a session. + +## Agent runtime and helper + +The package application tree is immutable and runs directly from the MSIX; the +launcher does not extract, copy, hash, or repair it at runtime. The bundled +Node.js archive remains available for direct host execution, which extracts it +on demand into the invoking user's LocalState. Session setup does not prepare +that host runtime: it asks the guest helper to install the runtime under the +agent's own profile. + +The agent cannot execute the package's WindowsApps helper binary directly. +During setup, the launcher stages only `openclaw-session-host.exe` into the +shared session workspace. It does not stage the application tree. The helper +has distinct modes for launching a request, inspecting processes/listeners, +installing the agent runtime, and collecting requested diagnostics. + +Setup also installs an ASCII `openclaw.cmd` shim in the shared workspace. The +shim reads its Node.js and entry-point paths from environment variables rather +than embedding profile paths, which avoids batch-file code-page corruption. +The agent's persistent user PATH is prefixed with its bundled Node.js runtime +for independently started processes; each helper launch also supplies a +request-level PATH prefix. Together these ensure the agent resolves its own +bundled `node`, `npm`, and `npx`, not a device-installed Node.js. + +`clawctl pwsh` starts an interactive shell in the owned session. Its +environment is built using the interactive runtime policy so terminal-related +variables are retained when appropriate; redirected output does not synthesize +interactive defaults. + +## Gateway lifecycle and recovery + +`clawctl gateway-service start` starts the gateway inside the owned session; +`status` observes it without starting it; and `stop` stops it while leaving the +session and agent data intact. All require the setup record where appropriate. +The launcher does not impose an invented port: the OpenClaw configuration and +upstream default choose it unless configuration explicitly supplies one. + +Setup configures sign-in recovery for the managed gateway but does not start a +gateway. Recovery is reconciled against the package identity and records its +own failures for status reporting. It is not evidence that a gateway is +currently healthy. + +A stored gateway record is not liveness proof. Health requires successful guest +inspection, a live process with the recorded creation time, and a listener +owned by that process or one of its descendants. A missing record is +`NotStarted`; a stale record is `Stopped`; a live but non-serving recorded +process is `Unhealthy`; and failed inspection is `Unknown` to avoid starting a +second gateway beside one that could still be healthy. + +## Diagnostics and safe collection + +`clawctl collect-logs [--output ]` creates a ZIP at the supplied path or +in package state by default. It collects host diagnostics and, when the owned +session can be reached, stages selected agent diagnostics through the guest +helper. A session collection failure is a warning rather than a reason to +discard available host diagnostics. + +Agent paths are relative to the agent profile: OpenClaw logs come from +`AppData\Local\Temp\openclaw`, and configuration candidates are +`.openclaw\openclaw.json*`. The collector excludes SQLite databases and +authentication-profile files by name. JSON entries are passed through +credential-shaped-value redaction before being added. Collection is +best-effort, and the ZIP manifest warns that redaction is not a substitute for +review before sharing. + +The helper accepts only host-named sources and writes collected files to the +shared workspace. Missing sources are reported as entries rather than treated +as a collection failure, which makes a bundle useful for partial or failed +setup. The collector does not enumerate arbitrary agent-profile files. + +## Supported operational flow + +1. Run `clawctl setup` after installing or updating the package. +2. Run `openclaw ` for the upstream OpenClaw CLI, or + `clawctl pwsh` for an interactive agent shell. +3. Use `clawctl gateway-service start`, `status`, and `stop` for the managed + gateway. Use `clawctl status` to inspect session ownership and state. +4. Run `clawctl collect-logs` when reporting a problem, then review the + resulting ZIP before sharing it. +5. Run `clawctl teardown` to remove the owned isolated session while retaining + the installed package. + +The `clawctl` command tree intentionally owns only these package-management +operations. Upstream commands such as `doctor`, `gateway`, and `uninstall` +remain `openclaw` arguments and are forwarded unchanged. From eb3dc008945f1316f2c7d3eae5f35d298cf8df66 Mon Sep 17 00:00:00 2001 From: "Paul Campbell (AgOS)" Date: Wed, 16 Sep 2026 13:49:04 -0700 Subject: [PATCH 2/4] docs: correct session runtime behavior Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 97c31f3f-0c7b-43e8-b979-6418dcb7fedc --- README.md | 6 +++--- docs/mxc-compatibility-evidence.md | 26 ++++++++++++++++---------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 584b58e1..b88213fd 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,10 @@ the read-only application directory the workspace. | Command | Behavior | |---|---| -| `clawctl setup` | On a session-capable Windows build, prepare the bundled Node.js runtime, confirm packaged `app\openclaw.mjs` exists, and provision or reuse the owned isolated session. It also configures gateway sign-in recovery without starting a gateway. | -| `clawctl setup --no-isolation` | Prepare the host runtime without provisioning the isolated session. It still refuses a Windows build that cannot host one. | +| `clawctl setup` | On a session-capable Windows build, confirm packaged `app\openclaw.mjs` exists, provision or reuse the owned isolated session, and install the bundled Node.js runtime in the agent profile. It does not prepare the invoking user's host runtime. It also configures gateway sign-in recovery without starting a gateway. | +| `clawctl setup --no-isolation` | After the isolated-session support check, prepare the invoking user's host runtime without provisioning the isolated session. | | `clawctl setup --fresh [--force]` | Remove this installation's owned session and package-local state, then run setup again. Without `--force`, incomplete external cleanup stops before local state is erased. `--force` is valid only with `--fresh`; it preserves an explicit warning when cleanup of owned external resources cannot be confirmed, but still stops if bounded local deletion fails. | -| `clawctl status` | Report the recorded isolated-session state without changing it. Use `clawctl gateway-service status` to inspect the gateway. | +| `clawctl status` | Report the recorded isolated-session state without provisioning or replacing it. It asks the backend to start the recorded provision as its status probe, so it is not a passive diagnostic. Use `clawctl gateway-service status` to inspect the gateway. | | `clawctl teardown [--force]` | Stop and deprovision the owned session and remove its setup state. The MSIX remains installed. | | `clawctl pwsh` | Open an interactive PowerShell session inside the agent session. | | `clawctl collect-logs [--output ]` | Create a redacted host-and-agent diagnostics ZIP. | diff --git a/docs/mxc-compatibility-evidence.md b/docs/mxc-compatibility-evidence.md index bcf906c2..081417c1 100644 --- a/docs/mxc-compatibility-evidence.md +++ b/docs/mxc-compatibility-evidence.md @@ -50,17 +50,21 @@ incomplete. It does not onboard OpenClaw or start the gateway. | `1`, `true`, `on`, or `yes` | Require the isolated session. A session failure is reported; the launcher does not silently fall back to the host. | Unrecognized values are rejected rather than interpreted as disabled. -`clawctl status` is read-only: it reports recorded ownership and observed -state without provisioning or starting a session. +`clawctl status` preserves the recorded ownership record and does not provision +or replace a session. It is not passive: `ProbeRecordedStatusAsync` invokes the +backend `StartAsync` operation for the recorded provision as its status probe. ## Agent runtime and helper The package application tree is immutable and runs directly from the MSIX; the -launcher does not extract, copy, hash, or repair it at runtime. The bundled -Node.js archive remains available for direct host execution, which extracts it -on demand into the invoking user's LocalState. Session setup does not prepare -that host runtime: it asks the guest helper to install the runtime under the -agent's own profile. +launcher does not extract, copy, hash, or repair it at runtime. Direct host +execution calls `NodeRuntimeResolver.Resolve` and requires the bundled Node.js +runtime to have already been extracted into the invoking user's LocalState. +Normal isolated-session setup does not prepare that host runtime: +`RunSetupCoreAsync` asks the guest helper to install the runtime under the +agent's own profile. To prepare the host runtime, use +`clawctl setup --no-isolation`; it first requires the isolated-session support +check and then runs the session-free host setup. The agent cannot execute the package's WindowsApps helper binary directly. During setup, the launcher stages only `openclaw-session-host.exe` into the @@ -68,9 +72,11 @@ shared session workspace. It does not stage the application tree. The helper has distinct modes for launching a request, inspecting processes/listeners, installing the agent runtime, and collecting requested diagnostics. -Setup also installs an ASCII `openclaw.cmd` shim in the shared workspace. The -shim reads its Node.js and entry-point paths from environment variables rather -than embedding profile paths, which avoids batch-file code-page corruption. +Opening the agent shell with `clawctl pwsh` installs an ASCII `openclaw.cmd` +shim in the shared workspace: `RunPowerShellAsync` calls `InstallToolsAsync`. +Setup alone does not guarantee that shim exists. The shim reads its Node.js and +entry-point paths from environment variables rather than embedding profile +paths, which avoids batch-file code-page corruption. The agent's persistent user PATH is prefixed with its bundled Node.js runtime for independently started processes; each helper launch also supplies a request-level PATH prefix. Together these ensure the agent resolves its own From 8f8b457877c91cc63ad82c11d804cd91a41b9888 Mon Sep 17 00:00:00 2001 From: "Paul Campbell (AgOS)" Date: Wed, 16 Sep 2026 19:14:08 -0700 Subject: [PATCH 3/4] Clarify host and session runtime operations Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 97c31f3f-0c7b-43e8-b979-6418dcb7fedc --- README.md | 8 ++++---- docs/mxc-compatibility-evidence.md | 27 +++++++++++++++------------ 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index b88213fd..a9643772 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,8 @@ Every OpenClaw child process runs with `OPENCLAW_NO_AUTO_UPDATE=1`. It also reports the selected Windows Gateway session mode through the process-stable `CLAWCTL_GATEWAY_ISOLATION=enabled|disabled` environment variable. The current -interactive-session launch path reports `disabled`; the future isolated-session -launch path will select `enabled` when that session switch is implemented. +direct host launch path reports `disabled`; the isolated-session launch path +reports `enabled`. These values declare external lifecycle ownership, prevent doctor-owned service repair, disable configured background auto-updates, and expose diagnostic isolation status without claiming independent attestation. The selected OpenClaw runtime honors external supervisor mode by refusing native service @@ -65,10 +65,10 @@ the read-only application directory the workspace. | Command | Behavior | |---|---| | `clawctl setup` | On a session-capable Windows build, confirm packaged `app\openclaw.mjs` exists, provision or reuse the owned isolated session, and install the bundled Node.js runtime in the agent profile. It does not prepare the invoking user's host runtime. It also configures gateway sign-in recovery without starting a gateway. | -| `clawctl setup --no-isolation` | After the isolated-session support check, prepare the invoking user's host runtime without provisioning the isolated session. | +| `clawctl setup --no-isolation` | On a session-capable Windows build, prepare the invoking user's host runtime without provisioning the isolated session. Direct host execution also installs that runtime on demand, so it does not require prior setup. | | `clawctl setup --fresh [--force]` | Remove this installation's owned session and package-local state, then run setup again. Without `--force`, incomplete external cleanup stops before local state is erased. `--force` is valid only with `--fresh`; it preserves an explicit warning when cleanup of owned external resources cannot be confirmed, but still stops if bounded local deletion fails. | | `clawctl status` | Report the recorded isolated-session state without provisioning or replacing it. It asks the backend to start the recorded provision as its status probe, so it is not a passive diagnostic. Use `clawctl gateway-service status` to inspect the gateway. | -| `clawctl teardown [--force]` | Stop and deprovision the owned session and remove its setup state. The MSIX remains installed. | +| `clawctl teardown --force` | Confirm deletion, then stop and deprovision the owned session and remove its data and setup state. The MSIX remains installed. | | `clawctl pwsh` | Open an interactive PowerShell session inside the agent session. | | `clawctl collect-logs [--output ]` | Create a redacted host-and-agent diagnostics ZIP. | | `clawctl gateway-service start` | Start the OpenClaw gateway in the isolated session. Requires setup. | diff --git a/docs/mxc-compatibility-evidence.md b/docs/mxc-compatibility-evidence.md index 081417c1..7f868cd3 100644 --- a/docs/mxc-compatibility-evidence.md +++ b/docs/mxc-compatibility-evidence.md @@ -30,9 +30,9 @@ unrelated agent accounts may exist, and teardown must remain safe and idempotent. When MXC reports that this recorded provision is missing, setup reprovisions a replacement for this installation and removes only a gateway record that names that explicitly stale session; it neither adopts unrelated -machine agents nor disturbs a gateway record for any other session. `clawctl teardown [--force]` removes -only the recorded owned session and local setup state; it does not uninstall -the package. +machine agents nor disturbs a gateway record for any other session. +`clawctl teardown --force` explicitly confirms deletion of the recorded owned +session, its data, and local setup state; it does not uninstall the package. `clawctl setup --fresh` explicitly authorizes a reset of this installation. It captures a redacted pre-reset report, performs the normal owned teardown, @@ -58,13 +58,13 @@ backend `StartAsync` operation for the recorded provision as its status probe. The package application tree is immutable and runs directly from the MSIX; the launcher does not extract, copy, hash, or repair it at runtime. Direct host -execution calls `NodeRuntimeResolver.Resolve` and requires the bundled Node.js -runtime to have already been extracted into the invoking user's LocalState. -Normal isolated-session setup does not prepare that host runtime: +execution installs the bundled Node.js runtime on demand in the invoking +user's LocalState before launching; it does not require a prior `clawctl` +setup. Isolated-session setup is a separate route: `RunSetupCoreAsync` asks the guest helper to install the runtime under the -agent's own profile. To prepare the host runtime, use -`clawctl setup --no-isolation`; it first requires the isolated-session support -check and then runs the session-free host setup. +agent's own profile, without preparing the invoking user's host runtime. +`clawctl setup --no-isolation` selects the session-free host setup on a +session-capable build without provisioning the isolated session. The agent cannot execute the package's WindowsApps helper binary directly. During setup, the launcher stages only `openclaw-session-host.exe` into the @@ -130,15 +130,18 @@ setup. The collector does not enumerate arbitrary agent-profile files. ## Supported operational flow -1. Run `clawctl setup` after installing or updating the package. +1. On a session-capable build, run `clawctl setup` after installing or updating + the package to prepare the isolated agent session. For host-only use, + `clawctl setup --no-isolation` is optional because direct host execution + installs its runtime on demand. 2. Run `openclaw ` for the upstream OpenClaw CLI, or `clawctl pwsh` for an interactive agent shell. 3. Use `clawctl gateway-service start`, `status`, and `stop` for the managed gateway. Use `clawctl status` to inspect session ownership and state. 4. Run `clawctl collect-logs` when reporting a problem, then review the resulting ZIP before sharing it. -5. Run `clawctl teardown` to remove the owned isolated session while retaining - the installed package. +5. Run `clawctl teardown --force` to confirm removal of the owned isolated + session and its data while retaining the installed package. The `clawctl` command tree intentionally owns only these package-management operations. Upstream commands such as `doctor`, `gateway`, and `uninstall` From 753d8c5b275cf0db80f86cd3d960320cdf2c395a Mon Sep 17 00:00:00 2001 From: "Paul Campbell (AgOS)" Date: Wed, 16 Sep 2026 19:21:00 -0700 Subject: [PATCH 4/4] Separate host and session setup guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 97c31f3f-0c7b-43e8-b979-6418dcb7fedc --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a9643772..d31ac08b 100644 --- a/README.md +++ b/README.md @@ -100,18 +100,21 @@ token reaches that CLI uninterpreted. Commands such as `doctor`, `gateway`, and `uninstall` belong to the OpenClaw CLI and must be invoked through `openclaw`. -`setup` extracts the architecture-specific runtime archive from the immutable -MSIX into the invoking user's writable LocalState: +Host-mode setup (`clawctl setup --no-isolation`) and direct host execution +extract the architecture-specific runtime archive from the immutable MSIX into +the invoking user's writable LocalState: `%LOCALAPPDATA%\Packages\\LocalState\OpenClaw\NodeJS\node-v-win-`. Extraction is idempotent, versioned, and serialized across concurrent setup processes, including different Windows sessions. Setup validates existing runtimes before reuse, replaces invalid runtimes, and validates extraction before publishing it. -On a session-capable machine, setup also provisions an explicitly owned agent -session. The agent has a separate profile, so setup prepares that profile's -bundled Node.js runtime and command environment as well. Run setup before -using `openclaw`, `clawctl pwsh`, or gateway-service start. See +On a session-capable machine, ordinary `clawctl setup` instead provisions an +explicitly owned agent session. Its separate profile receives the bundled +Node.js runtime and command environment; it does not prepare the invoking +user's host runtime. Run setup before using `clawctl pwsh` or gateway-service +start; `openclaw` installs the host runtime on demand when it runs directly. +See [MXC compatibility evidence](docs/mxc-compatibility-evidence.md) for the session model, routing, gateway health criteria, and diagnostics limits.