Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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, 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` | 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` | 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 <path>]` | 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
Expand All @@ -92,14 +100,24 @@ 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 package'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\<package-family>\LocalState\OpenClaw\NodeJS\node-v<version>-win-<architecture>`.
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, 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.

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
Expand Down
148 changes: 148 additions & 0 deletions docs/mxc-compatibility-evidence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# 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` 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,
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` 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. Direct host
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, 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
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.

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
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 <path>]` 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. 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 <arguments>` 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 --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`
remain `openclaw` arguments and are forwarded unchanged.
Loading