From 9aa1df286c2b6fd59b4c101201ddae0ae6000324 Mon Sep 17 00:00:00 2001 From: Chaz Gordish Date: Thu, 10 Sep 2026 18:04:34 -0700 Subject: [PATCH 1/3] Add Gateway isolation status plugin Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/gateway-msix.yml | 10 + README.md | 35 ++- plugins/gateway-isolation/index.js | 265 ++++++++++++++++++ plugins/gateway-isolation/index.test.js | 142 ++++++++++ .../gateway-isolation/openclaw.plugin.json | 17 ++ plugins/gateway-isolation/package.json | 23 ++ scripts/Build-Payload.ps1 | 96 +++++++ scripts/Test-GatewayIsolationPlugin.Tests.ps1 | 161 +++++++++++ src/OpenClaw.Launcher/GatewayIsolationMode.cs | 18 ++ src/OpenClaw.Launcher/GatewayLauncher.cs | 10 +- src/OpenClaw.Launcher/Program.cs | 2 + .../GatewayLauncherTests.cs | 24 ++ tests/OpenClaw.Launcher.Tests/ProgramTests.cs | 11 +- 13 files changed, 800 insertions(+), 14 deletions(-) create mode 100644 plugins/gateway-isolation/index.js create mode 100644 plugins/gateway-isolation/index.test.js create mode 100644 plugins/gateway-isolation/openclaw.plugin.json create mode 100644 plugins/gateway-isolation/package.json create mode 100644 scripts/Test-GatewayIsolationPlugin.Tests.ps1 create mode 100644 src/OpenClaw.Launcher/GatewayIsolationMode.cs diff --git a/.github/workflows/gateway-msix.yml b/.github/workflows/gateway-msix.yml index 15d1530d..336937ef 100644 --- a/.github/workflows/gateway-msix.yml +++ b/.github/workflows/gateway-msix.yml @@ -48,6 +48,11 @@ jobs: cache: true cache-dependency-path: Directory.Packages.props + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: ${{ env.NODE_VERSION }} + - name: Restore run: dotnet restore .\OpenClaw.Gateway.MSIX.slnx @@ -67,6 +72,11 @@ jobs: run: > .\scripts\Test-WorkflowPackageVersion.Tests.ps1 + - name: Test Gateway isolation plugin + shell: pwsh + run: > + .\scripts\Test-GatewayIsolationPlugin.Tests.ps1 + build-package: name: Build OpenClaw npm package runs-on: ubuntu-latest diff --git a/README.md b/README.md index f5d4df6d..11b263b7 100644 --- a/README.md +++ b/README.md @@ -41,13 +41,18 @@ copy, repair, or otherwise change package files at runtime. Every OpenClaw child process runs with `OPENCLAW_SUPERVISOR_MODE=external`, `OPENCLAW_SERVICE_REPAIR_POLICY=external`, and -`OPENCLAW_NO_AUTO_UPDATE=1`. These declare external lifecycle ownership, -prevent doctor-owned service repair, and disable configured background -auto-updates. The pinned OpenClaw `v2026.8.2` release honors external supervisor -mode by refusing native service mutation and OpenClaw self-update with guidance -to use the external supervisor's workflow. This behavior belongs to upstream -OpenClaw; the launcher does not reserve, reject, or rewrite upstream command -arguments. +`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. +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 pinned OpenClaw +`v2026.8.2` release honors external supervisor mode by refusing native service +mutation and OpenClaw self-update with guidance to use the external supervisor's +workflow. This behavior belongs to upstream OpenClaw; the launcher does not +reserve, reject, or rewrite upstream command arguments. OpenClaw inherits the terminal's working directory; the launcher does not make the read-only application directory the workspace. @@ -100,7 +105,10 @@ both: Changing only the workflow-dispatch default does not change automatic builds. For a one-time override, run **Build OpenClaw Gateway MSIX** manually and provide a tag, branch, or preferably a full 40-character commit SHA in -`openclaw_ref`. +`openclaw_ref`. Payload composition validates that the selected OpenClaw +runtime can discover and load the packaging-owned Gateway Isolation plugin +with its required read-only route shape; incompatible older refs fail instead +of producing a package without status UI. The payload artifact records the requested ref and resolved upstream commit in `payload-metadata.json`. That build-only file is not embedded in the MSIX. @@ -125,9 +133,14 @@ dotnet test .\OpenClaw.Gateway.MSIX.slnx ` ``` `scripts\Build-Payload.ps1` npm-installs an OpenClaw package into an expanded, -architecture-specific application tree. `scripts\Build-MSIX.ps1` copies that -tree into package content, rejects any Node.js executable or runtime archive, -creates a per-file inventory, and then creates an unsigned NativeAOT MSIX. +architecture-specific application tree and provisions the packaging-owned, +enabled-by-default Gateway Isolation plugin into OpenClaw's bundled plugin +directory. The plugin adds a read-only **Gateway Isolation** tab to the Control +group and serves it through an authenticated, sandboxed plugin route. It reads +only the launch-time `CLAWCTL_GATEWAY_ISOLATION` value and registers no mutation +RPC or process control. `scripts\Build-MSIX.ps1` copies that tree into package +content, rejects any Node.js executable or runtime archive, creates a per-file +inventory, and then creates an unsigned NativeAOT MSIX. `scripts\Build-LocalMSIX.ps1` can reuse a successful workflow payload or a local payload directory. The Node.js used by the payload build jobs is build infrastructure only and is not copied into the MSIX. diff --git a/plugins/gateway-isolation/index.js b/plugins/gateway-isolation/index.js new file mode 100644 index 00000000..7690e828 --- /dev/null +++ b/plugins/gateway-isolation/index.js @@ -0,0 +1,265 @@ +const ISOLATION_ENVIRONMENT_VARIABLE = "CLAWCTL_GATEWAY_ISOLATION"; +const STATUS_PATH = "/plugins/gateway-isolation/status"; + +export function readGatewayIsolationMode(env) { + const value = env[ISOLATION_ENVIRONMENT_VARIABLE]; + return value === "enabled" || value === "disabled" ? value : null; +} + +export function renderGatewayIsolationPage(mode) { + if (mode !== "enabled" && mode !== "disabled") { + throw new TypeError("Gateway isolation mode must be enabled or disabled."); + } + + const enabled = mode === "enabled"; + const status = enabled ? "Enabled" : "Disabled"; + const command = `clawctl gateway-isolation ${enabled ? "disable" : "enable"}`; + const tone = enabled ? "ok" : "warn"; + + return ` + + + + + Gateway Isolation + + + +
+

Gateway Isolation

+

Diagnostic launch mode reported by the Windows launcher.

+
+
+
Reported Gateway Isolation
+
+ ${status} +
+
+
+
+
Change with CLI
+
Run from the signed-in user session on the Gateway host.
+
+
+ ${command} + +
+
+
+
+
+ + +`; +} + +function writeHtmlResponse(response, statusCode, html) { + response.writeHead(statusCode, { + "Cache-Control": "no-store", + "Content-Security-Policy": + "default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; frame-ancestors 'self'", + "Content-Type": "text/html; charset=utf-8", + "Referrer-Policy": "no-referrer", + "X-Content-Type-Options": "nosniff", + }); + response.end(html); +} + +export function createGatewayIsolationPlugin(env = process.env) { + const launchMode = readGatewayIsolationMode(env); + + return { + id: "gateway-isolation", + name: "Gateway Isolation", + description: "Reports the Windows launch mode selected for the running Gateway.", + register(api) { + api.session.controls.registerControlUiDescriptor({ + surface: "tab", + id: "gateway-isolation", + label: "Gateway Isolation", + description: "Read-only Windows Gateway isolation status.", + icon: "shield-check", + group: "control", + order: 20, + path: STATUS_PATH, + requiredScopes: ["operator.read"], + }); + api.registerHttpRoute({ + path: STATUS_PATH, + auth: "gateway", + match: "exact", + handler(_request, response) { + if (!launchMode) { + writeHtmlResponse( + response, + 503, + "Gateway Isolation unavailable

The Windows launcher did not provide a valid Gateway isolation mode.

", + ); + return true; + } + writeHtmlResponse(response, 200, renderGatewayIsolationPage(launchMode)); + return true; + }, + }); + }, + }; +} + +export default createGatewayIsolationPlugin(); diff --git a/plugins/gateway-isolation/index.test.js b/plugins/gateway-isolation/index.test.js new file mode 100644 index 00000000..2e5c09dd --- /dev/null +++ b/plugins/gateway-isolation/index.test.js @@ -0,0 +1,142 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { + createGatewayIsolationPlugin, + readGatewayIsolationMode, + renderGatewayIsolationPage, +} from "./index.js"; + +function registerPlugin(mode) { + const descriptors = []; + const routes = []; + const plugin = createGatewayIsolationPlugin({ + CLAWCTL_GATEWAY_ISOLATION: mode, + }); + plugin.register({ + session: { + controls: { + registerControlUiDescriptor(descriptor) { + descriptors.push(descriptor); + }, + }, + }, + registerHttpRoute(route) { + routes.push(route); + }, + }); + assert.equal(descriptors.length, 1); + assert.equal(routes.length, 1); + return { descriptors, routes }; +} + +function invokeRoute(route) { + const result = { + body: "", + headers: {}, + statusCode: 0, + }; + const handled = route.handler( + {}, + { + writeHead(statusCode, headers) { + result.statusCode = statusCode; + result.headers = headers; + }, + end(body) { + result.body = body; + }, + }, + ); + assert.equal(handled, true); + return result; +} + +test("accepts only the exact launcher isolation values", () => { + assert.equal(readGatewayIsolationMode({ CLAWCTL_GATEWAY_ISOLATION: "enabled" }), "enabled"); + assert.equal(readGatewayIsolationMode({ CLAWCTL_GATEWAY_ISOLATION: "disabled" }), "disabled"); + for (const value of [undefined, "", "ENABLED", "unknown"]) { + assert.equal(readGatewayIsolationMode({ CLAWCTL_GATEWAY_ISOLATION: value }), null); + } +}); + +for (const expected of [ + { + mode: "enabled", + status: "Enabled", + command: "clawctl gateway-isolation disable", + tone: "status--ok", + }, + { + mode: "disabled", + status: "Disabled", + command: "clawctl gateway-isolation enable", + tone: "status--warn", + }, +]) { + test(`renders the exact ${expected.mode} read-only status`, () => { + const html = renderGatewayIsolationPage(expected.mode); + assert.match(html, /Gateway Isolation/); + assert.match(html, /Reported Gateway Isolation/); + assert.match(html, new RegExp(`>${expected.status}<`)); + assert.match(html, /Change with CLI/); + assert.match(html, /Run from the signed-in user session on the Gateway host\./); + assert.match(html, new RegExp(expected.command)); + assert.match(html, new RegExp(expected.tone)); + assert.match(html, /aria-label="Copy command"/); + assert.match(html, /Copy the selected command manually\./); + assert.match(html, /copied = document\.execCommand\("copy"\)/); + assert.doesNotMatch(html, /next manual Gateway restart/i); + }); +} + +test("registers one read-only Control tab and one authenticated sandbox route", () => { + const { descriptors, routes } = registerPlugin("enabled"); + assert.deepEqual(descriptors[0], { + surface: "tab", + id: "gateway-isolation", + label: "Gateway Isolation", + description: "Read-only Windows Gateway isolation status.", + icon: "shield-check", + group: "control", + order: 20, + path: "/plugins/gateway-isolation/status", + requiredScopes: ["operator.read"], + }); + assert.equal(routes[0].path, descriptors[0].path); + assert.equal(routes[0].auth, "gateway"); + assert.equal(routes[0].match, "exact"); + + const response = invokeRoute(routes[0]); + assert.equal(response.statusCode, 200); + assert.equal(response.headers["Cache-Control"], "no-store"); + assert.match(response.headers["Content-Security-Policy"], /frame-ancestors 'self'/); + assert.match(response.body, />Enabled { + const env = { CLAWCTL_GATEWAY_ISOLATION: "enabled" }; + const plugin = createGatewayIsolationPlugin(env); + env.CLAWCTL_GATEWAY_ISOLATION = "disabled"; + const routes = []; + plugin.register({ + session: { + controls: { + registerControlUiDescriptor() {}, + }, + }, + registerHttpRoute(route) { + routes.push(route); + }, + }); + + const response = invokeRoute(routes[0]); + assert.match(response.body, />EnabledDisabled { + const { routes } = registerPlugin("invalid"); + const response = invokeRoute(routes[0]); + assert.equal(response.statusCode, 503); + assert.match(response.body, /did not provide a valid Gateway isolation mode/); +}); diff --git a/plugins/gateway-isolation/openclaw.plugin.json b/plugins/gateway-isolation/openclaw.plugin.json new file mode 100644 index 00000000..b07da303 --- /dev/null +++ b/plugins/gateway-isolation/openclaw.plugin.json @@ -0,0 +1,17 @@ +{ + "id": "gateway-isolation", + "name": "Gateway Isolation", + "description": "Reports the Windows launch mode selected for the running Gateway.", + "enabledByDefault": true, + "enabledByDefaultOnPlatforms": [ + "win32" + ], + "activation": { + "onStartup": true + }, + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + } +} diff --git a/plugins/gateway-isolation/package.json b/plugins/gateway-isolation/package.json new file mode 100644 index 00000000..ced9c931 --- /dev/null +++ b/plugins/gateway-isolation/package.json @@ -0,0 +1,23 @@ +{ + "name": "@openclaw/gateway-isolation", + "version": "2026.8.2", + "private": true, + "description": "Read-only Windows Gateway isolation status", + "type": "module", + "scripts": { + "test": "node --test index.test.js" + }, + "peerDependencies": { + "openclaw": ">=2026.8.2" + }, + "peerDependenciesMeta": { + "openclaw": { + "optional": true + } + }, + "openclaw": { + "extensions": [ + "./index.js" + ] + } +} diff --git a/scripts/Build-Payload.ps1 b/scripts/Build-Payload.ps1 index a823b9da..42d110a0 100644 --- a/scripts/Build-Payload.ps1 +++ b/scripts/Build-Payload.ps1 @@ -12,6 +12,7 @@ param( ) $ErrorActionPreference = 'Stop' +$repositoryRoot = Split-Path $PSScriptRoot -Parent $package = @(Get-ChildItem -Path $PackageDirectory -Filter '*.tgz' -File) if ($package.Count -ne 1) { @@ -61,6 +62,101 @@ foreach ($requiredPath in @('package.json', 'openclaw.mjs', 'dist')) { } } +$pluginSource = Join-Path $repositoryRoot 'plugins\gateway-isolation' +$pluginFiles = @('package.json', 'openclaw.plugin.json', 'index.js') +foreach ($pluginFile in $pluginFiles) { + $sourcePath = Join-Path $pluginSource $pluginFile + if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) { + throw "Gateway isolation plugin is missing required file: $sourcePath" + } +} + +$pluginManifest = Get-Content ` + -LiteralPath (Join-Path $pluginSource 'openclaw.plugin.json') ` + -Raw | + ConvertFrom-Json +if ( + $pluginManifest.id -ne 'gateway-isolation' -or + $pluginManifest.enabledByDefault -ne $true -or + $pluginManifest.activation.onStartup -ne $true +) { + throw 'Gateway isolation plugin manifest is not enabled for Gateway startup.' +} + +$bundledPluginsDirectory = Join-Path $installedPackage 'dist\extensions' +if (-not (Test-Path -LiteralPath $bundledPluginsDirectory -PathType Container)) { + throw ( + 'The pinned OpenClaw payload does not expose the supported bundled ' + + "plugin directory: $bundledPluginsDirectory" + ) +} +$pluginTarget = Join-Path $bundledPluginsDirectory 'gateway-isolation' +if (Test-Path -LiteralPath $pluginTarget) { + throw ( + 'The OpenClaw payload already contains a gateway-isolation plugin; ' + + 'refusing to replace upstream content.' + ) +} +New-Item -Path $pluginTarget -ItemType Directory | Out-Null +foreach ($pluginFile in $pluginFiles) { + Copy-Item ` + -LiteralPath (Join-Path $pluginSource $pluginFile) ` + -Destination (Join-Path $pluginTarget $pluginFile) +} + +$previousStateDirectory = $env:OPENCLAW_STATE_DIR +$previousIsolationMode = $env:CLAWCTL_GATEWAY_ISOLATION +try { + $env:OPENCLAW_STATE_DIR = Join-Path ` + $stagingDirectory ` + 'gateway-isolation-validation' + $env:CLAWCTL_GATEWAY_ISOLATION = 'disabled' + Push-Location $installedPackage + try { + $inspectionOutput = ( + & node ` + .\openclaw.mjs ` + plugins inspect gateway-isolation ` + --runtime ` + --json + ) | Out-String + if ($LASTEXITCODE -ne 0) { + throw ( + 'The selected OpenClaw payload cannot load the Gateway ' + + "isolation plugin. Exit code: $LASTEXITCODE." + ) + } + } + finally { + Pop-Location + } + + $inspection = $inspectionOutput | ConvertFrom-Json + if ( + $inspection.plugin.id -ne 'gateway-isolation' -or + $inspection.plugin.origin -ne 'bundled' -or + $inspection.plugin.enabled -ne $true -or + $inspection.plugin.activated -ne $true -or + $inspection.plugin.status -ne 'loaded' -or + $inspection.plugin.imported -ne $true -or + $inspection.plugin.httpRoutes -ne 1 -or + $inspection.httpRouteCount -ne 1 -or + @($inspection.gatewayMethods).Count -ne 0 -or + @($inspection.tools).Count -ne 0 -or + @($inspection.services).Count -ne 0 -or + @($inspection.diagnostics).Count -ne 0 + ) { + throw ( + 'The selected OpenClaw payload did not load the Gateway isolation ' + + 'plugin with the required read-only runtime shape.' + ) + } +} +finally { + $env:OPENCLAW_STATE_DIR = $previousStateDirectory + $env:CLAWCTL_GATEWAY_ISOLATION = $previousIsolationMode +} + $bundledNodeFiles = @( Get-ChildItem -LiteralPath $installedPackage -File -Recurse | Where-Object { diff --git a/scripts/Test-GatewayIsolationPlugin.Tests.ps1 b/scripts/Test-GatewayIsolationPlugin.Tests.ps1 new file mode 100644 index 00000000..5b3b3ee6 --- /dev/null +++ b/scripts/Test-GatewayIsolationPlugin.Tests.ps1 @@ -0,0 +1,161 @@ +[CmdletBinding()] +param() + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$repositoryRoot = Split-Path $PSScriptRoot -Parent +$pluginDirectory = Join-Path $repositoryRoot 'plugins\gateway-isolation' +$testRoot = Join-Path $env:TEMP ( + "openclaw-gateway-isolation-$([guid]::NewGuid().ToString('N'))" +) +$packageSource = Join-Path $testRoot 'package-source' +$packageDirectory = Join-Path $testRoot 'package' +$payloadDirectory = Join-Path $testRoot 'payload' + +function Assert-Path { + param( + [Parameter(Mandatory)] + [string]$Path + ) + + if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { + throw "Expected file was not found: $Path" + } +} + +try { + $manifest = Get-Content ` + -LiteralPath (Join-Path $pluginDirectory 'openclaw.plugin.json') ` + -Raw | + ConvertFrom-Json + if ( + $manifest.id -ne 'gateway-isolation' -or + $manifest.enabledByDefault -ne $true -or + $manifest.activation.onStartup -ne $true -or + $manifest.configSchema.additionalProperties -ne $false + ) { + throw 'Gateway isolation plugin manifest is not valid for automatic startup.' + } + + $package = Get-Content ` + -LiteralPath (Join-Path $pluginDirectory 'package.json') ` + -Raw | + ConvertFrom-Json + if ($package.openclaw.extensions.Count -ne 1 -or + $package.openclaw.extensions[0] -ne './index.js') { + throw 'Gateway isolation plugin package has an invalid runtime entry.' + } + + & node --test (Join-Path $pluginDirectory 'index.test.js') + if ($LASTEXITCODE -ne 0) { + throw "Gateway isolation plugin tests failed with exit code $LASTEXITCODE." + } + + New-Item ` + -Path ( + Join-Path $packageSource 'dist\extensions\fixture' + ), $packageDirectory ` + -ItemType Directory ` + -Force | + Out-Null + Set-Content ` + -LiteralPath (Join-Path $packageSource 'openclaw.mjs') ` + -Value @' +const inspection = { + plugin: { + id: "gateway-isolation", + origin: "bundled", + enabled: true, + activated: true, + status: "loaded", + imported: true, + httpRoutes: 1 + }, + httpRouteCount: 1, + gatewayMethods: [], + tools: [], + services: [], + diagnostics: [] +}; +console.log(JSON.stringify(inspection)); +'@ ` + -Encoding utf8 + Set-Content ` + -LiteralPath ( + Join-Path $packageSource 'dist\extensions\fixture\package.json' + ) ` + -Value '{"name":"@openclaw/fixture","version":"1.0.0"}' ` + -Encoding utf8 + [ordered]@{ + name = 'openclaw' + version = '2026.8.2' + type = 'module' + } | + ConvertTo-Json | + Set-Content ` + -LiteralPath (Join-Path $packageSource 'package.json') ` + -Encoding utf8 + + Push-Location $packageSource + try { + & npm pack --pack-destination $packageDirectory --silent + if ($LASTEXITCODE -ne 0) { + throw "npm pack failed with exit code $LASTEXITCODE." + } + } + finally { + Pop-Location + } + + [ordered]@{ + repository = 'https://github.com/openclaw/openclaw' + requestedRef = '0965053fe6b9341776df147a6934b7485c60b5ca' + resolvedCommit = '0965053fe6b9341776df147a6934b7485c60b5ca' + packageVersion = '2026.8.2' + } | + ConvertTo-Json | + Set-Content ` + -LiteralPath (Join-Path $packageDirectory 'source.json') ` + -Encoding utf8 + + $previousRunnerTemp = $env:RUNNER_TEMP + try { + $env:RUNNER_TEMP = $testRoot + & (Join-Path $PSScriptRoot 'Build-Payload.ps1') ` + -PackageDirectory $packageDirectory ` + -Architecture arm64 ` + -OutputDirectory $payloadDirectory + } + finally { + $env:RUNNER_TEMP = $previousRunnerTemp + } + + $packagedPlugin = Join-Path ` + $payloadDirectory ` + 'app\dist\extensions\gateway-isolation' + foreach ($pluginFile in @('package.json', 'openclaw.plugin.json', 'index.js')) { + Assert-Path -Path (Join-Path $packagedPlugin $pluginFile) + } + if (Test-Path -LiteralPath (Join-Path $packagedPlugin 'index.test.js')) { + throw 'Plugin test sources must not be shipped in the MSIX payload.' + } + + $packagedManifest = Get-Content ` + -LiteralPath (Join-Path $packagedPlugin 'openclaw.plugin.json') ` + -Raw | + ConvertFrom-Json + if ( + $packagedManifest.id -ne 'gateway-isolation' -or + $packagedManifest.enabledByDefault -ne $true + ) { + throw 'Packaged Gateway isolation plugin manifest changed during provisioning.' + } + + Write-Host 'Gateway isolation plugin tests passed.' +} +finally { + if (Test-Path -LiteralPath $testRoot) { + Remove-Item -LiteralPath $testRoot -Recurse -Force + } +} diff --git a/src/OpenClaw.Launcher/GatewayIsolationMode.cs b/src/OpenClaw.Launcher/GatewayIsolationMode.cs new file mode 100644 index 00000000..ff8e2c36 --- /dev/null +++ b/src/OpenClaw.Launcher/GatewayIsolationMode.cs @@ -0,0 +1,18 @@ +namespace OpenClaw.Launcher; + +public enum GatewayIsolationMode +{ + Disabled, + Enabled +} + +internal static class GatewayIsolationModeExtensions +{ + public static string ToEnvironmentValue(this GatewayIsolationMode mode) => + mode switch + { + GatewayIsolationMode.Disabled => "disabled", + GatewayIsolationMode.Enabled => "enabled", + _ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null) + }; +} diff --git a/src/OpenClaw.Launcher/GatewayLauncher.cs b/src/OpenClaw.Launcher/GatewayLauncher.cs index 9f4f0fd1..32a16fe9 100644 --- a/src/OpenClaw.Launcher/GatewayLauncher.cs +++ b/src/OpenClaw.Launcher/GatewayLauncher.cs @@ -8,13 +8,15 @@ public static async Task RunAsync( string nodePath, string payloadDirectory, IReadOnlyList openClawArguments, + GatewayIsolationMode gatewayIsolationMode, CancellationToken cancellationToken, Action? log = null) { ProcessStartInfo startInfo = CreateStartInfo( nodePath, payloadDirectory, - openClawArguments); + openClawArguments, + gatewayIsolationMode: gatewayIsolationMode); log?.Invoke("Launching OpenClaw with forwarded command arguments."); using WindowsKillOnCloseJob job = WindowsKillOnCloseJob.Create(); using Process process = job.StartProcess(startInfo); @@ -42,7 +44,9 @@ public static ProcessStartInfo CreateStartInfo( string nodePath, string applicationDirectory, IReadOnlyList openClawArguments, - string? workingDirectory = null) + string? workingDirectory = null, + GatewayIsolationMode gatewayIsolationMode = + GatewayIsolationMode.Disabled) { string entryPoint = Path.Combine(applicationDirectory, "openclaw.mjs"); if (!File.Exists(entryPoint)) @@ -67,6 +71,8 @@ public static ProcessStartInfo CreateStartInfo( startInfo.Environment["OPENCLAW_SUPERVISOR_MODE"] = "external"; startInfo.Environment["OPENCLAW_SERVICE_REPAIR_POLICY"] = "external"; startInfo.Environment["OPENCLAW_NO_AUTO_UPDATE"] = "1"; + startInfo.Environment["CLAWCTL_GATEWAY_ISOLATION"] = + gatewayIsolationMode.ToEnvironmentValue(); startInfo.ArgumentList.Add(entryPoint); foreach (string argument in openClawArguments) diff --git a/src/OpenClaw.Launcher/Program.cs b/src/OpenClaw.Launcher/Program.cs index a3402c4d..3fa45336 100644 --- a/src/OpenClaw.Launcher/Program.cs +++ b/src/OpenClaw.Launcher/Program.cs @@ -142,6 +142,7 @@ internal static async Task RunAgentAsync( nodeRuntime.ExecutablePath, applicationDirectory, options.OpenClawArguments, + GatewayIsolationMode.Disabled, CancellationToken.None, log); } @@ -198,6 +199,7 @@ internal delegate Task LaunchOpenClawAsync( string nodePath, string applicationDirectory, IReadOnlyList openClawArguments, + GatewayIsolationMode gatewayIsolationMode, CancellationToken cancellationToken, Action? log); diff --git a/tests/OpenClaw.Launcher.Tests/GatewayLauncherTests.cs b/tests/OpenClaw.Launcher.Tests/GatewayLauncherTests.cs index 34bd1dbf..e8c9b23f 100644 --- a/tests/OpenClaw.Launcher.Tests/GatewayLauncherTests.cs +++ b/tests/OpenClaw.Launcher.Tests/GatewayLauncherTests.cs @@ -31,6 +31,9 @@ public void CreateStartInfoForwardsNoArgumentsUnchanged() "external", startInfo.Environment["OPENCLAW_SERVICE_REPAIR_POLICY"]); Assert.Equal("1", startInfo.Environment["OPENCLAW_NO_AUTO_UPDATE"]); + Assert.Equal( + "disabled", + startInfo.Environment["CLAWCTL_GATEWAY_ISOLATION"]); Assert.Equal( [Path.Combine(_payloadDirectory, "openclaw.mjs")], startInfo.ArgumentList); @@ -67,11 +70,32 @@ public void CreateStartInfoPreservesExplicitArguments() "external", startInfo.Environment["OPENCLAW_SERVICE_REPAIR_POLICY"]); Assert.Equal("1", startInfo.Environment["OPENCLAW_NO_AUTO_UPDATE"]); + Assert.Equal( + "disabled", + startInfo.Environment["CLAWCTL_GATEWAY_ISOLATION"]); Assert.Equal( [Path.Combine(_payloadDirectory, "openclaw.mjs"), .. arguments], startInfo.ArgumentList); } + [Theory] + [InlineData(GatewayIsolationMode.Disabled, "disabled")] + [InlineData(GatewayIsolationMode.Enabled, "enabled")] + public void CreateStartInfoReportsExactGatewayIsolationMode( + GatewayIsolationMode mode, + string expected) + { + var startInfo = GatewayLauncher.CreateStartInfo( + "node", + _payloadDirectory, + [], + gatewayIsolationMode: mode); + + Assert.Equal( + expected, + startInfo.Environment["CLAWCTL_GATEWAY_ISOLATION"]); + } + [Theory] [InlineData("update", "--yes")] [InlineData("--update")] diff --git a/tests/OpenClaw.Launcher.Tests/ProgramTests.cs b/tests/OpenClaw.Launcher.Tests/ProgramTests.cs index a32bb2ad..df55ec1a 100644 --- a/tests/OpenClaw.Launcher.Tests/ProgramTests.cs +++ b/tests/OpenClaw.Launcher.Tests/ProgramTests.cs @@ -29,12 +29,21 @@ await File.WriteAllTextAsync( nodeResolutionAttempted = true; return Task.FromResult(nodeRuntime); }, - (nodePath, appDirectory, forwardedArguments, _, _) => + ( + nodePath, + appDirectory, + forwardedArguments, + gatewayIsolationMode, + _, + _) => { launchAttempted = true; Assert.Equal(nodeRuntime.ExecutablePath, nodePath); Assert.Equal(applicationDirectory, appDirectory); Assert.Equal(arguments, forwardedArguments); + Assert.Equal( + GatewayIsolationMode.Disabled, + gatewayIsolationMode); return Task.FromResult(23); }); From 2ce86d5bf4b54809ab1b4dcf5930db74d36b6d84 Mon Sep 17 00:00:00 2001 From: Chaz Gordish Date: Thu, 10 Sep 2026 19:48:13 -0700 Subject: [PATCH 2/3] docs: attach Gateway isolation local E2E evidence Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/validation/pr-28/README.md | 129 ++++++++++++++++++ docs/validation/pr-28/e2e-results.json | 33 +++++ .../pr-28/gateway-isolation-e2e.png | Bin 0 -> 41807 bytes docs/validation/pr-28/hashes.json | 16 +++ 4 files changed, 178 insertions(+) create mode 100644 docs/validation/pr-28/README.md create mode 100644 docs/validation/pr-28/e2e-results.json create mode 100644 docs/validation/pr-28/gateway-isolation-e2e.png create mode 100644 docs/validation/pr-28/hashes.json diff --git a/docs/validation/pr-28/README.md b/docs/validation/pr-28/README.md new file mode 100644 index 00000000..fafc9dbc --- /dev/null +++ b/docs/validation/pr-28/README.md @@ -0,0 +1,129 @@ +# Gateway Isolation local end-to-end evidence + +## Why is this change being made? + +PR #28 needs evidence of the real Windows launcher starting a Gateway whose +authenticated Control UI exposes the Gateway Isolation tab. This records the +local run against packaging commit +`9aa1df286c2b6fd59b4c101201ddae0ae6000324`. + +## What changed? + +No launcher, plugin, or upstream runtime source was changed for this validation. +These files add the full-shell screenshot and sanitized machine-readable results. +The GitHub user-attachments endpoint returned HTTP 404 for the target repository, +so the evidence is stored in the PR branch instead. + +![Authenticated Control UI showing the real launcher-reported Disabled state](gateway-isolation-e2e.png) + +## How was the change tested? + +The run completed at `2026-09-11T02:45:20.860Z` on Windows x64 build +`10.0.26687.0`, using .NET SDK `10.0.401`, Node.js `24.16.0`, and Microsoft Edge +`152.0.4191.66` through Playwright in headless Chromium mode. + +### Runtime composition + +The launcher was published as NativeAOT from the exact PR commit. The expanded +x64 application came from the successful +[packaging workflow run 34546297901](https://github.com/openclaw/openclaw-windows-packaging/actions/runs/34546297901), +artifact `openclaw-gateway-payload-x64` (artifact ID `10179486438`). +That workflow's packaging commit was +`52f2a53fb62b13499ba2692d81870413fcaf943a`, not this PR. +Its recorded upstream source is OpenClaw `2026.8.2`, +commit `0965053fe6b9341776df147a6934b7485c60b5ca`. + +The PR's three shipping plugin files were copied into +`app\dist\extensions\gateway-isolation`; the plugin test file was not included. +The source and runtime `index.js` SHA-256 values matched. + +To resolve the previously reported UI/Gateway build-identity mismatch, the +Control UI was rebuilt from unmodified source at the same upstream commit, +using its frozen dependency lockfile and declared pnpm `12.1.0`. Only the +generated `dist\control-ui` tree was replaced in this validation payload. +The supported build inputs were: + +```powershell +$env:GIT_COMMIT = '0965053fe6b9341776df147a6934b7485c60b5ca' +$env:OPENCLAW_BUILD_TIMESTAMP = '2026-09-11T00:24:39.157Z' +$env:OPENCLAW_CONTROL_UI_RELEASE_BUILD = '1' +pnpm install --frozen-lockfile --ignore-scripts +pnpm --dir ui build +``` + +The timestamp came from the Gateway's canonical `dist\build-info.json`. +The authenticated WebSocket response reported: + +```text +type: hello-ok +version: 2026.8.2 +buildId: 2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z +controlUiBuildSource: bundled +``` + +The JavaScript served by the Gateway matched the rebuilt JavaScript SHA-256. +There was no custom Control UI root, cross-origin UI, edited build metadata, +mock Gateway, injected status HTML, disabled authentication, or build-admission +bypass. + +### Launcher-to-browser flow + +```powershell +dotnet restore .\OpenClaw.Gateway.MSIX.slnx +dotnet test .\OpenClaw.Gateway.MSIX.slnx --configuration Release --no-restore +dotnet publish .\src\OpenClaw.Launcher\OpenClaw.Launcher.csproj ` + --configuration Release --runtime win-x64 --self-contained +.\scripts\Test-GatewayIsolationPlugin.Tests.ps1 +.\scripts\Test-SigningInputs.Tests.ps1 +.\scripts\Test-WorkflowPackageVersion.Tests.ps1 + +# Run the published executable beside the expanded app directory. +# OPENCLAW_STATE_DIR and OPENCLAW_CONFIG_PATH point to a new test-only profile. +# OPENCLAW_GATEWAY_TOKEN contains a newly generated random token, not a real credential. +# CLAWCTL_GATEWAY_ISOLATION is absent from the parent environment. +.\openclaw.exe gateway run --port 19428 --bind loopback --auth token --ws-log compact +``` + +The profile used local Gateway mode, disabled mDNS and browser automation, and +contained no model credentials. Process inspection confirmed that the listening +`node.exe` process was a child of the published `openclaw.exe`. + +| Check | Observed result | +|---|---| +| .NET launcher tests | 54 passed | +| Node plugin tests | 6 passed | +| Synthetic payload provisioning | Passed; this is a fixture test, not the real Gateway | +| Signing-input and workflow-version tests | Passed | +| NativeAOT publish | Passed | +| Actual launcher `--version` | OpenClaw 2026.8.2 (0965053) | +| Real runtime plugin inspection | Bundled, enabled, activated, loaded, imported; one HTTP route; zero Gateway methods, tools, services, or diagnostics | +| Anonymous plugin route request | HTTP 401 | +| Authenticated plugin route request | HTTP 200; `Cache-Control: no-store`; restrictive CSP | +| Full Control UI connection | Token-authenticated `hello-ok`; bundled matching build identity | +| Normal UI navigation | Opened the Control UI, clicked Back to app from the fresh-profile model setup screen, then clicked Gateway Isolation in the sidebar | +| Rendered plugin iframe | `sandbox="allow-scripts"` without `allow-same-origin` | +| Real launcher state | **Disabled**, with `clawctl gateway-isolation enable` guidance | +| Copy affordance | Clicked Copy; button reported **Copied**. Clipboard contents were not independently read back | +| RPC errors during browser run | None observed | + +The screenshot was captured from the real rendered page after the sidebar click. +The model setup screen was exited through its normal Back to app button; no model +was configured or queried. See [e2e-results.json](e2e-results.json) for the sanitized +browser assertions and [hashes.json](hashes.json) for exact file hashes. + +### Scope and limitations + +This validates the local runtime path in an **expanded, unpackaged application +layout**, not an installed MSIX. It does not validate Store installation, +package identity, execution aliases, MSIX read-only enforcement, signing, ARM64 +execution, or an unchanged workflow payload. The UI rebuild described above is +part of the tested composition, not a workflow/source fix. + +**Disabled is the real interactive-session launcher's report.** Enabled, +missing, and invalid values are covered by unit tests only. No isolated-session +launch or isolation attestation is claimed. The CLI guidance was displayed and +copied, not executed; changing isolation remains outside this PR's scope. + +Only the validation-owned Gateway process tree was stopped after capture. The +test port was checked to be free afterward. No existing Gateway service, user +profile, installed package, or system Node installation was changed. diff --git a/docs/validation/pr-28/e2e-results.json b/docs/validation/pr-28/e2e-results.json new file mode 100644 index 00000000..c52a82f7 --- /dev/null +++ b/docs/validation/pr-28/e2e-results.json @@ -0,0 +1,33 @@ +{ + "timestamp": "2026-09-11T02:45:20.860Z", + "browser": "152.0.4191.66", + "browserEngine": "Microsoft Edge (headless Chromium)", + "launcher": "NativeAOT win-x64, unpackaged app layout", + "admissionBypasses": false, + "events": [ + { + "event": "route-auth-check", + "anonymous": 401, + "authenticated": 200, + "cacheControl": "no-store", + "csp": "default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; frame-ancestors 'self'" + }, + { + "event": "authenticated-hello-ok", + "version": "2026.8.2", + "buildId": "2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z", + "controlUiBuildSource": "bundled" + }, + { + "event": "control-ui-plugin-tab", + "state": "Disabled", + "sandbox": "allow-scripts", + "command": "clawctl gateway-isolation enable", + "realLauncherMode": true + }, + { + "event": "copy-affordance", + "result": "Copied" + } + ] +} \ No newline at end of file diff --git a/docs/validation/pr-28/gateway-isolation-e2e.png b/docs/validation/pr-28/gateway-isolation-e2e.png new file mode 100644 index 0000000000000000000000000000000000000000..e6c27a9bb2dd3bed080d698ed67d065506dfc3e4 GIT binary patch literal 41807 zcmb@uWmME()IW-e1*j+;0s;a83IftdN_UrlbPPSfP)bR6$IzY9Gr)j!w{&+6JunQz z+`-@fdG5OJ?p^D$d~p_@*xz$@e)ir3D=A3fJt2F7gM))7{Z(8A2j@X14$l40kM3fB zWAD5F00-wejjK*z7$ERE__{2P8mTKP zt?~j%`1)mUqG-yKybZ&fw`-xVB}uB7xPKe%69AJIpo52LD067F4^VG^U=KN+=roK> z!~SzRY~ejbAw45x5;GWlrKW4+?#IjIXjtFJl7S;qbxQ~K$M??*`+ozRPP*m)1|d?d zcm9oDMf%?RH+V;N2lwAVN#HL2zd@$keTshrk>f|7{|$Usi|+dx_w|e{4fXZK+$1Ku zqYwwQ{c|%jyq`aR^_iZTD^jykrXV=cx}Bb>cb`J!<99Ptv+c2i{R2vhPZ4CbX9el{ zqYIgKO9^9-(+vuSNA@^4&zQq={F=pr`G{_py`#K?`;E0(Au+yaJdSBgE8nxqHSXu* z_~NiLI@W@MrI9@SVHL{>EBVK~|K`WtCHS!1zzY1$<6J!)V@Sd`hoy(~CJL6DaKpHs zC?cIZB^xXj7+YP^x02E2^_ee0mDj>)2S#Ezqb zqJCqWjz!Fasha}d3gj`7;~yQ{_)MR7s}CQa`!e1^si;4p#Ep(i`l@w{QuyS5Ht9lp zg@nAa-FC4gh3F#l$&qo1hx>NY(69VYGQUT?YvRemumPX?grLa4{Up|L;NsUY+E=cKn_>UQqCOuF+8NGxmmoiFV&(T@#sK5J-6p z{5ar8q)j{#*bRfZrEnR z<&~m4nhIU>`sZ~ecL+o@G!p!{V2&y^$^+VtloV>fb>A`BAk?@6(_z)^(=QuUJ24x! zRfSEWH=dfJbc;&mn3gKPK#by|vs6j5(~S>apP#ZH2L|*2yo2|Ir)6KIc8w3JmW0Pz zF@4**7mLO%A9d09-mGR`h0lZV+;GC)8bxpxjNV4(YF69U9AFOcGLNORZV4vNsCWiA*%%vS z`I|;6(Be8&=X~(G?2M}}NA@*w_fJia^9+n^kn@g9`N8Jhll~6zbcgnM7GCH^*?eW! z(QHFmA=&$MVV`on#*^~$cvejYM*77j_x2J=`5(A{K8VxHKAAaLNJ%M9=UwxvAd9r5 z=-+mMTwb2mHd!wzGob&L4W|B;N7>uWI0Exy#=7}fINKe6g`EA)G%-c(O-E0bh~`?A zXq1#s8puN3s}(4h?)U}91KHk_Hm>~>U?s=Gi3krQ@-68q)%1=HUtW+wBEtgS6W!Pr zVa=kl42t7c)SY`8(6H&2YUJIetW-fMn^~l*V0$1ZjTir5$fx+R%cdrqgY``|WO>+A zcgR912{;()O}_pcwNMaLD*NfRy)`Flu3~{mNa(xl&~aENVtD^ztdGP=Fnnq0X#5+s zQL*`QE`zSwjZJBL*~JvU@QcIEG8$MpEzAxr0dX&1%8WkVFzk-(>h2U=*dV<#*O(BK z`A<8v=yGy$jsq4-w{=*T%7XCWkpfp+BQJ9DHu@hY-awDWi>QZsb!~QH0tWB?%y?vx z0UV#q4K0UrQ9KhA&o!Yp6f&%GbWyG}thbx3<}Y>Hq8j{}lE|W~@Z^22nkgzl9&-ai z#7}i;TpYdsZrJ}%Rzw~z66a0#HOb>uk&A zPst9S>fJ(z_6&NJsL{Crz2=0x)$bne42c%sq+ivJ_Hf3|6#3|akce*`Ya+s zxf(XB3hMA7Ca`%AuobX4&c+N`s7g?zbGn&^FUIyJ835ntu~+frHypo z{dHIe&|h3q{M7-5&3ono7aL5CSfixb=!OZGhSKOcA^6Q@kXB*Q$IFLwZ938rTAs*8_rMS&nPUFP5& z{0D1Lp_Y$R{K?kT(!N48QC}^&!0Ka7YuDbsp2{h$)4@|Xm$mbs(`367ksn0*AnU)S zkM)7e?F?hUEw+du(fxG(%Y}(HeLn-V>(X~*ALSq*uP0e=Vsu90S0UG7)9$4shWkr( zJ)ARw{@AKoyEN=ohAqE~h4nigy4{Iq?QXFRv3ycY<-ex#&6Y;2478fQM_q5AOPakj zhC>=-QVcp_CI$S~?|kDdt|8}%KEvs?_4PgwS>O+;$ueEb5*Q|56THQuR+t2|p2OUi zq7tle+3PZgT>R6hnIg>bn+6%-->QAvKdAnQztf$JXIP2{wb2SY-MbL4m(kd#Q};&I z<@X?8jQeP_5}i%LNOpuqM;5n^#;at*Utgz#7(B01T)YKWs zR>~XxDe=N@3GF^S#so@u;_lx&X1G=3((AO$nN@+8^gQ9+ry)Caabvixflxp=`8ypH ze!7Zk?M6TJmsD>(jp5u3|FcWj7t!Q1545n4)MUxh*Xf?6QDst6Qu)*en^5(uNsDnd zxA80Re^&fm9J*Ohb<9jmE#%{8db10BriFLrNe;&o36zij!htB)=p3~%;PrLt^PzC) zIec>Na(q;gPG!oonod90dR!1XxOg?3Y~lkqz&P+IIynE;gr4drmq?ab2r!+E2s0Ag zRC(?E+8hcN_PKIe4C?L*Xky4Cw-vrR9XM{sb@d*TpN`Whb8vAPxA?TG{E|HwrTK1r zMGRNy%HC0Kz|x4{vVP3!?+IIOt4ZXfj4YJtmd!+xLr$HeJ*VF<_w_b@g1r^qr=+cD3dsFwf>7`1F{u3rtT4l5K1S2xAhcPEEmo6}hPq z8#gRF5km&*>$nQJq1YGrx`a{){j2Egd0OA#yt29x%Sq8w5FB}C-jP_%gQ*kT?TaVj zJ^K|ZP>E>;R0qk=yg$^QNPF67{rnx5u>z)f7y7zv?z+1!ok>rhr6AwxDU&_=>O3T# z`ROg)Zf|EQaf9L`!2)$A!+13Fe$YDWnJ)^T*$!tYO%^gFTwgZ+Hc|I~?v3Wx5sJ!1 za(d-X)9!B>3M?5ME8`~SI2k_i{w;Cj3o!QdU{9YI5{AVSf%si7*HJ%iH0zrF7M;hk zLYko6Rf8z%i^P(PT|tw~$gg3Sj`P+|v}39G;Kjf49i{FEc|R&BEjVvX6={rfLLS*U zPQ6jGx|}FNt@^gDfH3tgrw@(zGcvf?44R^pkK}l^hQVdW(ulnOoqu-Ne(D9j|qLuP8Evtt@BJ`HL1#TA4tM z!~{Wt7rj!ddjfD4v{w0WU*GlNA9pUQ678>$e@=B?>R@2uBO^`c7Yi+vr~sO!4?+dv z<8`*OI~C-*JcopTD_5T@m1i$5(t@*8chw8EEJv0#HGD9G2wT`&JxJly9#+21O%#1@ zW^8bAQPWA|1sJ66?OU|c^_mHO&P^Sr1!?8(Yx!th$?A)}y{_uMJbLBD%TBY}kx_

iQ00ki4J@308s4Q`F!fqnu3%i6K7jS|Y7zuot-%~z*)9wVcYrbV zo{c94T-L5Th|-#y_24x_cHK|krwjQar(WNld-SVHyOqWVZ6Mwf-DECRb6tNk3>LaR zjj#;@?vK~nXsZ38@x>i}zGyl#voXHVI}E!~6!yj}v2RNEd!(}+Y|5{lP_7PvK`Wg< z+^1wGXXmz3UWj>Uk5v6G;!2571nwo7do^F-VF1fV8-}bD=UsCK29dAb|MRxwZHVlr z=Xk$|h=LtoR(rQI?NrDt+JcXibxRe4@%bqj5fw`*WAGUn2?|jhg0xpW-_3T_i#;LV z;#f3q%76^i!meuI^8SH=C<7scRvCYv1qB!T8MRiO9msq+|j( zv(OIn_M>T+if7RsO8L*MTN*=Yn8y;^ldnXdbnGvBX^-u@NEc_(ZT?G=Mhu${8P5_0oJk;HL_`#{EDAfc0U}y}zddc7Kk1g-pdpLicMaI6do5yAmD|C2ioaUL{9872}mS7z$Z5xy5 zL+GG7t@j5q(@)pw<>;&5f7b|%0V&D_X`Rzm+>|l&7OD7 za*9yow}}73qhMA>(psQ>Pv5|R&uJAU$nL8T(#2Af>#!?$ z0;zw5d9uxAW=$dPm(^q{PS+bP3~?5*)y|!RxC>Kseyy+V)g49%FgD%ezpyqeC{>$P zGFy7B%=+f5$HvWznp)&Osh$_mtOZXq~hYS2RVP{Y_TNu)Lf3 zekd2gumJ)k@8CMQYHKK7x~r==moHS=Jh) zow6bC>g`+qD5tcNhy+icYUq{1k~{5$^wG?&z1kkZiV zSfzLuhoa?NA;_U~>(l0SCe=yxIfR9qH>iV4waQ-*mF9u}sQCTl_M+XuUOL{Iqn@s- zt-2WVzRGz2&Iz(V+h%z?`QEiZ_swBHsp)u)rKo;er!;GtUT)t5nP=@=I#>7k=H=vj z2S!3c4C=J%>iMOiIvZ}?xVj!i8vHV;c2=>67yrW9%uiLvNuIdzCK_fs(F9?v4A>yE zYxXyrtt7t7WBuP#MGEMY{5y0W=#6RB(Js?Ng@Yz>(dpFLSBmi!;4x zObu}^L@Gx#X+JZ{8!gS9FCal#%8IcZt6Fwe4#0$luflccRLUNxR7Dd|3Mij2dx@>W!7LS?L@bc7> z_tl@oLmy)L;Sak8-KYeOPmiof-=Q0p1Pa(w$*NSHlRh+n=2`3`A1Bpd)=+(4Z(Bl#pfMEe)&}z7KOm>chZINhBv5R#VHJ?T4M_wC; zp3&=;P~k?NV))Y>LmTRe-}xn-ZufOP0R(d~Yk2W}ZHr&}j+}RRR4eEgWT077OOW(< z(?NK0GAZP&Mwh3;y27A$WUmjRmhci6gd5}uRU?U{H>EITX^=+c8OX=EPVB+^|9iNJ zO0??hXF&6muxII&4~m#Us8s@xgC(zLNI$T8(Qw}VPo)Ms{^y&{eQgw#)96h}1^@D7 zA3Vdh_OyUa$Uq*vzrJ1!qwjov!;ZK#nH|tZSwVC28Z-yJorA1PxZ~^4Xf>r7y?9OA z84h>E06Tu|zCb>D1R*O7GS4VT{1vI{LW1@v+ZR1YJqytj@Y>DdW1Fqstph|T@0py| z{5I&pr`&XWD*wbHGE#mo4iW@g*f92{p?XEmus+8S~L%Jcu( zzMXH3UNbE4dpqUtPcu02u^iks+b9v5i?v}^E^QU3y75FG0gE#ku^FdKW($99s#@;D zE3BCwt3>2$=yE;VMcA6;N7J*KE+pKGa2zU^I5aaS@h~=Lf99wEtRe&+7k8nhAt;0> z|4&!Yx8d2wH0ahHwi&&BKsa`w9(a?`pnG!4Vasc}lg=b6RP-mkBnEMyV9i@o=uC%! zgv=XzJ&t?hYBu(}nZ`~@J35S{U-!lx*bT9jXmtQ~|8rsUpjZ?vEEiQZ@JwIhBek35 zVWy*!rA%vcvO&pfHnw$wJiRIp`*ro9yx+Ip4$icw^gfn=VcufbrZN?BG5y2k|#lBh5sv)o?%S~HGaM#%6_Z9xLEJp2RnH+DzoBP&oNK!dTIe}JsIuOwg2K` zRc`x8q$tBfzkphr7`ub-11hS=I1ff7(Vxtnr(C~u@jD?4EK^%sa)=KbX=NJs1+u56 z9J1dAFQMfdJkMRK41EY`Zcl!SMRB7N5j`O*KL$M_F&z8fJ*|dzCpuW9+P(Qq(43Xy zwdS-fi7GKf_hhwHGI4fhlh7qXloR#x6|avsT{6-Q?DQqBbk_veH{RU3w_0w`o$PUZ zvvaADM*#*)9b^g3DDRUU{^3hahqx*0HDd&(&N(*cTwOxW!=r=2y-hJQ384t*wy17W zg6a;*R0zouAYNcM5;3@?O!g|H$WLx3a4F7k3a===xpTC$A2z=1o_>pA`@RgKVaEBk z)29fom?BGPGDtR!wp*74ah#2R@$$QuN@iaA=*d1m97WgF+zIE&!?g1w%kFaa(vaWNWar~S zjrHCQbmf(nB2TTWr#TgLEcaVzz<&nt9g}$wDHX-nglU|1dD}U<`>&lCob@zKdOg1A zGakM>KP|$3p8y{=CT|tJYCDh$m!(>OB8inh+btvk6ApwtRzfUOA|_a*>J@gUY{#N$ z5rpQV9<|%TmQJ~rQu@2el>G)4GkbfSDy1(cddIc2*I$^taiBMb@=8zpv^KnQ>6reC zStdFOd-VeR40%~_uS!!TJl1c!<|8hQY6cOYgxqXK^tY#y0VAHwfxUQqzIEHRFGUQW z+0c|`F7W58Vx)zs1!Ao-eBN@oVt$B+j_(NGq|WQYNXH=yN8q7XY9>auY#FN*g7E$? zZHG33mhX#X1sgr&DtMJ|g)Z+dHlLu?;Mh4o*apieLP;v%J~>rHR7+4;14)QZ_I{`q z;cL)Ixb>3A47HHCoD z=b7;8t1EIwx?Ukl<-_>N?p#?1;|xta!06idk6-RaQ>pyb$vQoV`6R6hL+m!H^Bgm#=!Ea zpSUNQG~tvlUmN`r_>D@cNp7^XTJp$Xi%{V#*Lz`C8}22tN~hR&aiI=@QP`B)UjVwK zN~jjjLbLXMnNPKxiyw;z*z$SM>wnfLnzDwMd}&nZcAB2APwjaTX%bHah~%W_$JMaw z!yJDMsGqUw6!19E>^eW^&^s~rNKp_J%1~y$edBxBH(qC97;*;e^L~$=?{CfKm#kx% z6Q-Ef$&kvC&PlNKGt{vpON}X>B+>)SkA77Z4xt1fQy~5|lvpNZ))2Bd#XktE?MHKE zBl>fcud&p=BanQt0*(CDz&U!7?UbsJ4{|<;R_}7BUpK3Pe{@i7YNQOL<8`IDjHy!X zp%OEXiZz1q;y?~ zQwR6f_tDPUhj9x#YV5eporo4TgFW8hAQ4?AH2eUi0uBab>V6%!#f>{^80Qg$}{ru3C$94Pja|aGKW2p1i;S8jc^Go0aoeO3(DOL*aj?~<@wRJKF zmWSsl#%Y?OYpXlT6=L>+Tl`kfc5lLr)OQo)RfHVh%-b7>qg+dAOV_z9`dgx+DVqk5 zMRt1!$30v;06>R7k7PA!NU?Oiqr$RH<;3@%P^zvxI?&52>r9jKJ)}DZ(!Yd_5&Y z6k3gQAKERT5rHpgY0bv1#1?6Eh6O3yZGh7W^lOl<$80)hK8w#=a_yF?fEau+B>p{= zPCB5c_#mhYV6%w6 zW5L+;qGJ*IYNEw1Ft4M`j}H%X)%x0mC*X|bxN$Xtr6?btYL+GNj`s6apiKSBBsIPn zn2IcHb_CM^`d;)(UkxN<*DG0qvjir0DPn1MUL> z)?O_%wRDIApa(8l>a1gjVi%GlC5)U2sBOt{iUNjv@hJ=)uo{+J+2WS9yn(syk#ayw zWQ8WRCpYt(2T|~(>956z@MdJ~KHLBOdMEaeQ+^B5Uhe@>+!y6BUTb9z<*S6#=y+{i zMA=9Dw>wa`^EmvjA+ux^w|_*w4W|Xb(qJOne!?5-+Y;Ju}jjmCsG(T&M7vE)Fr()>Q~S9z8kpi z3s-_1PVl;Czp#4F4}dK6Jny0u488UXh~>JA1TFekCOJX4e_j73DHb?fNE-$m-W2NJ zx#Op9YsbfBb9{Q9#+7Z~Da>~(L+6tH#O~*%gF2JV|dvAi{ryOFGuf2?7$yv zp+-dubM4l*QBr0N4VEQTSlQlQ3R9a4i%#avX+8xTS>09&7>3&h{|^=rCo0GB1Sj&L z`JqCrMi9G&SQFN@@>L0zmOL&riBZPR#wHozrZLJM|1UE4i(c+>`&T2>dBPxsyTa{S z9GrO{Zg`u+&RAy!k)jDoz_jAqW>}lA2E`9C$oT;}L>Uv!~zVojl0f)$j(B2bvVh!eV z(Gi+qIApLiJ>ZL!eQ@6%P_8e}>$xqmW_AZ=H}m!%p_SkKq$M!|Zmk7~wK2sn4|3%n zKTgawR=m$md?D_`YkUy6z{qAX3C9D&$4l~{Iy$7)=16dP^K8MvqZxMr=>yDwuQzLd z+Rb^83qSj#3hrS%Tf^=TbrK-st=V(bkd?YRdHvxOdu6eXh;pv8$rANSI@A@jG_*7e zbkq4q!nZbVMdeWo$4&OApJDqO`{H7%X^-($axN$bdc5DWrsn33buC({%{KXhIbh95?#^1>!jGr!PNN zsX!c#MfF?=*e#K(0hiFdS_fXMt=2oq6gk!d^`G!o<}y@HJ8nk zFN(uADr7#TH>Vo=;#{IJtp|ULK zW==NPYsi5`eU|+FI1w2he3G&7BSEN@`xK)1IO*Rdz2PCprFhA-@F9>aL7z7y&$U9j z-6;d=XnA^ODU}DSmG1phD@}P?t(LYcw8so1`)6`eqCw4dP~Ygc+Ix4@ ze$||lMq`%&k^KAv8NPG{#yoPxSi65GJTa{p6`1%5&68akU>#9Hf2SRDCRps0$@uBICAQlQg}pEuSl@`9E-wh#1Y!7+0Kn|u5ClqM;#0B(2XwEk!EhSHtK^Z`s4yg@#Jxs-7g3O zY=lamb1%IUwuFv#Id0Wcl$VFa-}DE9o14AVm?x=0KyyrP-omR^FV*J$4)uN_5}z*h zr{rL-AdTkkf_|ZGWqpBHDkmoz7C#+ka)xnBgmzYFj*hfj*kx=*&NmO38NvKuG~bGn z`0uZLj_>%B8c2W|4Ink29@wo99#D;b9*@d*oErt?vuXdf=`%pa_my;R^UOhX>Ps+{ z4rn4ay&JfjJ6uIQFH^I-w)nl$YCO;tKCwZX_~bPO1x0RUj^tpkh>+`~$}NU)io zZ+lVcc=+DbQ})>ScUTP=M@ZoH(_)=^rch{dgj)Sv>M3LgV8uDXrm*V?bT|}p zvICxm7B@2t9-8Vo+j4FCX^2)dGw3nfo0qUMiIc_*1O$l}Cr6sudr1gi=u)`Or&19ak zz6jY|c|(cR1lGT@hW*3*(faPEVuu4dv2Qzqwb|`lyuMhqx;KiRej(&0tKYPfrXuR} zUurO=yBAi5u7@Hs9e+4^5rsW|8NhY9+EvdGlTsZNda#0TnFxPXYar( z)+zBoovHn)Ix)}~{=Zu_O&*EMIz;E2dIx$NtaUeYX92QC)-iHreFaS`a$AUCYJexP zqkgOBoJoVsmp1eIK>gDB?2>6%=ZRO59WqeIAmpwhO?{d%tJHea3tssc7Gk7c^8Ukl z2kjF~?#3zAgPIe2s-8aMq`ky?B#HuC<4LD%Nv=%3rW^Ssi6xHxilB0W?_a37*Mi!x-*z#Y zjYmXZT~WP)_Q=wiP9fan#u^sfo`-j&79ck;+ohAa3SE_$SinLIwY%fyneZ5RroX(r zoHUtq@UG3-lDms`A~gKn1l#NTIIlEaDs)zR0z&fv)$+9XUxCIY>ll+*K&vR7$5$TC z6G}Dl@y7mV^*Mo{(cKxJVQ$R-%^1erd#(d>{!VDrpwn;G+~`9%NYLq0hJ@(*g^w1tI1S$ zz2B`abVq!h1vw|jT5Mo}%&k0z5$M#~ ztLkhFdG#RU4<*8@HaEYj_C!6UuBr=H z@MlW>wbgi5s9@MkTh>xe9=S~@1tW|=@&~x439tH_!<(IVth(W6g)cM(|B$$MfMp%a zwCR=}Zh0*|^@7zwB6Sfzc>9xTD+6EM`2^5(PjD98@Szi@i1K@;T1-nhQDGXTCWe5% z*?6D*?Qzget(%h=58^Si=d(oQJxhxtf$^X$-=%y)8dR@Q|A;I2 zrJjGFuHSexPP}}F{k|qoy#UV?aTnPvgW|;-FT6$m<%oo@JoWKT3LQC$7YSXwZ`M~{ zdZViqj|RW6%D>)(%sL_oaq%|dEzwS8Ueh1i7OKF z$amBd5uCYt!)|>ic@|_!g4oA$UwY~Tll%^hiyG>8Svm{~2j4NFV^4$4|CY5smvwLy z9Q(4z!$ZXFqmdUAkOrEh0;DX>Go}(9(bRmu5h3$F^xw&RaLqkQ{r$=`kuBX}U7>tD z&iX@I=$DOUA?JB)c^yra_V)5_Unvoe3{(5FP}akywrYxFqx~Y~W#WYgUmNVDC#*~z zhBey9-Ap!Ld~%G}x?Zj1c|vj=Ee2tHHJPHzJ7+OeNi6N9?CDPC$+NygWi{DQ9V5WF zsy+Vc!1TJaF9VsL>0H~{Qn5IFp^hM%N&%kzuFAirTwmln4yY}tL~?EHIVn@I##9%Z z8Wkv!M0U&FJ9Cu$+Iw-m&^xdB}2Dy=VL_cbO`+030mptGV z-*sQBV@=`_VW(!;62s0Xi8BEt&qV3(0!v>4EYrGetKY$q_~5LYlmzm|9lw7kkcQdO zzH+u^@q|jNrQ}tB;DT1m&PQeQd&MvI}@a((RdA@sV zCoKE&#JVzk9Z1`SGIH8B(PIpf|MOuTi@)nxN7UW~Q$2_i2BY$_ZW6FJ@%-f6a)xnu z;3@G_zJNb^mpn6PD@Ar>9W(``;i*qRD2!HwVff+?tuS`OCTs>L- z;`2^(G$7V9C0=l8Raz1ozI^C&mwS&Ra9<_rxT{H)xB2hjdsu`})9?hVC{@XCcITWT zfM>_Bb%@6s7ZDa%sBU6X#upY!YwslIYV#!VZ&k>)8iU#=6`~McxhJTJ>$nlI8L43> zTF0%Ys<6lHVj_6!{CuZh!=Gl!hRiItliOapP0TaW@<@^dO7v*H@o+&rE`Q8<0VyPV z{`T*{lGemmf13x1icg+$$-}?7Jq;7%ePX4UmAhAcSkeiMh+{f>1^<4$qAhSJ4uA1H zYh1$+f~q1w^6U?}%1FzcrIhu~psm+?*2bb20vkV+s!yXftVRRdpTc5J$kuw^v~MSk z(A7R;&+`lUB@dO?I=MQm~mBk3K0N!|K8E-mLH^uB_vskr|K6g0yx{J(xrXtV1L8>*C z(9q5N@1>E^N$8bd*JPxD{$+HSn6ljYxcmdO_<+yr1>WO;@O4vSx~Lz|UEy0=+}o zk)Fn_g79Ig#&5GFt*Q-vade)1`*`hxje5EY1vHJ3Vm&i#gQ0f5??i6!pnmhCVp?6K zfpeE!ogfh#qr)k^=<$dBL1AB!{Y@3(K5Me>@W>CRy&C7wjW+8C0Q0}^g5-K)bDuqp zmiqnm^~6O<#zN8yTsdk~U)vg_VF*=E63%nO{W{7)?clgK)2ZDNP5oe4?hej!R`qyZ z!QP><6B3Ix^q|MnF6i1j5cUBz_O3RZu96n}sN zf7<>la`o&0_lf;>b(9xxq#rhf7P%qGzKg?6H|&?hIkbc&D!OxLj$qx$ljD~_c5X7( zCl<*f$^I!tDW-NCSY-Nt`}JQ??3VlgTaEnxZd7gB>VQJnrYo2?N_sGry}CUS2j?P| z^PRACmwRlW?t!* z-BaGxRvSFBf59w}QX%A72Az2)IxAARiBZQ|?=O{p{YemI)xY!{RvXo&`L$Qcky3;C z60AKvsesPTaYWc6K=0Co`r6mQ*0?~-+Gx4z!GsqmC*(Z^=~d^hSmz_f5W1B_fX0nS z*QZ|vw~@qF3)!20bc#GS@uOkx?d>II??~rGN7m>Kw&&PF5o4mo8svnh!}0$8ru~Vh zMfwFgT#>624H%^+&DgAFW_lY8&8q)V1$)H=)j}l#Jd3{Kvj5n`*TQ{vw&s<>5DJ6dGc0DSwwccTuDqW~Vbv!7WZC)Ao@~CyzB)^ciIx!CCEcpxPF98Ck4w3jS z0EyBoySd&^1s>^v_)nbU_vAvCs@)fc2p@ZF>0s#s&92SQjw~>$1RyGEW!d=E@%N{O zkv%c#+2hNuLZa)yS1z^W?t^ zosPrvuy1HkJ1RoEbr0$1fz1Zj@$sbysAn5i3Tjd<74JXf<>#lKzCisQB|;x-GdPETdF<_v5_X#a8Ye79DvPV152=&$SWHik zOLPEIctPs9#XFq((E9gIo*VnTd#my&xZY`Ju@l!E&`R^*54)i!x7Y4iI~yxMu%u`S z)1DT^sgmsP0v^`(X=}#T;anl}(GZ)VV%hRYo}-few|$T+>3CrSY1Wt=T1D|*FNqW3 zkgq~6*CU(sPl5Sdc1z98pg%)^mTPrpukXm3k^Xa3M8@SwEDz9|7v%Kw9|z#nnfg&t zFvt7JY^W8*lpLEDYoMkKyB|KIpk>{2hCIYe{bV!Ydy$nBNUWnP5I$H}(O?z#t7(R6 z&@UX>yete^xap^l3}n4m(kBJA5wMue2uD)o#e2ST8S$Uu@2QS@7y|3AxI(2_M5i!6 z_@EH4$I?(ocJZa%npENcJaq!z-3b1Uj%(Ed1^u-XEDXr+3THN@jznEiPG3OP??_Dy ziK)<5+RfI;pRhDPuXjC^$M=|3*ZPtg_g*h`;$s1gf(y0NYpK|9Cx1v1VbYVKp)qj$ zVWHB&dW@sz7bEixr5Yua`;@r>R+9o0{c)oP&|Q@*;}xisl(?B&oqJ2VyQIoN z7AuT`FXh@9HQyOC_~Q?ynrLdwdvW!(lH6BiwdREj=$U=_Vk&_5$XIph)zP10mZvOw zO*w84VK>T^2A~_cj!kL}d0hq}N>Vk)46lC>nTX{#ly8nr;%^2cjxRlM-=2EV;l^s4HpDKHD`tfSx&&+AI6-bzA z;rY}JR*m{6X4w%lW;J_ivlkaTg%CNvdXZ?@$=E^;dwbAG5QIBbX4cuo__=rzfpC4D*59aEUZ}$R=-=0ok|yu)VY_mGXi1%uNi{%4F#^HuruR^W z`WC5g;9*pxfO(@mlui?7tn2I+m0Frk*IK+Mi`_}U#2{|&%_0P4D7;PiEn2?p-Cp*P zxgWQD!{;KW5Ys{@10BO=ME-{XPOHf;p-!*7W^13R2dvgVx>)#sn#;^jGR@Jh+-z+* zRvW)nK4Wj)H)f@4P?wmE5jjz))ABwN@GjlXBDQ1U_m|e_tSL;LSEx*$f^-6P)@;e) zsjI6iR)=(_@g8X9%Q>oKM-H!@@A6=~mavfdeTp7g5PEYX*E(Zz{?@R|WL(My!|h({ z_eDFzi4yQGe~?j7h;hWT%rfqj>3R^%RULAdfcOqBJSsWa<>UcqaJ4#YU?Uq=mq z6WE@H+hmnLi)LMzWErHmnFfawn^Np?*h`3rh`{b1^35CoPRL-x;k=@^4&?odNm>ux;r}&WEoq}u-oB`3D1q$jr!f=wc+l4hZA>~G+7&~ zZn0}bf*H}(@>kudI0M^lw-qBeIR78J4FA`IqFesA94DmUsUKR z4*!v-5-LkX#qU>===C@x0_L*AaNy+sH7~yVvfsfP{+UsNJp0qg+~a0Hiobg5PiZ^Ol?p-|ouh%i|xwe&qGCkW92i-VH6)RQA>pbE~PXC~^bsTPq{~9FezXaxdwq;k5 zU;^s0vQ3Ak@~sTwG1=_3$Z>dJ>-@=i?7qX|5-JSY&tZADB-$tLi|dd&tiJflBS+CO z$+4Q7-oS)2SLM~}a4v9 zKxSVYBALcg=I3yvG~FOIl05DM79>XvR5#~sG(&+h)Eemq7@Ogiv3_iaSN-8gZ*NiQ zza5f_I_W_U`T`!g)f%Cp9_~W;tq*NT?XmJFb4MzNL6O9;&T>kKZ+Cso#Vefs+#@|* zKblf9W=Q-xJq_JA(_gQEM_k*KMC5Z;vEGMA_SgPpXSC~0#hQbHi_Txyf2H6`W7Ch* zW%Qm$GVjcDif_#QQO3C#NVtPVcEnK21@(Zr`QkwzX0_6HWyhx#jO)vEbT-`xOwA!y zIHDErg)B5$ZICh&Gnzm->~5m+5nc{sN11&^K~p#OZ!^st?%^L~;g!@u3EnQ>evs13 zqE1*O;zRhHm4gA}?xW?58HVKs4=(!ER_ZoNzLJUER-&>Sff|@s(9n!-qy&`%utKHE zn4ZPDWZ^J&Wl*mFc#pxW&T29`^JB(px!M7jr8oOOmZXnN{|bE0v^vV5e`kkpB>3LN z(8JiUuC$x2BQUO)rxgI>Qms)E&U*^%3~9WQ{bWnzc92qYL#^zYA-~5TDogy*@o(B( z^Y>18(!SrJcFXr+?X{EIZA#fqc^~u5v?#yFKB-gPTJKBIEWA4v@=t}6uZI{7OVP5{ z^Rn2~)#R%7peqfjo84s*2$CK8ma5YV`bVK+T=D{?19Y(nKhHiMUm zvo#+wL`9Uk6B8suW0<^6g)vuX(N&4#4xg!7@0@a$vPF6Fn?+8+E?a4Am@&_TznW4R z9y-@umvWMZ+{%N4hmk9n8_uVHo#qN$G1n;Lh3ErArb$j8pG7>)zZc*WJ@`^b?Q!J4G8bE-F$=h?nE!5Eqzx2PW*i2I&ukUJ&|H|=L_(a^#yoYRhbd6 z_#Q6iYbSXaA*b#>Ri0AK%*%Wtu7>zT*;^1HmBG;zf}dQspExa}h}fSfpEWdOo43#b z>x<}ou5s`ElWrM42Lv2uRGy}?`^0Nf8*reyWm|@uk((pj^?zEl8g^oEe4(48NWbAN z_Ur3dqi~gWA<_>XXs;F?g=gSdOcAjL(S@Y2@W-X*5xdr!%D0CZhwO0*MnlsE-jGYt zR3Caz$%;BLQ5%P&7`ojc8hzb?4-Z6&%yUeJyBPAZ?gE?~*P-_4E^b|b_wirMAj$J< zWGXxQxIg93)6gevluMU|Q{>bx`&VvVqr+1Xa47Siqj~Lx&W`HdsfxFG!7uv^j`TTg zmKTExr=`PW)#poG;bVfJ_G1$%LNx@Zfv_P*b!0VY~#UP_l^cGwKhlah>o- z8JVW$pA^P&n{co5Z@(3^K@vz04G#}W^Ek@RqmG}O)H?D{$#%yDL7XqwZhdRVnT^mWk0)ZqVO|XHn62H>B3x891iWRSAk~a3KCR9bnFFEegf*)HiG~D zUO*WS*b=RQ?Wrn^C#O4@w6gL?F2CR;(`^};yG){%5+3i<5<6-#3D9fR14#f#rj{Bs zbGn*^gGW+yxQt6`DsBC%iW&oJUMUsqcnLI^dYZS72%9U1 z!ml@hc&Qmzo}(F_3{M-6rx3|r`Tc9g87YEJ{SxD|6VvBi%{tO7!+W7NC1uiTHAGuQQ68GVEwra4qLEBV*)vupCTZ(HI zE}wKiBiH&i7vXib8f270MKhPT7I8LV84B@b2#$vF3&A|Q;pwU7LK|+os4wGrHJzsc z09Wr>gW1c80w@rk{4#0p!_%{H(VS=L_|PEKw3dcO6eXI z5$O&|mF~^~27~TKQt56Oa*%G2?v9~{8ipBSeg{9_?_KMzb=O^Y-TV9VbN-t(C-&KA z?{~lN`#kTn8B=B@kZ}hPIs^}RHIXEZomAMVW28B&nhm&bxn=2{6uz?%4Sh=+Vb4EF zojTsQ_>cMls1fkCADQu4&hCMtuMn|3OB_%@?8i?It@oHhY*AxAf5Fy8Iqli4aVu3`Yof_ty3a>zf;u$V9jy) zG+Q;<74C7FYEu6TgfN_wquaR;JBd+Cf}28yM;n68mUQV)MxPa5KAqEp^{sK=zKuD% zMVuu1tNQ(X{rb=HMstwIR_*Ck+Ja3d=hccZe2mDdOFEtW6C#q${!Ec%31H7w4WOF()In3POCc*YG`*D_{dtnp53L@3;lMLiDehw2rW2PspN!n3;An3at_y}oUKurbHcVOzU0nL!UD-x}9g!ho7@IR; zg>O(0agj!y>}8a`h^6gijfAY8*xBp@6%${Jt^|p_si}euz-OG_>Dt^Fpa!FMy=o?% zMjTB|JM-04klXyR@$6b9BR?Ht<^hsYuD3K8Ox?~pZRv{8!ge3g=Y(FoUSFBru~;1K zl+cNr4fo-7K_C4QM%>LUP%zltpuUXZuSScbEMtb^<>?y=LSt&P-3T6Isv3a7vo89n zYX~=`joI1V`?Q^2rBa$zxMpPgO+9##9Ye5*Zd^Q&7Vy zZO3~!I2}&9LQ_FE1MK-Ol_s&pmotuGkdL~bs@W;79;}pGrqyYRxFt>Oq&pUmzE-d+!^8NQ+;;WJIGti-$9gTTO9pc!b?d={>dsYo$}z>^QN- z(_Yu^^hRvD%HJX^v(ZS!mel??`99JpHZCq((<-#@lcPyIc&vSO`%Pz&T`x#Nt31Dv}n`{kBF+oJ>Jn%&PG;#`FvCnw1~ub_(s?tlh`7-`E0#FagHq=n zZ)lRxO_JOQ<4pf{{+{6V%CTWdwNP!Rl;taBcENH1>ul*nK%PacX%sgV?uVuO;oj2V z{ff+^o`{V=WX!Yoh`+^laK?t)Io)Pv-0t_mJ3~knzZk1SvN@<(>nYmbxtf~fYz2B_ z>m~Jqr^iv17CHVUx$+WTzXa+e)y{>g0eX3E1+zeGq|~pkn}Nus^ky@5Zs9DI7za5L zuV}v3)dh`$By-QthZbYF4f8fN_YRo{u%qC}vXOCd-AODvm6DYcyqV#-AT8O5v-=3B zu+tlmLa9c&x{942L8kZ zI0ZvpOFOVsm>_<#F-8x`^xjwSsM}jhSf7Ecj`Rw5Y1dMV$_7a#B`~{;kT>UmR_kU9O6SF zf~V>PB^Gf#@S&*txuy|U?q=%pC*ct+Lm>mD^&{OS1_V)Q1y2XRznP)KFK za63z{(G6ODs$b%#!x^F@VT8-e!w)_!AAU&%Ybs)vSJBHyk{Y9=Z3#n!f+^XC@HD!7 zkk@HyP4%OsK<1X>w`(g>0PE!28pM*RllmQ{h=}C~Db%ZGF2lmMWe9(>Mlr2^6phAO z8Jgz?9z=9vACsl$xttvEtv}J!`~7w`RsqN?Z3XGVxkXIMWfXUf+FCQ+zSCD~>oy7k zr4TzNcN5;!Sf=#4dRnY)dMqlSZQ(n|S}q=FB8BB4n_3433`$(uXR*?4EARv3f+#>K zv9rd{os%lDzB+&hI^_#Wc|`PfmNt|c);+t-f1dk5OQ}egI=;|(?W5OuqDXR|D z4L?Kt-?9Ra#a6a;>gLsG>z#L0$}{G?d#0zEYKogn)!^k38r`Bv{R5F@w7_IzvMNNG&=q4&*9*b2G12>`|)y|@z z-OFCL!`7FJxaiPx+hr%%%f;}$d9z*5h$sZv!I)0MM5UW`((ov+>wq&b5+d9T4y-}O z6IMqKv-gr8>^^94v`?rhwFZp4(_jl&@$qIVoy29`>qUdeK~!cs9Ob;gU#^r;vsd3( zwi}D)xcsUsN|?^4Rq;5TA=P@PH`m8~ zy$j?Bzx5#;>!1T&x`jTFDI?eRac7JxJ;niMVo(XG;Rbfs?NG0fq zy}@ng+#4RcdA>ITd9LXYr#b1qRcNrct#`TCL>ALYn}1~4#VjQ#7UGLr^D$QrUjEcQ zOJ7b#IiGKuu{gLeMb6}l>N6gZni6P&JI+e;&WuHkyV*|sm+$51VO!dTqtwJ-Apfvq zQXp4rN#!u}IxA3GJ0~xT)TLb?Eh*dLc3by7OJC5$B5*?gZG7lx{(Co9{yVMXRNh)V28Ni*1p?+#PdAm>cuXL@X z`tEDk60+Qwx+$rCkY^NlmqWZ3sFlOP5$5R)G#5SWo==)5H?bwag3$}9PoHO#`~%Ot zs#D*}*ta<}7oR$;v6rWSg+BKs`X}G|Thdk6+&1WT#9-Uoino5c84ETJ3G;bhy#D$7 zmCR3B3K(U?@6cq=UnDm@8Hf&Vh;h=8( zC(rt1iw0_& zvmo2>$<7Y`q*6=xh3#FY_Y->@Y;L2ui}l{3a%wq6YSYptH!ZI(@Gav3v}Af4OBBeV zcA}Ov*`>XB%12YP)3c&?mY1F|(W>@G{gUGbG|#jFiv`f}FN@seclTxmt9n!meyLc! z7gRoykqJ2Y5J$eIPJDgFfjO(l())(|I3D6^Sx%hwNKiS{E_a^QZ)oB#RJW$_7T^Q8 zYGR6$pN|l+M#eg1E!MZF*Z#ehm6c(s`%gA{8=3dtT)^zC=nEb^*=OFidwYAxdfmS_ zQJx`tV84mnA|}@CAH5O#UR5js(2Kjih3`m7-~j_ri;p4Kd!**+n8C%wbe_F$8O+6| z0;pmDjAKB4?fOKVSXU`AW&w6~wY`tynZ}j#_0BI(3-Mf6YEa!!nnIv(8*;i^Aw_IL zV|B53P+`E2cYrfZ&`>1b^xvz$Q$Rz|du}82;F7DlMM!Vg$kB8*Vdd`Ii7;wp&Onqw zT9R-NxPO)^A^4`d@@`gEn9RHDtn1Q)k9}zV3Lc*5tEs&!XSdZpowhEa$x|dHGXBtH zqd3{sl~_|VJ46&_hV|Kk4<$ZIWtDMufb4_lv>FAnQ)Zg6>cMd)MyHP&d>*y#pW65X zodp06TV{Q}Z3fu|$C&SD)r-LUwAAMGs-^B~Y;!bSrF-x;NyD;TU28IuYKztIPigsG z4tv8y1^xO{U*sXIu;M;Vkw^8hiDj2BS8m7%H|}PdoEOWp%YPQ|;j=Qb{*t^-Dr7D3 zW$I5|M+rdM0D4+F)#he+6`=#x3$wh}FAokg3QO>BFTI>_1mt7h^i7oPtSy^JDb#}~ z-JIF z0oz1$rBoCGkoAqcsXiGQf|rmzB?r4hcP9PTE5ruZ*~$*`d`Q?GJ>lRKJj)A_GOja) zY0ze2uzHyBr(qt#YlR>l>apWmhl|`&at=Kh2HLEebvntBUTZd8vDb`TW&uN{x~_{~0+tG(RV2KV(&+?O8= zh`i?4>OZ$`*fnnJiXTGpoZuYid+s^9m7e4LH}U$q`&rd$%1R`+pte)9qVL=FhlS$F zSfw65EY&PoV*ozw&s#ED)#G!|31S&ACwvaj{c3!Gc=th;&+A=S>D)Fb%^UyXeBg5c zkBJx<)ts4#Vz<+qMiySpR5KKaA}1F!K7{z!X<=?fcxQ%`I#Z;VIgI2*s-=l9JQgnM z2pf-CxEGYaHeXcdCiV2WC)9kR(NBr#0rYThImD<5+<17}Er1ELYZibH?d-2?4~~P0 z7~ig(mdsT-eb~I=5llF5IQs@$uOf2{PbrV72@+^~7rwjf_TbuGW)9AxL#g`PUTtJqB+HPWng7zQtC5qid2@gkE?*Pq8FRD`oQ6KVN4qaB&j zYdBSj0~J)CkJS8#eX{$bUaV#SpYXO!U&g1l!vuU-og@6Wuuaks(KP*Wl3jKim|M_X z2X(N}RxiLAPA{Qc?gF7-26)^Bvi>4|;9aHUQv<~ZHsF)|^W)yIF8nYX)>FG#*GzQ# zpa*YDp@WuRp89Z;sz&K@r51ABf{%gO_;A6o2|h%%#%NMCh`4e{f+SIt}f{*|vjy$7N-B8P179x3!86KZU0UADeTm%@iiG4+;EgCOkr zK$9dzwUb|~)$vhuMr0owTaM_dDWl{Ye;IZG#T0vO2~D&k+qtA^iP(Jzx}s_cM7>O^_vX>7JDSi5-G#wOiPF0k(;Pjor1|liH?*gVH|wdY%$ZGX z<|rq#BfO4F*$ic1UnYOp!qr+$i405Vguy;#S{?(-!s0pWYG2;fx?!!S?bGM1)V}Wc zz#!NK>cir5!J;*?xsNShY+x@1XWpazgsM-f2_V&I`@stTI6eYu>F_(enxi#fcn1Po zWt}awyWru|<~6GWTQ2MPgsiJ5ba`)?L6F(9>JN zq@OGOK(QH?q`VL0y|eKDFLUY*{8W#>#{^T?)2Jq7u;fNBU*tGKpck&xt&b&56-_v2 zH~u1}zn->#^!<8xr8UHL*|-p@l)cW;B;kM}MiJ|0tyl0j%{L%}^)G%5 zmJ<9 zC71t7W08(~%-aZkK-VXgOdbVP@ z=+VI#^t^aN9Z(J^usy(V)YVUt%ReFoB8rCJe+~pzDY{eNR=BY(X%m4@P;?FQ5~UOL z)->i^d*?G3sP?hCwsRlbyh7v|I^N~4fy5znt$#z`;>d}Pez#|CW~QZlLtpjtuGX>l z;<>WUmDxf76>9s#q*{|9EqjxgI5xAl_)3kfEW1{;euqu)yMyfTTw!U*(K^3}oNh_{ z>A1!7IH;?C@WrNT}peL_p4U$emtbQ87S=QWDy1})V(Pfbd)pXI4j zA?F9pQ~|}4S8NX{Y5VS9dmY(l|5K=<86_^Xdv~!YfA@3>8z#iRa~VoK>HV&0Z*BQU zn!B*&%q@$Up-qB`aQU8Q%hh`{9$E<$QYBm;7r&CkQDaMHjWUMxcXd8e6V7YS zAAGxbYWcK(UH+d{>y&N+izEGL{{od(d_ zyr~=>+J8?J49>0K`rEvNJ3u%PITGf`RRZm>Nj2!wCX4lg+L=*G6lSFGD*a`~_)7a} zkR+Bt-Rw)WnfCkzE+-VgU{QR0eDD^xRqKPL*FDiJbCFjGYTD9==^+Lc^}HG#pUI z^p|HNrUQ^ihYagi4C=l*O;;#}Q^obZ22RdeY^ieAuUCW!NVF6dP&a=oBm3w4H(8>E z-`itFA~YuR&9G2DF3{TVZ-IFCZ%j!?#->vYUcZ|~{i^4w35|xHzG~GZp8e3Zo{HqZcw22yxy5d6pfHyqEp^L2IOU=~b#EE@I6^AjM;k+@&J7R@X_CT1~ z-Nrk*v*FU0#8bdgPOQeH@I9Gqq^E$$Y0-Q6gap#I-0&YX^Xm=#xZ=eNh7E2jm5c(< z2oSmc3LZ7(x}Vo3Y(z{_gngw4i=CTdGT#ATs5gE%D|hEV@55ZB%Ph0ykEm5xBtkjx z6Z?8Uw(t< zmMqm4G&+~Rjrp1$Uvt0tFeJ6rX!D*^eN@1HYy4sA`ZBeGXfs6#e~~PJX-6)RhlR3B zmqzfD^M&92Kp~99^H6)0{F3^!yvDQr#EH^!vD;Z1r4f*eZpWX}D}yKuwSNF#oB-|E zhKM~T{$<#O=wJj-V{L^`pt`kQZTY|=l84KTB!eJ*Y0;u)EPP6-{%jIK@tN*jw7I2x zW+yj>xC-C%xZiNw z2NxMvx-j4z`g@|!itiGNGV2J+Mu#e2L_@dbhSu>NwhqqO4>;?3;|M+ede z{+;p{XW0Nn;yy?=?1#9Ew^>N0sU=%)J#qo_*G4r#@8L7Ed1%N}(X8+lA$ zJ6#M;du!gaF}}p3A(9>dN@_apAi{T#_Wn{qa?h5#o(=n4jW`t3`W^h>7u{HL>bobk zI>|kiGKk&4;*_%brR^AF&})S6Snx=I ztF~4+dD0@{s?2>Dqd$C@A0*?}-?O!4QP3$yYH%@ao*(_n(1~U_MPH%6Tx}$MbcR1E zz6pw;wXqrpu&&1Ap9gbf8?z>ILnmeHqKpr5KNAQ4Rw*tBWbinD-1bn~4DMA^@8Nmp z0c1HiHVdGl9vlEOtc-NuHm+Tg36H&?f_S|*zAoB}b6=H#5}yv|+9v59?97cyzV#6R z2TaU}f8G$EgkYWysf0kTJa&eML@88eM%!ljh&wmm?Bb0^D>1SS-8uVsJ_sl#gBDNv zE^j>=`Z+q&_cD=!1Jc6G}8mf_n|-!k^xU zE%1OZ%SCg~PY^THoGxu$i#fOP&k2TEYXJ~xbLSgf@yr^ERoeo7_N`f3YIlyByJ(r$ z^7IvAthf|vdwg{MRM&O?&iUc!%gY@9WWijzS$2J*RVC*PU^1iBj;eRo`$U2s=6Fq4 zsJ7j*PX}^}zBWPvK4yKVXk6UXOo4u%9b~zYgaI{TMfW{E5ZapF0=JjY%w_MfQ-4e2 zF2E14-xWD-aGMqN_vWdZ4XMlo57H%w6L&bh>MkI7O)(L^xd5|i@UgQYOIz?bJ+-3W zEg}t1Z4ihz#H)rp2M{+XSL*Q(%CX8WKu$ppdfc{9>Sd-6d&*xt4F07{ab@Vs?77-y z7eRZB*`@!SdRZ}a(OP3MGXCOY&HDEfW=k>#$&bw5iv$?$g zl8ZkBvLDL+XY|ZoPd)Eh@4+88J8hkiwE1 zd^fFu$7?LWzc`Ptdz43=;L2X^AmDm=f8`^q`8$fH+;}S@N{c5;N+a&)FGfS_6$VZ^ z10kPvnZD03TnZ99=C?D8$qC$xU>$ZcEn(1t#b)AZ^}WiiwdSjljjd7FI+E0LOJBWr zK&eSD)2}YldjXF5^R}CP^E*^LUB_hu2AR8%XdD3fA2-Dj@FW0(uQqt(_hNk`LnO9e~ z31kTW?p4FS9F(xIqov!vr&DL#m++L1p6Hm}y~*!58Qwn=w>|%Psa?^f{fAAVWSc~? z2RcqhGT9iU#K!13KlmL-c&zNB)Ih{{5Q&stAjt6j4W-hqB=HBV!E7%ND^6IhJqT8Z zl{a6p$A^>_E!g=3g>Ulo?`-6RF2=iiacQi zI+^Z)!M9dLl4!dK_?_8c-QhyyutVMc)a;-r*fZ@@Q(1nK(RRO;C&(@lQTkb*9Gz}pllRmgB{#>tyt>_7qj8sCG4V}U(<;j@S+Sf}iodkF%v~WWS8%Vm<79zb z7j{!UTl3YdS$%bpMoXi@`Q!{!f`Urx>R!O@$w%WeZY5B=^#wmW1pBH^vFm7VgA1{J zLRZM6Dv7QitJpg#r7*}~Qd05F=a=Qj{U1IN3#HslvvBgb!u-jr!F7}+)8_?V#rJ~p z&E3QM;wQIb?*M+7VTg~J)!3_{T@9O!LGoAmAGu{Cspgq|t~P!v-l*179oi>K#qP5t zbCIdeboS(Qe~DG*V%p)DowQ+1My1`IZ@;uty9+z z9lojGUhl{!voukWLdUR9jDqNfdUArgQpvj{ZOvqFy~0w+>*8qq%D3KgB3jjWe6MU> zORP-tKFv+CdwxLYtm)aP;jZx;X(m#e8d!MbJL$7xJ6mUr);%is6)#HY67)h_(Q{L}7&}gN@yrVl+&wOF~eflFfxBB^l}Y z>12!qu4ujbyo6@aZMteW`*pJxJ_-NTt;twT^9WmQm~ncIZ6CZdG`ZZqGX$w_5rwZr z(YWwt&p(3j5EaB4B8l~3m2w|1G5JtnJqk}d3^b&t`XyLgmSH*v(=S?Csj1cP7P#)z zffw`dno0rfzj#RNZ7{iN&HPQZ@=7ciwMMh0IZ;`obQ1MglF46mwwAZNI{EBQn*!oz zqFY;-UzihDcbh>*D+{_OMpoOQ$V;a_BcX1PR_#IxRjSaYbOiMHM&bTZ3Ng^(2sE6Z zzj*p^WGHi86q4RqZS;91)NSjC2+|+LikLCTnV>2pIz*q5dZ;D4F{5qn@^=aT(zR0Z zEY$xJ78juZcqX!MUsyO{hEGu%cC};3Q@vg2$t${M%<8c|S>QL)SK82BnGJk3JKQxk z;kWNktEr+>y{%KPoQCY%WM3YS&ildeMw5462s~*-VP0>{eHxWtW!p_;2rcFj?ALZw z-96d;&al1uTDmKh6Qhl8`ryWLs$FEqn0^86kqz!K%xXN#m3jF+q*A^9Cz3qnD@MH9Xrd&p zlAVZVs#8rbNV{Q$#O8#Hsy^JM*hj?P2Y_nNjoE^W2x{o+dEO>3_AuSnU|2ucbOtjPqT}|iJ>6nN z>ix2xQojtgvwA%Y+|}*5zL_w@tt;KkTwl>ar3C>EA1ifZAwibn_cYi+MU?Fv~M?}bp@Zu z`f@^)P{fN|;(gjrKCgMrMff6z!F&8EJ%YPJDPIj}f0V5?xK!qp#u*mO=>qxskraz( z2<*!IH29!)ZD;9-9G-qN4Q9iJMBAAVMYKguc#NNto3-!%>4w<} zUTr~}7&=SyBWjfzfoN9zcy+=>BHr*l<(G2Y_ddnXl_g004lTC17ZvFr*dfW%_ro8U zd3k#D(2Be>?z-Qw*bN(qzZv*oRI8Cp6Fi?|+eDtENd@n&+JAJrR8(|INYS`mU+h35m^TwjG;WEAt1VM+6J&_bO^Uzecz*BGkGnj>+T>UzWG#26T8LI$^mCM#pU1 zqurCWOOzKyC>Cnepw0ZdyVCWIFC)BgNpxkBjMZa{=e_6f=Z}kQ1x#%#FM=CtXvE61 z$9D={k}GO;PuX+p=ifm_6gEdkzQ?GQ{CG3pFqD!!e>=B^5f0_V1V)sRb}<@#Ui%_a zy(4B&>ca@cGe3>}$38Ah+CkYcCH%}sp)c+&zPMK{#8}@gClMyKnF|UsAZ%(^0+os~ zG@ke3tv&hpC#6a9NNiD^_^nTP5UI`nO6Rx`Y;|yu8C}!+ry}QSSem2x6m^tO!TZBAr-j(+ik6iT(wzq{O`V z)SoWnq1@5T`tOerhvi3sS+5x-MLtA{rU+AUdU@UJIQ8M-)p71qdt>RlNok-gg>L@f z)^VH<_ckjfOrK{SGWsO$-PnPtJj|%>cf0a%7g$xJ)OM&FZ1jg1cWkiTd1 zTP}=o{*}YH-Bj&)rFT|3SV?fMpthl|4#;5n26S5~Pfadt^aye0EL5e`j|e##&q8y~ z>}ZWy1)6#qgbhb*7Ccpn@n%kt)AcfsyW9d@30>ubD5HjGVpN%0`Dk+vwH^G~Se%&Y zy)%EyP-ojOuiX!kc^Ae+Xc>1vbL5(!Ajv`f$MlyNLNY+CIC!Dz!}|w8vB;FU#%co_ zrB#?&C=-?xJ@O0`(l@@$^fc9UNKtBTg_@4 zzU1A;oS1rT>z7ccz&kJTn9v4=Ul)oRmW0jq;KikU+x0wVp2}@TpTnFi`{`^A=$jpP zyH=)&H>!+w#E!jamPy}P52WRcDbF@41XluLCI8e2_|SLAyBAjD(20oZV;C=<+1hO{^t65Y?1k`c}9(`6pILQR9shkj*CYNhmgpnpm% z_^u(QYCC-vGSnmSP57oCn9}|DoR~aXu>4SfNs05&8$m0u`2mNze4n28$SXs4fV*)K z5J`QctzCplEn9`(@UI3ux`wx>DfcgXcD395-Jr?v)fb3|scMp6?qc^Eb|By4attjW z&;MZ#YS734P=4PEjUAy+rb=~;(KMv}+B!DF2c|0vG&=RH%lRY}E`?nC>2IRHf=8@R z=GIq!nPavyR9&HZ4+pzV(@7;w0qIqh(}Ph)IcCFJ)+F+ir_fKEw_~}EaKchvQ<5{P z(Xp;}6ORzBTZkjt%RM@@xxWwja{>fK(NEh z{faywA{ZrFYUyREw8CuPYb9Lbawq<9v5&&`_BHe)}AA6J9ZutJ6p~8J}r7x zU95lAcap*S^g6+F6%9yCA$gFyWfxR)XH6%phfNM2g^WVUCAd?HQ zJ=j!p(K3&{!xyRGI{|-7A0PLS5_WUW|hc&|pDUIlq4HL*=n)tI8BwL+L4${ByWo-|FJycY7ahqfa ztqB=J;Y)q7$(uOLr^C_BzhjvK?)ew0re1l@>2>C{%XBV% z@p1}IL@)CuY&IB3`a~~6&`?>J)#YUnLEk#~y@yB7ubeu#VQr(ya0%5n_#odLgia#% zoKL|m!v86OBd_Xr$Z1XNAEK2uDW^i}0{xSY2Tli1m4wUZoCTAiM4bc@&&8RGlsBcg z{$vjr8XGQ1N)uBLmH!O6@1icB*3hUE#sA3Oz)i2-%e8U!v%x;EN69kBnyI`F!a~vJ zs3~z`&+4lG@xo68!V7}9NYRsE@S|lXmO*S4cA`EHZ{#>?E3d(yT`jK3MvzVUT^&W$ zGItKr9!a~kZJ6QK&!crC5&YK64d!hvA>!+|Y0$h<&*;S+^L3Gyj`(?&N@DEeuI|m~ zRTjf9L;+x8JM#PYYd?pSCq@#cM1Lg#q)%CW;Xl(O)+_6gyLqHy!gx%5j8~7yaLTgf zng{4aEE`Wqhd-BSsNH`5H1P10dudvtgbmwCrm=v`H&cLy9EIsEE$worBumT!#S53x z6(L~)bJd!5!&ylud!B}pas_xb6&v@_HQOUCi!t8kiTfGz4H7%aP8@{rRW54kQ4Z8x zjDJIynSw&`gpG5TEIBnhlG5aYT)#x~nO-Dmykr3JMoPZ3yu z;j!5}&u^GBGidIMY5HbU@AQIrYoU0T^cWh|xsPYwlp>Z}pH{gt74)C4Mc5vt?g{Qj zFY?EZ+*MmXgLJ5QUxXnlPDB}Wsw1gKt*g+2QqL{wYmQ*QK$OXD&ln1#%bx*N)5OH5 zKw2;3drx<_y0ASW=sf&7?aeFPw5Y{Fbhoy2ejahb+*qH`aK<|%A2u##8Av$3?|u5G zmN20`Un;W`UgUu6_U1s9@G=MXR0dqdyM1h3mm|n{=de$={zE!isR?AMHTWFsUPn|y zhbFcubN2}wpfg}ZeMsbB9(YV|Nyo18N2(0we=#J-*K|CxF76yIMlssg_V||eOO?K+ zU8~d#5KCGFB`@W#@D=$t-|uy+5h=g=g`BnT#%29!Z{8`aNi(Lvp(AIJR`9Gh(3p4~`wUP3 z_`wtYpTy?GP5+1)kVN{8n>DfL?}qaVx-OH#)$2)Jk&neQ4+84mQ+Caj_}6~gq*w`e zN&w%wm1tYc-I*Qursq=_BrVreuRe0e_F}~E_|0R4I%0BFXU&0f{@&`7PVNUzhMY?b zdK~YF(5VR=L)i^RT`8e$O*$Hf4ILe^bvkI+VjpaR4db-3a1tc@OBHiJa~15ruV#5weN4T0OGD7xlRI4A`RqA@hYjb{PwDdxm=5yM@@C; zwL0PN3f+Ri_*xwNN`LH)d+u&A@4?pDMv8w+{2JD#>99KDzZC&PPWVv@1cc*d>F()059N^)j}_15h$&KAUR;9>8{3 zyx-)%^mSZHA44F=&Hn!Tj|p_&kS6iPF*fJCzDkf3OoT9UoL|w17#|XvKYm;J$<+MK zX(9y6|}2Hm$7Rs26aLemc( zmw%s@l=kN4?nUx7W#(tDbSA&!s+Hg`Fv^yalK(z@GTuW0jC7E*-(j}HlFXZjtQsYm_MY_1bd_i3cjNAc=V*G_D&7=u$v?YXO zOA_H~zr7mrW1DK)P2O=*{d2)Gp~q0yAY0AdsY}co72Gq=?&(TIgKRofRX;`z?5C*D zH!dja!Y2R37GKy7S`~nUx*;j~Kj1SFpMyE+u}uw_}mH? zlR0{=uy)G$0>g+eJv-ws=o~$<}+IDHV^3-7v=cl}C(MN>}oLFXH_4PgH zn9O`>jrvKtR6+@g@$gpzq9mzn&4xL%&fG6Inefwlq!W8vo-#5Xe^QXad182EmyO#T zS9T)}Kp_ES+AlLxgj1gd08|0Z6B>R?08sr0CVt)<@6Z@mLV+V2tt+DcA(!W7tr_q@ zfGVY~Ua*vsn4vHk<$%NF7c0!1o26Os+bgf^#(x0j#)7)k=EV1%H)3z8)<1A#8?LNR z#J3|H7#d-Jzob|xh#MpSDF?)0i8Puc0HviFIW$Nxf zC^M&OhDu+hW$-Cx+)8l71p}a|H39J256;gs!1=pAd{?ez%&a%Nqg58^V=12h ziS z&G!r6&|LfaQpw4Ko0{{9w(8y%=+GR;AW6A^!GHYa5sXxW<-IgfHDaD{8i{8~VQJ^f zm>-BPfXG*$f88Ku`FkoiaFPjVIG89Z{w{Z3%NbS9TT6%@SY`!ph_BgsZCbF9v8Ri~ ze#J5(XJE7R`i17MH8*P0SGe>Xk$GvyGk`%gDp_7|>HMw<83bGcG18E0JOULCu)FtJ zxJlHshza={=ZGM3fF)lK*$98Q7~^pLd{p4|8M&5UiuIH@dk49RIrSf{QyV9`83lQm z02UIx>u$dFM@5e0FAGBR69AahmahF`{d~0hD-$NzctTs^iN4paf=w?HFb9cE2= zV=d<)j;~l&XlBc5L`NsnTy5OOM}+dbOoy>Njpz8+EyZVNWaQP)ZO9%qGch$aHs(Jm zmRclQ1Ikixj?C=r4A0BA?XKz^|CMCb})pPM2WGxmoKnW6@Rb{Ghs{icF;Dvo5LLZ@iQrjC5bj@wOj6yIJw<&a=oD zf)!&r1n&*L)B8xUu)twM-uvE{Z5M|=b%HOxRt`F=|2UoDpZ*MU{ljX?rHC=L$iL~DfBO?=>Yr$3O1 ze-%=Fu&Pm5waS@akcvE`KE5jT?8wllmYXzY^aDc?bH#11)AwAvf9{{3vdZ7rlx&;1 z_!_Z-07|<)qT;<9WjQ0Y451=>FG36o(QSJ}SdY$D(+wK2pR+O)s2Jg?51Jg{LXAR! zVqK`rtW`v-_qE_W=dt3zY(Ac=`jWPWn&5ichaqu3X!)ld!(Tnz-PHCouO$aXt0X_o z-l8v##}EIiSv>2aya`-avzVm8PqgFO#3B^mT)jPMl4ZaCuIi>anMidTNor z#5i{JJIZ1bruMpTAGqeAe7vm2XJC6~jHk}f*x5#3avG@wnW~RM_w{#>=%JilJ-(V( zfI3{PcCMR7uSzbcV<0#Zeusu6Jo&0~ckg0GK3a+B?*T7|w*ll_dBWMnyx&7gPNT7*}2ov*-kT6 zJ%?YD*yFjA1(1iZ%kYa{VZ-y^1gORH(R?*}&_?akR8horE0*lmj~-xzN6D>iWU;&u z`?-WJVqs(d(MtMH>M9!MJ;8qaWY=$uTTY$+S8 z(G_+EKI8uNQ9Z;J3DX~4pC?B;ZXdF(1D}9VQQTXORFUq=uhZY3B`5Z}=Iczf?j8*x zoYTsu)xfCURS8*WrH1nHMp?RUP&?I_kj8tMtip3Y!F{TQ6g-xeJ1pQyS}*G=T%p>5 zm5zf&h68v_V@Y9cA@oiAV+#R%VJL~i41#09 z&cF^btxzGy(Y2l4LV8La`dYKsR9C5hjtq)U#S5ix5>q%R0kuHH_3BEec%Z&sN{2UjYcKa7PF}28 zecOTX9%DuVr0HF@Vij?((C6^eV$SBh8M}06pV?d=j|)NyqQ+VVlNh_17ak`Lyrn)z zzntW@lVIoy_fcHR=|Uz#@-Z7BoigKfWk1b&f{X#``l$uGljOwW>i4y{1=yj`sLVI*IiLJ z7#5ap`*>^oyzHr@(v;XI*$#R`AB)vd2C(z)*&1mC5skBaf;T7%=$Vf(dbh)?kwgP2 zoZ?M+TRZrd;dQ?ZEmLV}CUW^ShLmP)Fm^2CxyzYJH77z#a`4y%m(??ZIC%J0YFgv@ zKHkS-o;?Aqb$L@V0ZD|B5Dss7HyU zBKtt$w24W~Zu#OTeI{=F^SRSdTkz2UDQsL&bhGl~#Tqpn1Zv)F{M5yrmeSd*%;P?F z*p)rs9cq^Daf#FdBe!E{wKN9}nmmyfjLnIT+r``4MRB{spCX93wI;^Ij?Ncd5e6fL zs0KR`vk7`SAM-`;23L;V*rc1%xk+T~1%(uMuQN4`T3oo&x!yCJr3Tf0G5Qh0MMees zBL812=l_(19ma8Q+;TTVZ`ZOy%X6+w4P0gDWWl-Sni1ke)RkbKsY}!}oM;MIuDUXF zE5j6$ji#k!Xa@KVsafYpkSS_>k#HCqDrn$05M*%M?JwA`pC6ukKhJ%h=kxkJ_k2DC z>$M*gJu7?R^OGzo5NQtK<+BB<#%a{uxI|{W<&J+vJ$@_*V(b@q%!EhZx~XMV znXL@6xfLY~9lVT0R)*j32JRwaXkRzsP4UMBo_iIAGWZp*Z!%;pJRaj{nh2V+_*f-B zD{Kg4gna@_=4N9bH7JWYMF!YuA^NcWI>0M30+!s7xeRt}s5Lce#Hq<)#h_lsG)|OA zksGT`*0&SAGL+DG6Zt$3foGebmBP zM*T>iB7e+=QuU6COCPh!&SPVQ_#p6|B(9!k4i3R&W0Kc4NUFo$URC}cJF*y-+gn3u z2kacn3Hl2y0+ydAF(zOpiB2tm;Cu88Qg*RcHN<9cY@N6za*ycn&*so<1Uu&5aLsh;TCG zm9g76SkWed?4g&+IC@I3+uRs5|%OVBm7j z^t?7^^>|F~3*#BcoI4)OC^*-B*gsDFQ`zE<808gDIimJA;d zh(I88JQ!}r$h=$W)gB+3R_EHOQBhG!@V^F9AP2giUA^Z;B^pPPQsqiK+wZrTzoHeo zt9M&}!Lsd0qNT=ll+4F4b!F25a8ncV`aI);FTgCUuh5ht!e2#i#l30dG=}zUI`- zN3QvgB7k4?WI3+Rbr)*$X=Ayd;{R+!JDhJ;9FG19n#yT-lWSiB+~!uBL6<&*%AG52 OG10MKJ^J$0#lHbY-#;_} literal 0 HcmV?d00001 diff --git a/docs/validation/pr-28/hashes.json b/docs/validation/pr-28/hashes.json new file mode 100644 index 00000000..e96d7406 --- /dev/null +++ b/docs/validation/pr-28/hashes.json @@ -0,0 +1,16 @@ +{ + "algorithm": "SHA-256", + "packagingSource": "9aa1df286c2b6fd59b4c101201ddae0ae6000324", + "upstreamSource": "0965053fe6b9341776df147a6934b7485c60b5ca", + "files": { + "launcher": "a85063b9caedf346444db4da72fa3ab62a0bf913b6a4b6056b8d0b6d4a476def", + "node": "b3094d0b49f9ad602262a9921551737bb97637c05dd357a06ae98188d7290aa3", + "upstreamNpmArtifact": "d0d5b0a0a2ace6c0a957b785929af6c0c0d69fe5dc5fb47e995db25ec700548f", + "runtimeEntry": "4f4d29770da4f86dbd0e07cbd4d46deab785905dd89ac719033fcfd866fb5d17", + "gatewayBuildInfo": "b5bbc98a27a81d41261ca7984a36126ccad982e3fb1ea46e67234cc007038648", + "plugin": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "controlUiIndex": "73ac0e6f38896c9d491b45a6c3d23b4990dae139d8ff3cb93da7a33e640bb1e7", + "controlUiEntry": "1430574e4d89d8c43b303057d918fdba41a4a940d436d7feaf8e0122a533e4f6", + "screenshot": "1dd7153742614febf8d00aa08c50f3c3465cdd8a7a3b4cf87e8fa585177a0142" + } +} From 084f6d6303ed97a93f66aded8cddb614c6c0b51b Mon Sep 17 00:00:00 2001 From: Chaz Gordish Date: Thu, 10 Sep 2026 21:15:15 -0700 Subject: [PATCH 3/3] test: expand Gateway isolation contract proof Attach runtime and payload matrices, clipboard checks, regression results, and authenticated Control UI screenshots. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/validation/pr-28/README.md | 183 +- docs/validation/pr-28/copy-checks.txt | 6 + docs/validation/pr-28/copy-fixtures.json | 104 + docs/validation/pr-28/fixture-disabled.png | Bin 0 -> 41835 bytes docs/validation/pr-28/fixture-empty.png | Bin 0 -> 28633 bytes docs/validation/pr-28/fixture-enabled.png | Bin 0 -> 41850 bytes docs/validation/pr-28/fixture-invalid.png | Bin 0 -> 28633 bytes docs/validation/pr-28/fixture-missing.png | Bin 0 -> 28633 bytes docs/validation/pr-28/fixture-uppercase.png | Bin 0 -> 28633 bytes docs/validation/pr-28/fixture-whitespace.png | Bin 0 -> 28633 bytes docs/validation/pr-28/hashes.json | 11 + docs/validation/pr-28/launcher-disabled.png | Bin 0 -> 41835 bytes docs/validation/pr-28/launcher-tests.json | 234 ++ docs/validation/pr-28/payload-matrix.json | 3656 +++++++++++++++++ docs/validation/pr-28/payload-matrix.txt | 625 +++ docs/validation/pr-28/plugin-tests.tap | 136 + docs/validation/pr-28/policy-checks.txt | 4 + docs/validation/pr-28/runtime-checks.txt | 8 + docs/validation/pr-28/runtime-matrix.json | 686 ++++ .../pr-28/runtime-registration.json | 28 + plugins/gateway-isolation/index.test.js | 68 +- .../Test-GatewayIsolationPayloadMatrix.ps1 | 377 ++ scripts/validation/gateway-isolation-copy.mjs | 72 + .../validation/gateway-isolation-runtime.mjs | 231 ++ .../GatewayLauncherTests.cs | 14 + 25 files changed, 6321 insertions(+), 122 deletions(-) create mode 100644 docs/validation/pr-28/copy-checks.txt create mode 100644 docs/validation/pr-28/copy-fixtures.json create mode 100644 docs/validation/pr-28/fixture-disabled.png create mode 100644 docs/validation/pr-28/fixture-empty.png create mode 100644 docs/validation/pr-28/fixture-enabled.png create mode 100644 docs/validation/pr-28/fixture-invalid.png create mode 100644 docs/validation/pr-28/fixture-missing.png create mode 100644 docs/validation/pr-28/fixture-uppercase.png create mode 100644 docs/validation/pr-28/fixture-whitespace.png create mode 100644 docs/validation/pr-28/launcher-disabled.png create mode 100644 docs/validation/pr-28/launcher-tests.json create mode 100644 docs/validation/pr-28/payload-matrix.json create mode 100644 docs/validation/pr-28/payload-matrix.txt create mode 100644 docs/validation/pr-28/plugin-tests.tap create mode 100644 docs/validation/pr-28/policy-checks.txt create mode 100644 docs/validation/pr-28/runtime-checks.txt create mode 100644 docs/validation/pr-28/runtime-matrix.json create mode 100644 docs/validation/pr-28/runtime-registration.json create mode 100644 scripts/validation/Test-GatewayIsolationPayloadMatrix.ps1 create mode 100644 scripts/validation/gateway-isolation-copy.mjs create mode 100644 scripts/validation/gateway-isolation-runtime.mjs diff --git a/docs/validation/pr-28/README.md b/docs/validation/pr-28/README.md index fafc9dbc..f9815d0a 100644 --- a/docs/validation/pr-28/README.md +++ b/docs/validation/pr-28/README.md @@ -1,47 +1,79 @@ -# Gateway Isolation local end-to-end evidence +# Gateway Isolation validation ## Why is this change being made? -PR #28 needs evidence of the real Windows launcher starting a Gateway whose -authenticated Control UI exposes the Gateway Isolation tab. This records the -local run against packaging commit -`9aa1df286c2b6fd59b4c101201ddae0ae6000324`. +PR #28 adds launcher-reported Gateway isolation status, a read-only authenticated +Control UI tab, and payload provisioning. This evidence covers those implemented +contracts against production source `9aa1df286c2b6fd59b4c101201ddae0ae6000324`. ## What changed? -No launcher, plugin, or upstream runtime source was changed for this validation. -These files add the full-shell screenshot and sanitized machine-readable results. -The GitHub user-attachments endpoint returned HTTP 404 for the target repository, -so the evidence is stored in the PR branch instead. - -![Authenticated Control UI showing the real launcher-reported Disabled state](gateway-isolation-e2e.png) +Added reusable validation harnesses, expanded regression tests, named test results, +HTTP/browser assertions, runtime registration output, and authentic screenshots. +Launcher and plugin production code are unchanged. ## How was the change tested? -The run completed at `2026-09-11T02:45:20.860Z` on Windows x64 build -`10.0.26687.0`, using .NET SDK `10.0.401`, Node.js `24.16.0`, and Microsoft Edge -`152.0.4191.66` through Playwright in headless Chromium mode. +### Evidence matrix + +| Implemented contract | Executed check and result | Proof | +|---|---|---| +| Interactive launcher selects `disabled` | Real NativeAOT `openclaw.exe` started the Gateway with inherited `CLAWCTL_GATEWAY_ISOLATION=enabled`. The child Gateway and authenticated Control UI reported **Disabled**, proving the launcher overrides inherited input | [Runtime matrix: launcher-disabled](runtime-matrix.json), [screenshot](launcher-disabled.png) | +| Both exact values are supported | Real Gateway processes with explicit `enabled` and `disabled` launcher-input fixtures rendered the correct state, green/warning tone, and inverse CLI command | [Runtime matrix](runtime-matrix.json), [Enabled](fixture-enabled.png), [Disabled](fixture-disabled.png) | +| Invalid or absent input fails closed | Missing, `invalid`, `ENABLED`, empty, and whitespace-padded input each returned **HTTP 503** and rendered the invalid-launcher-mode diagnostic, with no status badge, CLI command, or Copy control | [Runtime matrix](runtime-matrix.json), [missing](fixture-missing.png), [invalid](fixture-invalid.png), [uppercase](fixture-uppercase.png), [empty](fixture-empty.png), [whitespace](fixture-whitespace.png) | +| Route authentication | Each of eight Gateway runs checked GET and HEAD with no token, a wrong token, and the correct token. Unauthorized requests returned **401**; authorized requests returned **200** or **503** according to input. HEAD had an empty body | [80 HTTP case results](runtime-matrix.json) | +| Read-only route | Authenticated POST, PUT, PATCH, and DELETE returned the same read-only page bytes as GET. A subsequent GET remained identical. This handler serves status for these methods; it does not implement a mutation action | [Runtime matrix](runtime-matrix.json), [command output](runtime-checks.txt) | +| Response hardening | Successful and fail-closed responses had `Cache-Control: no-store`, `X-Content-Type-Options: nosniff`, `Referrer-Policy: no-referrer`, and CSP restricting frame ancestors to self | [Runtime assertions](../../../scripts/validation/gateway-isolation-runtime.mjs) | +| Full authenticated Control UI integration | All eight runs completed normal `hello-ok` handshakes with the matching bundled build, exposed the sidebar tab, and rendered the plugin in `sandbox="allow-scripts"` without `allow-same-origin` | [Runtime matrix](runtime-matrix.json), screenshots below | +| Copy behavior | Clicked Copy for the real launcher and both valid input fixtures. The button reported **Copied**, and browser clipboard readback equaled the exact inverse CLI command | [Runtime matrix](runtime-matrix.json) | +| Clipboard capability branches | Six browser capability fixtures exercised Clipboard API success, API denial with legacy-copy success, and both methods unavailable, for both valid states. Manual fallback kept the exact command selected and showed the manual-copy instruction | [Fixture results](copy-fixtures.json), [output](copy-checks.txt), [harness](../../../scripts/validation/gateway-isolation-copy.mjs) | +| Process-stable reporting | Seven initial inputs were each read exactly once. After plugin construction, repeated changes to the input source did not change any response, including fail-closed responses | [21 passing Node tests](plugin-tests.tap), [test source](../../../plugins/gateway-isolation/index.test.js) | +| Typed launcher selection | Enabled/Disabled mappings and invalid enum rejection passed, alongside argument forwarding, working-directory, process, and entrypoint regressions | [57 named passing .NET results](launcher-tests.json), [test source](../../../tests/OpenClaw.Launcher.Tests/GatewayLauncherTests.cs) | +| Minimal runtime surface | Real launcher-driven runtime inspection reported bundled, enabled, activated, loaded, imported; **one HTTP route**, **zero Gateway methods, tools, services, diagnostics, hooks, commands, discovery services, MCP servers, and LSP servers** | [Sanitized runtime inspection](runtime-registration.json) | +| Control descriptor | Node tests verify the exact label, Control group, order, icon, route, `operator.read` scope, gateway authentication, and exact path matching | [Node results](plugin-tests.tap) | +| Payload acceptance and rejection | **66 passed:** 33 per architecture. Six accepted cases verified exact three-file shipping content, matching hashes, metadata, excluded tests, and environment restoration. Sixty cases rejected missing/conflicting plugin directories, failed runtime inspection, and invalid/missing runtime shapes | [Payload matrix](payload-matrix.json), [transcript](payload-matrix.txt), [reusable harness](../../../scripts/validation/Test-GatewayIsolationPayloadMatrix.ps1) | +| Signing and workflow regressions | Existing signing-input and workflow package-version checks passed | [Command output](policy-checks.txt) | + +### Screenshots + +**Real NativeAOT launcher, inherited input `enabled`, actual reported state Disabled:** + +![Real launcher reports Disabled and copies the enable command](launcher-disabled.png) + +**Real Gateway with explicit `enabled` launcher-input fixture:** + +![Enabled input fixture displays Enabled and copies the disable command](fixture-enabled.png) + +**Real Gateway with missing launcher-input fixture:** -### Runtime composition +![Missing input fails closed in the authenticated Control UI](fixture-missing.png) -The launcher was published as NativeAOT from the exact PR commit. The expanded -x64 application came from the successful -[packaging workflow run 34546297901](https://github.com/openclaw/openclaw-windows-packaging/actions/runs/34546297901), -artifact `openclaw-gateway-payload-x64` (artifact ID `10179486438`). -That workflow's packaging commit was -`52f2a53fb62b13499ba2692d81870413fcaf943a`, not this PR. -Its recorded upstream source is OpenClaw `2026.8.2`, -commit `0965053fe6b9341776df147a6934b7485c60b5ca`. +**Real Gateway with invalid launcher-input fixture:** -The PR's three shipping plugin files were copied into -`app\dist\extensions\gateway-isolation`; the plugin test file was not included. -The source and runtime `index.js` SHA-256 values matched. +![Invalid input fails closed in the authenticated Control UI](fixture-invalid.png) -To resolve the previously reported UI/Gateway build-identity mismatch, the -Control UI was rebuilt from unmodified source at the same upstream commit, -using its frozen dependency lockfile and declared pnpm `12.1.0`. Only the -generated `dist\control-ui` tree was replaced in this validation payload. -The supported build inputs were: +The valid-state fixtures set the process input directly while running the real +Gateway, plugin, authentication, and Control UI. The launcher case runs the actual +published executable. All screenshots are captured after clicking Gateway +Isolation through the normal Control UI. The same browser context is reused +across the matrix, including valid-to-invalid transitions. + +### Test environment and provenance + +Windows x64 build `10.0.26687.0`, .NET SDK `10.0.401`, Node.js `24.16.0`, and +Microsoft Edge `152.0.4191.66` through Playwright. The application uses an expanded +package layout: the NativeAOT launcher beside `app\openclaw.mjs`. + +The pinned OpenClaw `2026.8.2` runtime, commit +`0965053fe6b9341776df147a6934b7485c60b5ca`, came from +[workflow run 34546297901](https://github.com/openclaw/openclaw-windows-packaging/actions/runs/34546297901), +artifact `openclaw-gateway-payload-x64` (`10179486438`). That artifact's packaging +commit was `52f2a53fb62b13499ba2692d81870413fcaf943a`. The three PR-owned plugin +files were provisioned into `app\dist\extensions\gateway-isolation`. + +The bundled Control UI was built from unmodified source at the same pinned +OpenClaw commit, with its frozen lockfile and declared pnpm `12.1.0`. +The supported build inputs used the Gateway's canonical build timestamp: ```powershell $env:GIT_COMMIT = '0965053fe6b9341776df147a6934b7485c60b5ca' @@ -51,79 +83,34 @@ pnpm install --frozen-lockfile --ignore-scripts pnpm --dir ui build ``` -The timestamp came from the Gateway's canonical `dist\build-info.json`. -The authenticated WebSocket response reported: +Gateway and UI reported +`2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z`. +Served JavaScript matched the rebuilt output hash. Authentication and bundled +build-admission checks ran normally. [SHA-256 fingerprints](hashes.json) identify +the exact launcher, Node runtime, plugin, runtime entrypoint, build metadata, +and UI assets. The runtime matrix also records the tested executable hashes. -```text -type: hello-ok -version: 2026.8.2 -buildId: 2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z -controlUiBuildSource: bundled -``` - -The JavaScript served by the Gateway matched the rebuilt JavaScript SHA-256. -There was no custom Control UI root, cross-origin UI, edited build metadata, -mock Gateway, injected status HTML, disabled authentication, or build-admission -bypass. +### Reproduction -### Launcher-to-browser flow +From the repository root, with a published launcher/application layout and the +compatible Node executable available: ```powershell -dotnet restore .\OpenClaw.Gateway.MSIX.slnx dotnet test .\OpenClaw.Gateway.MSIX.slnx --configuration Release --no-restore -dotnet publish .\src\OpenClaw.Launcher\OpenClaw.Launcher.csproj ` - --configuration Release --runtime win-x64 --self-contained -.\scripts\Test-GatewayIsolationPlugin.Tests.ps1 +node --test --test-reporter=tap .\plugins\gateway-isolation\index.test.js +node .\scripts\validation\gateway-isolation-runtime.mjs ` + +node .\scripts\validation\gateway-isolation-copy.mjs ` + +pwsh -NoProfile -File .\scripts\validation\Test-GatewayIsolationPayloadMatrix.ps1 ` + -TestRoot .\.validation-payload-matrix ` + -EvidenceDirectory .\docs\validation\pr-28 ` + -ProductionSourceCommit 9aa1df286c2b6fd59b4c101201ddae0ae6000324 .\scripts\Test-SigningInputs.Tests.ps1 .\scripts\Test-WorkflowPackageVersion.Tests.ps1 - -# Run the published executable beside the expanded app directory. -# OPENCLAW_STATE_DIR and OPENCLAW_CONFIG_PATH point to a new test-only profile. -# OPENCLAW_GATEWAY_TOKEN contains a newly generated random token, not a real credential. -# CLAWCTL_GATEWAY_ISOLATION is absent from the parent environment. -.\openclaw.exe gateway run --port 19428 --bind loopback --auth token --ws-log compact ``` -The profile used local Gateway mode, disabled mDNS and browser automation, and -contained no model credentials. Process inspection confirmed that the listening -`node.exe` process was a child of the published `openclaw.exe`. - -| Check | Observed result | -|---|---| -| .NET launcher tests | 54 passed | -| Node plugin tests | 6 passed | -| Synthetic payload provisioning | Passed; this is a fixture test, not the real Gateway | -| Signing-input and workflow-version tests | Passed | -| NativeAOT publish | Passed | -| Actual launcher `--version` | OpenClaw 2026.8.2 (0965053) | -| Real runtime plugin inspection | Bundled, enabled, activated, loaded, imported; one HTTP route; zero Gateway methods, tools, services, or diagnostics | -| Anonymous plugin route request | HTTP 401 | -| Authenticated plugin route request | HTTP 200; `Cache-Control: no-store`; restrictive CSP | -| Full Control UI connection | Token-authenticated `hello-ok`; bundled matching build identity | -| Normal UI navigation | Opened the Control UI, clicked Back to app from the fresh-profile model setup screen, then clicked Gateway Isolation in the sidebar | -| Rendered plugin iframe | `sandbox="allow-scripts"` without `allow-same-origin` | -| Real launcher state | **Disabled**, with `clawctl gateway-isolation enable` guidance | -| Copy affordance | Clicked Copy; button reported **Copied**. Clipboard contents were not independently read back | -| RPC errors during browser run | None observed | - -The screenshot was captured from the real rendered page after the sidebar click. -The model setup screen was exited through its normal Back to app button; no model -was configured or queried. See [e2e-results.json](e2e-results.json) for the sanitized -browser assertions and [hashes.json](hashes.json) for exact file hashes. - -### Scope and limitations - -This validates the local runtime path in an **expanded, unpackaged application -layout**, not an installed MSIX. It does not validate Store installation, -package identity, execution aliases, MSIX read-only enforcement, signing, ARM64 -execution, or an unchanged workflow payload. The UI rebuild described above is -part of the tested composition, not a workflow/source fix. - -**Disabled is the real interactive-session launcher's report.** Enabled, -missing, and invalid values are covered by unit tests only. No isolated-session -launch or isolation attestation is claimed. The CLI guidance was displayed and -copied, not executed; changing isolation remains outside this PR's scope. - -Only the validation-owned Gateway process tree was stopped after capture. The -test port was checked to be free afterward. No existing Gateway service, user -profile, installed package, or system Node installation was changed. +The runtime harness creates isolated profiles and random test credentials, checks +that its loopback port is free before starting, and stops only the process trees +it started. After each case it verifies the port is free. Public results contain +assertions, versions, and hashes rather than tokens or machine-local paths. diff --git a/docs/validation/pr-28/copy-checks.txt b/docs/validation/pr-28/copy-checks.txt new file mode 100644 index 00000000..7f2fa31f --- /dev/null +++ b/docs/validation/pr-28/copy-checks.txt @@ -0,0 +1,6 @@ +PASS enabled/clipboard-api: copy success +PASS enabled/legacy-fallback: copy success +PASS enabled/manual-selection: manual text remains selected +PASS disabled/clipboard-api: copy success +PASS disabled/legacy-fallback: copy success +PASS disabled/manual-selection: manual text remains selected diff --git a/docs/validation/pr-28/copy-fixtures.json b/docs/validation/pr-28/copy-fixtures.json new file mode 100644 index 00000000..c9f65a56 --- /dev/null +++ b/docs/validation/pr-28/copy-fixtures.json @@ -0,0 +1,104 @@ +{ + "kind": "Browser capability fixtures against the actual rendered plugin page", + "completedAt": "2026-09-11T03:55:15.070Z", + "cases": [ + { + "mode": "enabled", + "capabilityFixture": "clipboard-api", + "command": "clawctl gateway-isolation disable", + "label": "Copied", + "calls": [ + { + "method": "clipboard.writeText", + "value": "clawctl gateway-isolation disable" + } + ], + "passed": true + }, + { + "mode": "enabled", + "capabilityFixture": "legacy-fallback", + "command": "clawctl gateway-isolation disable", + "label": "Copied", + "calls": [ + { + "method": "clipboard.writeText", + "value": "clawctl gateway-isolation disable" + }, + { + "method": "execCommand", + "command": "copy", + "selection": "clawctl gateway-isolation disable" + } + ], + "passed": true + }, + { + "mode": "enabled", + "capabilityFixture": "manual-selection", + "command": "clawctl gateway-isolation disable", + "label": "Selected", + "calls": [ + { + "method": "clipboard.writeText", + "value": "clawctl gateway-isolation disable" + }, + { + "method": "execCommand", + "command": "copy", + "selection": "clawctl gateway-isolation disable" + } + ], + "passed": true + }, + { + "mode": "disabled", + "capabilityFixture": "clipboard-api", + "command": "clawctl gateway-isolation enable", + "label": "Copied", + "calls": [ + { + "method": "clipboard.writeText", + "value": "clawctl gateway-isolation enable" + } + ], + "passed": true + }, + { + "mode": "disabled", + "capabilityFixture": "legacy-fallback", + "command": "clawctl gateway-isolation enable", + "label": "Copied", + "calls": [ + { + "method": "clipboard.writeText", + "value": "clawctl gateway-isolation enable" + }, + { + "method": "execCommand", + "command": "copy", + "selection": "clawctl gateway-isolation enable" + } + ], + "passed": true + }, + { + "mode": "disabled", + "capabilityFixture": "manual-selection", + "command": "clawctl gateway-isolation enable", + "label": "Selected", + "calls": [ + { + "method": "clipboard.writeText", + "value": "clawctl gateway-isolation enable" + }, + { + "method": "execCommand", + "command": "copy", + "selection": "clawctl gateway-isolation enable" + } + ], + "passed": true + } + ] +} diff --git a/docs/validation/pr-28/fixture-disabled.png b/docs/validation/pr-28/fixture-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..e3be96a07d9bab4293ef4d378cc98e101de84d44 GIT binary patch literal 41835 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≶6q`BwXQ%68lG*A*A?_B<5^2z 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 literal 0 HcmV?d00001 diff --git a/docs/validation/pr-28/fixture-empty.png b/docs/validation/pr-28/fixture-empty.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4559fd397ae5bef26581b2deec5c38437bb009 GIT binary patch literal 28633 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 literal 0 HcmV?d00001 diff --git a/docs/validation/pr-28/fixture-enabled.png b/docs/validation/pr-28/fixture-enabled.png new file mode 100644 index 0000000000000000000000000000000000000000..d0518d6f37f93c39f98f645fc2e5803719e70553 GIT binary patch literal 41850 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 literal 0 HcmV?d00001 diff --git a/docs/validation/pr-28/fixture-missing.png b/docs/validation/pr-28/fixture-missing.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4559fd397ae5bef26581b2deec5c38437bb009 GIT binary patch literal 28633 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 literal 0 HcmV?d00001 diff --git a/docs/validation/pr-28/fixture-uppercase.png b/docs/validation/pr-28/fixture-uppercase.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4559fd397ae5bef26581b2deec5c38437bb009 GIT binary patch literal 28633 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 literal 0 HcmV?d00001 diff --git a/docs/validation/pr-28/fixture-whitespace.png b/docs/validation/pr-28/fixture-whitespace.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4559fd397ae5bef26581b2deec5c38437bb009 GIT binary patch literal 28633 zcmd42XH=6}^f!v*C@KOvh>X(4K|rZ0y+&mO5do1721IGn6-W$_#D5j=7J z1Ro!tpy};@?(^{-`NYTfyY{i)fKP&6(2wx(o#He7=Z4MmEc)c}2+_fBT2md*4!a#c zb;c&h?ev3B0sr0;xTMlxKT$Fyyc}KUQyb_%SyE=}TssIn-$K_lkAE)v`~8g2S??pF zr{9Y!O#L?W>Ea(L*Z)XlToikB^5XCRcJ@(stt?31T?^4mWU$mW{-U5rz0 zQ;oahEr^9ea&=@4pw~6oHJzgp$+lXf_7qQ7D-COSHQdL}VN9Ty!+)r-jS2Q(6)6CriTB(&V>?B|$Jd)qc(!akE* zu(Y!GI#u`6SBty^tdqNwQ|tUD4HePH3D+D)i_a>LtGHsdAFM4Kf;M1v2ci_Lj}mUl z{v+;DAUj{6IGh|4bD zh>#xf78+y&s7uv3*{=!E@Tp+;!VC}3bAP{4B`*!4)vi@#X!wqf2wodvW85yZUQ%>U z9%!<)s9w+zFtd+*feCrsHaSvL2W+e%a=REWGgv%{Zn4 zHXyb1!$E`5D38iv`#f#72M>B*6-5VUP&Fa1m)tzgJ8Bj>1~l~g29y?I;du&gy%Qpi zF8!zL$oBU3?oNw>jCsw#gw*jW^T#e{M{lD{zgkJQe3Z*nwz*&VLoc)Qj7RzN#(+6s=J9)0>nRBFTbeEaETxQ|B!?7jPYMq); z)Y37KUg5QCYS+Y()g5LmGX4r}3t!D_;>4~a8=j?mVyoeZFr+F}F5LJ?pv|je?L7QCXfnU3bjHR3ZWkRVJ4{I@Ug$--&8- z+3up$csoMR#05D5w-v+r_fFd6l%SI;k6I9J9CvaMGT}KsGb1ajXcxjDZ`KTu{06bP z?)etZz>=L~J$szXRa6DDG45*aAIlX?Gb|jRba<}*42z_Ys;y(BB-R^IOr4dSCWfKT zQ(|VgkTivc6Si#fu3r)jHpvNEtgRmU*h$;V)?@6CB4EqlhKFwc!$#FCvvag) z{TFy@%sh=Fb?1XPJPr))4B?_oKu=V`eq$Q)i11%cwcGUdfv8nbo^REc9Jf@)?xKcp z{_@CD1IUsc`izFvC}r3s$V-J^49S5qwrjWOUDaMH4=NtEPn*c9XUpC?GCHbLY||Sy zT<(Go8|)PI->i3JjL}r@W@>D7OvTl+nVqiWihxSJ0GtQI5YD1iQ?O`5 z7dC}0H11_fx$wuB!hLC9q@#9*wU&n@Qho^VvRqbXB33UsbU;|?I?})V-vf9%MObcaVms3va zZ_j19PfzA~eX+kwQ2zbgVZ?TSmKK$;Hq4+qvD?dpyTQC>r?dJ&EhBMt=OGkyFgYT$ zc`!;nd}R-0zRH{g#r|1mGB{>nA-x_2;y(I1)X^>8`=^E~^^>c?F2+lK^69g}en%pE zH!Y)2VCmGVuf5!8~ zVbrCKjo$&-znShhnz^em_$A_>g7s|lXE9y`EC2JAzGpwrQ6}YyS2Jxsrg|-?FQigU zS!Cyo5Z$Hr68;#slh_9s+XCyCiq4d3jG)`;LA1!g4e&x}!?*0z_eWn}jQ zO7mROw_BODy=IBStN1y(Cq>8OI%QcpGXs&5zxiUlqsY;;@MV;geg$?y)g^N?dWmX& zw#jKs>AR>vbm~xucd&)j({Y+Dh>U_i7!EJbW=;3oIy1uBb3=WLOm3^^Jf|l>DKI@X zwP4^_$w%0hJ#c(RqO3}VvFpcbp5Ru;Uh+$*`z~y?Nr^*$^|i?Ycjt6xXJ@$so<%aQ}u3>+z~lJz2}mYJ2V#*kXd(4v86&vvF}uul}}v+TP%qV1+^Ba+#a zc9565XEu{(VL4-CXUAL+$E?)t4=2iP{8+{$r=~J$S%hVWMVqxOK8_5jjZO-KLBSYN_-4|++88zfcR7s`w=0{Cx2AfX2m$C*9%8F?~o*m)22%0t6C-s@k?GU;(fC{-uAg8 zX+a~POOSkVV|pMDWtj-J(8*^Cm@@U2c1}6peLj_7A;y`0R6K?9lD6Wr;9W&i;xU)lh4ynGtd)aTnwNSHo_I;BnXUU>r+(yGD(xF^`IiL0)>I zo2~25qwol>F1*`X3_Od;)T74(_a;JCW7PLimt9#==|s>EE8Xp-S%i)TEog?p+W>*h zcLi>19KpI=^eV5cgl*2nVVx>ctV|h8h5!}4;RYl zL-Mvy%Hyms?<99q$Mql+%nF%UN2u)+T8VEtmi?i+ck)SL`L_S6MkOEL*Ruhz^%-|- zjrqUwVlLV0uF#67Q9_6LZ9|)%?FrLUyVL3-#^!hzUB`o(`x@jliyX;A&RPM}Zv`U4 zo}`U0W<7c>hzw=##*VwfSLQQD0j$yb$4QL4$j*?(G06KLrYYusC)_FMrx}arLKaPl zgw@VfJ=RI2k1D3ffz#%UsOJdjX~qW}=&w;@R7Sxxv2yzF0&7%GiVanq#`-vSQep(e zu4Y%RTPOYS{zv4yuaPw4C?$8ZVEBtaZh*8yHbCO`JKCf#?@SRrJPH7SAR6$>D3s@L zJG%uoED*oFAbuQJsr~(=$#181QQ}Q4pBHKTUT={1$K{WZEG&rn1*IO;i;nSk5q?W? z`z+GvLy_aa<_0gYd`O6ZxFWyUtSrw0j{d*r+WpVxhQFm<^u} zXVm$OmTboANg?L6S~l!m(>YW<-WtdYLEP^(_yYhQOq!g4b_oJOxlXXs-lYwrxys?| zTvvjF*W`!7!W5=-P3{|+mn7HF=k}H4=?Lg(C~Kd$UJoMg;jVyz*H%5c6^4yH!oUY_ z6t@h4rAm6b*}wk%)2)tB=ac{Jnb5gsa~GDCDE=%mFL1;W%Aut&c#K;Bd8znzKmiGN zGnA&c3$4tF& zyc*rrRb`#|9M@KkW9^};36!c^T|fRK>K^?eaYb*WqwG^P?mZ;un?^T-z!ptAiMiv$ zE>?SfeLr2hZ@ZxMYu7SO<^n&x6HG(237ZfGu(v|BRDh#xP11S7nsAp9{eWL!&Xp>@ zg%lA1+UuxLn*eV$w!zhHTr7~rwzeNzH}=FIGN}N_vXDfCca^Ea&D!Fu3@=RcKWSw? zinTOSHGSf7>i@_jJK+BM!&{e!ua{lJ>6IlBd7Ix{DTLmPER3`ZhuN(YXAu@yol%qm z+TkbeY?IL32Zo>4%5f;y1og&OmBSPb#oZ6x4fA_#pxd_-SL((C_9Y>A>-a95aj?Cg z=r?B;amUOIRAS;_Yh`8S(9q!CT2)$V8Tr8tV%zb4Z%jc|6;td^>o2Iybf|JS4Lg-p zp^wkc&%gLlRY~b2Qr>jFBw2B(rna2NWfApO8)jRCL0J(ghA6ufWoO9OL;P8YJ(_7! z*m|oNbi^%c4QehzTb?`SL#`%XtjiQ#j%t+_~AN4-3I zp5SOEX2I?P*PA2sx-n_{TkWTZU34C8iD1N#SWcC&%TAjz5y#9R>T^2BH0Gl{<2YS{ z_T1HS`GqfN6i^kYMpv$C@4{KwzUyVaRzYSO}*H&O>M{IqD|NNegS*~K$KX4s(sIIA8YPHyrSy4p~tK3eYS^D<(GrGI=~blJ^Ur54n`tx z@3n2Q(b||yTuLqDV>!W^H!Hl{hkZ<(wbb{ZSadAQAj5e5hrC=M^XdHahQR~=s;R%| zKV~|#z@XqlYZ8$@BV%p(VaFu&nYDJP&r{TZ3U;HL9LV;V+d3876g2D~43%W&b*UJt z!{$~^%{Cx9TRQ|vXDDcCM?`Bqfj{Fx=rghAm)-rzT>zp5vftAFd^9d4p?5&`0hM&sTcp$KG zbJ1sSX1Q{f>^sDA6U6QwmNwUpl1D{68{uVKQpmo`Vb&A<8+w)J<^n$&BkqItM@e-f zIQxvXgL`>ItLyqI7Bc;njy^u5tvf82amaxF@5Tnm((U&jE^+gC~yd??6! ztG^1Vwymc`78r)!ERF3#r@7i*^D5`L`PvTio~%7PR8o|kV0y-q_F5X5VX(_i)Mz~+ zXW3)GtRbuz#Yi5_=DltyL3MR7kl(rEQOz(tNH2Jc{5ijsKm`YnshF-eYn@H5zjRr} z^uGVbGi%cTmm+<)Xe&54O7V(sYyW2;OcXPr@XyI*ytmOsAdvS_X@4gLG{Jpp^)&mM zn`W}lP}42)`vX&SJs z!HWD?+Y8RTJXh-t<^%>%F6i~w`Xe6%NG) zW_0$LX<1WMK8j-E2phxoaVSDXL+Emhlt41c+&Ju0Uw7##@lpr7hG+Ahf<_g#6|mF59#%dGUx+6Brs3-wTeHwv+*q{q;B%-Z2JeHHHeU&rD&JKBV`~B?b&FlI zql57B#NL3wU(nnIn_t{d1NIi!uULNPaPJRWcDcZb2ztX4 zNX)LLslIT)+;jW!;{zdKDdeZH%J~iM3W&4pYdh;3vPkyuc-oH+fGTp`LDig@*?w*+Bm=N@sc91*<9j*c_mi7e8Ui92I4A#@0JN9a?Uhke#fj_p7mz zX}(9P4(z>U)B1aEPHj?pDp}l{*dNWuWsG|tPy*L67O=9m4r;b;Lm*Fb)7K#G=VJKp zI}J>-rWnLq5zk(D|=8`x-%=>)pf^tt`<|& zU353GO9iJ?EOj=70%r*l)#L|xf!uKlmsxFHNZzI?*1MzSgzGWMh}l2&o0X1@)@T_^0XnhB4r|FX6$NR4VKtxn2yxFiv)CE*n2mR)(_ zW^G~CvpZoQqttq}W#9q6zH{6ty9E+Tnpx;Y%9(b5yLl?sdv{~LmZ5P>`X6lEd8Q`) z{!U1<+n3;^doTxbV=(oet#;@({9m^Ysc`!G*Tceo&MUM+6k;|;OGtn1tM1{{Hv%$S z$}M%dxk%2ktA>da_4gqfYG|O{?$fm&M9o9QRX#| zJK7^b?bELsXWlC|zpYj68(aEtwUQj?`PzpyZ3GRQj1HPiLd8Dmr!)jvG^anAgXZ=Y zA2TDvsM&6V{i%*=J2Xq=dB|T`@5kCi4QDb&fyp+GnZJRXxjtLQdoH<4&@%5WWs!nx z-xwT^I$L*QAhg#j4Nk9YYi>;^Pge-LS^AWtbB&_jGCUjNo1rBZGj##!LFRAcFVTa- zSpCu-a2%L2EdNos%P5j&bgU3AVhldQN4TFs*QnGe34f(CKVM*KeazOwGl2bA6~-Z9 z|7Ku@xgp=(#88dA;=&%n_MUIyYP>x=z%g#1H-M5m@O37$T;ghYW>xdV1iLEv!rPJU zUypO}OBud}kS@i`OFt_Y1|@g*g}qrj;`~hi_2N!FCd2hPN2A_?fgIU=9VJYd{b7a} zE)K2=y21QL#Xh5M@nw{@Y$RTcs+YH{u6(5XM7`uj^>UOAuiG-7Ak#O!_Q z>Uu5Ssm3QWIs3#7(=hE18BY)0OuY=gwsqpBuv*Byq^+`h=Q@;$#9h6Xw*cNNI9Aqt z9{MVAq1WNQLuk(%aM2w;MTPg#B>^+X1pOy-A4BXcx`tK~OBZr!KZmr4yFEYWwRh)| zy@}#COg=2>TQ6-;_jQoT*h#% z@9^FR_2%mYOftN?ztV;dMeDs4Krl$ z#BDPKx}NAmGrC<89!I;N1|9dW|5BAr zKebRM_o(6bii=y~zJ}i;1;pOMErcKZ(QAZF{+X1e;cIsZWfK>4npsB>`P1U|%I!-A zx}H^#n)YoW)alMQFJwX-2gKh>j)XJtE&nW1<(ESk!v@SPmqAva-@T%Xz==oQY7ukW zA-t(}60tZk{i(TG5Fz$zJLi4;yEhCc?H0F|pg;DQE6#z+BKpoU7>Bd#f@^loo^Ps=p&Uh z-q;&k3}MelyJ!!hXE3&mbwzC3x9zSmD^ zTfJYO?0?jiiTmdJg+FII`elc%xSd8n=a)3tKD_5=7sdfsKAS-kYC%q-d+Qp*bJn8` zMCxu|m@Vr3~z`9Hrm8yl;F8*`3wZ*c8N5kxIB-XS?IGj zM?*yq_!lSyqm4zu`+Flly^c**FyM@E9Q}SM>}~I~eD%3=CZRNd06I?E*?E+$YY!z8 zUV=in1J$`Q2||X=mJQQwgJZHr>G!TF2~Q>hUb6mVf&hH-C#Z21yWITGh$dbwcmFgN zkkz)QQvI(j&P{oRi>kTHiL2iJr9Yu#MH|x(B6A{Eq`SqR7kVzj2N6s+JRX;iO>$L} z^eI2CdOok0TZjwJ?Xq|MT3Md4^QG?KKt=ION35+)w+vX__C_;DZwpA9SXuRjWje5a zA4=dFfI|9OlJDVCU7Q_~S8Jlw9&EC2?|EEuvmGhOSSvD&+4XLoKmRCtjrNPi9+t2P zd-Ph&4F_3~dOr0s)Yp3lcaKthZ2Qe&;n5js?phQzCp_Ra!{GSK+uF+0O10j7e`i|_ zL3@6Uw#4Y7a_{yCKIjroLLto^1DQ~q&^{eQ&*RKK0Qm~Czo^D;s5jj*ab z?lf|!=`UG5J-<{T?epHBznJu0cOGX{%znMWufINLEh1+)03{-7y;$QI*Gm)abpSZA zKVbu|$Gb>{1=Q|qY8*cIhOpiQ+q@ZfmA!@l?B-y|UoFC8w8UJaL_(_po6ni@;>?rW zeX-bjfW!tPlFeCoaf+b8BzH{aj=GZMp5GOtgF~a5A-`IVmpcBTyA)%omAHg> zyeKkcDsi5BswHX=aKhIPMGC?8#I{3O3L((p{l5p_#?>rTCg@u3{W^^(vII4riZ!?^ zKlpSU-~&(~imO>=G~OO37s9YFby%O3<~0x$^RJ4zwTBIbE1c)5s0S(ZvohJ+805-C zWAI@sE2ojl`L5Kcu;z6jh4%eyOrxjfO2km3fam10Pw=n$alr_9hNjygKEjq^OTEII z9LEyJ=$~ja&HE$yVJ)P&NF{L@42h*8m4&)4Nh@Rl5rpC2Pl^9=g2>%lrj?y9*I_?6 z$Bjem*{$U7@sF4$$(7ZYC0XcRW~YdAG04Tg26I+^6$cHmDW%W0XJLz%uUUd zGQM!PX@3>hCJ}sh5%N~Z&0CkB|_;StE9A#)Q`CzB1IgTBA;!WHafYReNCG30n?PcKqTnH%|MQ_#RmgL3i zmIP7=;`%Q&?7@dgAKn;~04BFp;DQs#4ls~#>e-R2O)V_IqzfX{pImrwY}jpN7vSi4 z0yJ+3dRlH!9wcElGMHp(*!X2(JOHN*-w{NLo!1tfmLUT%7z}O|8;IDVEBfs4gW#Sc zVh`eTgoukdP%=!TEb7m{4X$5L6FgwP_SU8=*}`4Eyc3d$t#TNdU@?#@lDKL=Y&fTj z0}q5Pj^qn#(nl^tNo@Qy5-!j>&Z!I;m_AwKKYkFX$_<*e96Rub1L4cgH25)i{?9x! zR(5}K)Vqw5=EQd*@rWTna$h8HZ$iQA_|Zb)_GywA`&vLwvoEHF(dh$el?a zrJ*aCmFn!%z-8hN>pNIczrWoxQjeD^&SkEDu{2v8eS4?*IFHENCuVG>*u*tB4g~yr zVTj{B6fR?&eZ$Syu-1JgSYp}bO>XX(JkgV~l+|&RARvf(zt;EbLy(opifZ5`Bx@2H zg+H-wzA{;E4a4T>4qx9p<%1$+sDd5R5El!3HLR_Tddi2&)eL-$_oD5n7fb8A|2-{p z^Iz+I-zxHCIlMiTV5otz*r2JJwb$umf8%qt>xveW&s^F(rae@2-uz+czdFrC+Vqjc zCD-QRiFdA{dT_g{tAS=O<<`@WN~}2+O%_}HYrSXu?ydCPA-|3Ic=GCtQyGI@O|}C$_ueI?f-|X=KBN4KT%R-cs(l*5emV zt=y*7EJ0RIP8one*Okphg4q7QP&f#K%v(M@1QtCDStbNuivPOcxbd{_1C6v&2}Q|E z!L@QBS7~d!6`n=q?KD!0AcjArhkt5P?9_`a{u2qhmXAO`Pqa+s?QF}0#6+aur zWW=8kpqdkwTiLm<&2pr4o-${Cm78Qk9`P0e4c1weA{0wqVeKb7Q>%ldx--OU>jeHn z0yt~(Y1}vYoQA+Qo0~Q_u~)Z8k&=+_eY~ulUsJE64od6pnGH1El9i_>tqa_Yw^9Qq zdC&QE^YNRxqV{gWdLFFrd-#4iYZ%cJBXS1A7tE{?xZ9<+Q!_A_{T)b^s)f%P)SmV?Ew!H zH8{<)c+IDtru((wb)T;oobc(Gdn$4Qo4qrx#>8M{9#hDTGKgoS2Bff#7w?LF)>8Po zuu%E=<;rbmYev@Od<`XwV3szz{yKfw+|?$i2{7e}Cd?#MWZMq!XDaLu;J*yTc zLGZeH@+NluK`3?|(?O#DDsTo0lx_oJO$}sdPaV67O%T%Xp>$SSVFmH*QcE&!f!Pz_ur^lnZl^&?=crUXx0;}3dB(se%DiYh=e6Mt^V;Q+KCm+2* zRlUQc$5#|6Dk}@pew?Bm1zsZPv-e`QIw|{%n5dj-+t$R)=b0a?K+56bq~&fa>~OHi z-6Xav67wD&mIk}t5J*W;MbLa_$ykOK<~;qgr!ELYj0oMmU=-Wl`Tj|} zFyZgtC4l8Q|EsD!bz4#CK~_QnkcCUIu>->8k+K>C$)d@-E1|!Q-uw?M0rV6JQXf?o z-QC5)4zwaBlT%*=Jn;Q8`U(iZ_mAcOR|Dqq;aH#yr@y~{%&ghZA?-kjh?IFV)++D}89|Xm_*9N7Hmi29-Hdj}uY`MDugZm^z*Oxw*MFyPnkL zTfL$=zB0~OUb&f5$s{2-L_$y9_*+{bPkrjW2B9}`lr?D(_G_}W4E9_ ziDW$5d@jjV)xuKj0Gb(=BuilC7s_|7W54y4!ZypnxM7$6+U4GZWSt05Fyj%Gja9Gv z?A{@eM4kxvnLC+ck-af?RDg6oc-de;>u>$hKaa#s7%aVO^p%HYWrGc>CN}je+=cU+PB#a4%mUje1wm+6olq?7DsXe74L9vN8nE^sgIFJ6~w- zIszk28;y(V@3N?_rjSXzkK1~8)M|M3_&a%KCpsq+PD!hW7$PvOkL8+n5NW88aaWf+ zSjiCP*X;i{J8&lu_nc&1kJ8&C6bGh;{uwe;FSJ^@vD=4)vj-C=CWRysdxTxv&=jRC zeFXix{fSN|hWgsSB2j*%6YJNy_puuZV|GJ_V*kZ%tfXVQbBNah_g(OMbry+3lB~tS@Hh)tM{^XW z5wTTD$H(f)JBjbs|81NWXPI&`*Jee_}l6;1sxtu&)vMTC` zR5YE=8Xah(K)Svs8XT22XfXQr9T$lF`y+x@j{c!E#(A@;vfn#wf47OVw|?Z{c>Ju% zm=cPm(@W{}3CPOEK($$Pv@2p4R4BNQx&n4`8bh;k@Wi^|kESB7;h~T;?| z`rUH%9E)**YGa^fJwYpSwiwsAOSjwTFMZnawX0X^4`u_BS(={rJ~}C1DR4^1Ubv&j zH{njAi>!6dIs9{2p#iHWhc_o9?Kh0$5hT%0&L0D6+&3Dw>#C5pip2ym-qciy)oqqJ zxglsvoNq~cRQQcvH%2o#Y2Pmh2cu>R`R(EqoAFQLn8(0yIeFV8mLd&Utq*X;$Oqr1=+W^v{|vQM&! zOi4vw3;)cQg*jI?hr-M8i#ha(Sc9k>xRYz#0X$z9@db=&%dI2(TcfH5*>?)6u2naG z*Btj72EbuPR+?J-WPEJ_0|KF&23`aTI_drWWPQs-I^D23sC~*(O!0yErC$mE4@)fN zww^DJL2B=(2_VQs>*!w}oK++S?@h<}77W|~HLQNBnqe&%g1C%43|4J-MF(D=1*HI$ zZC_JwSOcZ@Ww*NQ1kN^P<`}ZuA4~li9C)8Iac6oaPBSgwqO3Ivc6oHO$eOh>j_g6b zj+?-5zq)MsA8(M4RFm&f6ma|Qncuw zKmRltxsT6(oC*f`iV_UQd{rAtotJBkKAQ|LS^QDE(dnwH&x@s|=5N$d=BJFHB+K^# z??wLSYI7tdz_?Hh?0f+%V3nr_e|{k5aJgP!(0JmgHPw^xbfFvtc;95$fTv}8ct5R8 zLVZ2uxE6bE^db(>B(q0)(+>M}m0xJ-dDk1XN>==qgyu}?riw$@xIfh8YJrbAgo>bo zuUr9{p1)d7RRJhtOBu_R*CKCJQn`O4yvA&S=o(KStmM7KxA9iWr2%3ky_4iSL^%G1 z^A$L!2%I#iiNs)Fx0;c2nwEDuH}~MwDdQt52fIG|KSmGW7u_y(evTB*-mntPk8M=u zR7-B8s*L+pgZJQ-fg}`kYRX76g1_x3Kr}3z<_d-P*yWNqf}B{8Z4#)MSJ0 zxxCTQ;?K<`_C-Pl)6VD4ox|XD!^so%85)5u4Lf<|U?|z2gv3sc1?5VpYEAP64A;* zZ5SI&S{wVhixJd*UkFm)>kw-Bk65mG45=S#Ym*i;;7wHXOGY?A6l#IYqidF-|Jt{x z!BP&XG*vfb1nWNzi771`e@8U*WoQftw7DQ=7yDGV4T#oNrn*9S_LtlP>#|lb^!uT< zrh0P3e)cZF*1|X5t?wgeU%-MX-s4PbmKhx=X-?wmxREEcaFB7G(c9U~G5mJEJz4d( z&u_6%xk=5dI$IxZfCpkM3CkUGpQ`y+&wNR3;%*tl8R`))LhFs9wpC&7kG3~5esh~S z@HCTx9a;SRn=9~ zs~7!RShr@s7qNAE zt98UQ*{R(%0Ss>Sf(;38xKW}folaR@Zj;jW&P)v?dQ4=@YaD6*zO`OId9Bht?wg75 z>b)!LtK+C5C;i#FW#0M?Qj$u;!<`q&A_4gMY2gEU@|R{NlHbHQK4%PT)Yc*d!g{vS zdEH7tA!zu@Kp}j;3@sp+elDiu=_)++frcjA*{-T4Utf<%TC;|lCf*VZw7#~Ro_YtO zy`Jhtcim1&f#c+fxV>+oCqxVPT-dK)qg`xqfg3*}^C-{d&n4n(v`sgjZH`mth4raR z2JgG@bAWZ^o2hO*WCBz-htsRZ^SyG;hfH0lO^pi4Yk1z_621*XELG!KBf-7CnAIv@ z%tB1K2|d;X%v>S+ehJQ-2at$;Gh3{7jU(J=A9Eye+)B6aLi^rleXDh<7JO=$xcoVZI736s`bfMPhhi~ z=E{my&&ZpO@>`q4AVGNbK$2m0qR!($nA>#X%na*GY(!ANtWP+6Za0;zS*tzxWuV;X zD67}odP)RsgkX@;Rp~uGeKp}(6cQGztL$6+6+=|`ybJKmMGi&TI$&{oI|2k!K zO)c{;m0 z0h(5uF!(<%t)@?dFv0zQ?QZqpU+3APhd2bosXh~_6OBJ!@=NyD`Qr-AqNNdw+*8>S z&wu8c@3`NQEN;@BO-|{-GfHrj)u-S4!fPymKn*(qs&~?mkU%rG4OQNFBMvO)R2eX- zj6YC902IddWNKNG${i~IHdS!0@lKB@Px(K=0Qtl*Ac|}hD?LVh-Tlfq=)htBdiGK9 z>XdiJi^DUrQ@~6kH~lQW_I+$Y{)eL%{sX-0TmRcbRZ@(N9k!$?VsNRdY7pI}pr|M^ z@|!#G<5Ad*vMF(dlsE!!_-fy6{JR8DCJA<|(pOWHLErI&*lqq^_oryG=mn^vb1e{I z_`47mJ#iLxfR(Q2Voqo)DA=hgs@zpj%$!#j042*;%y)FRcX!`OEG>->d6Smc6k^-e z#9q1u{C~u*#-o#fOFiEjd10{KbpE#1$VOzo%mcLBXN6=Sx-x}!YdK`n@qQ-$X?~UU z@$Y#{@5@S+99^=2@2-hfynK;YRrLsH!W!)t{QJzcSX;$Z@e^VPUwe4?kO_=d(%r3O z`Q=nz(4?oQXG(JUUEpgwRpZycTG`bpD56i#hI~DH`FrrZ2l@cF2z1R;E~PGDDZ~*= z&Hj?+xI5ABeLT%TDhgn>)o&G+7pgeHCb_!Lk3tpDR+z-H%8l2&Ufw{@ zIa80+V8n#qGEgrRzQ3Z!iyv$nW%3xMXS1Pqr-DBwxC0HF2e5r0!*i>~1R_Ee0oiC% zwHV)i?;1&~XEYT2EmQ13h^R*g9IFm4Z*1z?6`P-{HJ{o{Je{cd`U9{d5l7VLcg~B> z&qt%Of4Q~y(MGd-b%~+%Ibb4hc8k80ta$BO)p3~7b9hW{ST2{;B9aGf`L8@)In*t^nHf_qeW3KE47sUGFyyyPBFAHX zX)s-S>}@#*G1^lMAkO-*nMm{&;8sQ zEwF&sFDo)4W{)SIy}Q307(m!230s8AqXDwyJg<@#G2rT1JAw0RE4{~yhO(c8^^VaJ zkYSKe%w(Oj;XW5M8PNr1>2E)?8sSMg!_{|t^-y=iR;&F3wx!Oz85O&ahb*UAYt%>d z?nF_c277ChPO`UxrEr`d6wW#s*{jew9$Md9R)QiP7vOCajt3Txwv@zh_v!eg#KRV& z$ngrSg)>7Rve{nP&wmBUteKbGtIf2pwKsr{tEdzFdK;|jc~8F=Jtg&^7bnnEJKNBn z%%FjWxbT4eK5H%B!dpF520jdphmLE?=OX6OT|n>a;!rMdAH6(1k95d&JQ?~MV9TE_ ze=Jil)f`+Pf3tG3`SXvMatg76!{rarovwj0q!I?3V1=_5#nz==EH10XE9a7PmHXkr z9@uV-I|G3S;VYJJfY_9l@V71z-x|7zpl23^kGZTYwS8qGbwj|o*LT>1!NJy;C)R=Y zR`9OG@|DCRvnsm2-`Of{Y{o6>$xGtUzDBL4hEk)A_3zYU=om*dfmDO9e zwCV$hqJq%Z;cjFiVPS=-<(%mr)wg$2dm5%Eq8W}qX=!RvsD9jHP8Si`QZptz{IPu8 z4p$B|<4Ip1;o)&LW_QFaGPOMrwqRBA8Yg*FI)TAO?{vPzWVVD5CZt0SOA|ZOq_LMWP5i`R8$$aGBG=&=<6vU z74A*Tvac5pdloH;D|M{N)%N)I`H1O8N0QP&fcC-|vOpepa(|$wtwthfe)6?*ov&zB zEc{M*95$fuGX%`fR18yrY3Kiam?d<)c}|g$0h*#}p`^Yfk@2bz)akFRM4~3IJS0*+ zWN9)ca#lR=I{xy-NU444z9jiGkokc+hM4_WZW`sL6%$|&_Ud=za)d1%Z9bmVU)Yfn z{%~Gve@mKa@x_3DWJm*^;)Q@GRZM1w~=ZSRSH-{%*MU_^3JVfLIYaHMOSNp9~|=hlSF$W`2}Y zAKVMy<&QI{*?7&W7vC#m8S@%v6O2H6RBK5gL;XRlc}s2Rs>J8`TeoichS9@OYR~4< z-42dJj@6(YI_1`Yv5VSLVTgiT)7cldxB@VO1rq=k_5580d4`i!m z1g$ti3wj&5Uta6hccwpWxoTfl_$n*ErB90tvm3TlRn{$PV-%WaRz*x}SJ_c5hvy#s;e*U|&@O8>*qWtXEH|5zw31jF%?TnlptgijG2h-*iQ07zXO< zyloi#J#1Gx(V1I=A5fl$ z2AV9P*eY3RBD{?O-ER$S3AyDsYLb+*8nia;hHZ@n>q_W^aQ_v@A$ZLnx?}#e(v=SW zKia#_uqLx@&Bz&1Q8*r~6f=r~ij)D74k{`Fq9O*Qgouw>;5?Rxqs#!etplEC;QoZuf4y$*1Psv?_x0_D|I6ZTM0>jx zvH8i))tIf#&PScK*qJF23xz@k)D-FpeIbCDuF9XxJJj&P(QsTyqtFR(D6Jhm58-ri z^eDY7S^U8s#Li-phE!GQqpAwRklw*^1jQS&%@uXVA$Sfw?-b;$GIAr1a91ZB4U5e+ z7>Ve5bvNsj9yHkA;KL(m`b|JZh1g(H7q#mdw-8pNx>r8I?UQ;=BqSu{ITjC3A$qPR z|H(UGB1Ostf>ro7X#U4K|7Y03EB*k~ZZ7s3MpQQQwinY}kyZ`CmIF-ayIM#A7$hIK zP!!c%gr-4824&6qp+13si}5**GrIEWQ-(VO;gYUNi3H4ox+M2n-pwc#uM|g|P0vw9$OFKj%^j{V$p$Me!~`8X zq|JVx0Z)Hrb#s~?*`5myQ?vXO2H5bAh08SjJluX6dsH?**&ex4(jntNbRc-g+~OUO zDUNgQyWcM}1_=2Fuqpd(T+gh~>FCj;`@cM0qxTi2&HTU>z7qS?v0f>^D?D*@blg+6 zf580}4QodHPqWdana0AwBaj9CG=113xx zYP6+QRB$(Kf1sPjaKV^2@QMxs=FUZ9f{{*fQz8b7&EB#yv8sY60i#;#`~G1d$HB>| z5?<@mwlV>hvjAQkfKh}a#l>P8X?fW$jnM$R&1pb&P?d2v8T`e;ypHzgxxxu`O9drv z;DDi`K1au53yinEko7AdQlw=5q4~u=?Y{O8*+3W2YZ8Y&a`PS#A87IumKzhl*#GeA z|LdUcUq*rdaszCtYv=Fnj5Hb~EwkkHOlinLb$=ou5cWdjgcCIQG3^5Ls2iKoT~ z)DN`8oY0YDe;}Y|Q*oetG8f$*@7ml7Du)p|k%Gr6|v z#wNpF_SkCS0acf$H;B;vig%Ga+~1k1_cP6CQtMRMsDpIKYFG9Wj!%~K+~niApCzLX zM8?gF1YAq4YiK5Qq_2f8%F20J)Rg?1xcH zKo#~_;#jk9s-{c3{BaZa47>@hK3p>35lRG1it5F2#JphmL44GdXh-x2)1T9|BS zh?b><$JDxpOJjEGDM{9FV~_5I%JCGy%73o-<(TT;)^!8h^=%!Pw(|6lr6OL(vBShn z2DHjDj-lo^bXNzVc&v2l`<+!WGZ=ok{bj9ffbW(cTD{f+UQbXnTEE+Rs+`b^*HIpS z6?SE0!lI`;?<-T$=041>pp%Sq>C=2#@f8&EE>tL~ zi2nHV&yvhLHSSOB@RJcDIswcq!xgH&1ysv%z4xYpXz8f{Y0SVMFr>?k*AvO26tz;y zHJGS&p#d*GE{=w%c3CYsPBjW#ctl#EqTGf{*`0>B&)XWWTLp==YVk5`-+3?M%@!z6 z%LWV$biCHW>@%3y-;M>z_5wTuA0`YP9}G2W0>g05l|Mf=`=)jx!7#_%*O|A_K%P>N zSJ)r5QdL-eGSgu$ZlaQHl&L+T)H5fXC2YKCXYFXWBwte z8?vC1gGQ*i4L-ly7C{0MXJJvPY~4KMPJ!QfW-C5HBAnpajlU zRGuq_ijmh|3Wv+ryRW7Xm=r3c54g_;$j%?hr&|N0H3qgG*E|OxW^g<`nXXI@;ReAn zDrhyNlzGqYGKy^tY%!&}rS~8(|KOjLjVuz*LLrXl&KbhdZ?CIS%KOb{go`{WW&*hq<*p1o$eJx|%YyEJ;h}C%n=<1546My0V zuJIG#HWT=}&hBGZ1pijM!0h=4>VNqH{;g)d`?c>Lc)Mr*uG-sG`MWBASMlv?!(DB- zs||Ox;jT8^)rNlwZOB2cFKX8mZCxGPP~2a8N#V;L!=J*wWy{}}k2;XC$I9}{9 zv#!pEUt=_TA`L1YNqCQFE>zfqYhDdsA3h*uomFah6)Dv5|u!1w?p_GIth(c#R-7Aq3BlJ?RqrGZ&MejReF{0l~fkzXb02=fUwC z;J*bp@Bd6K8UtPgvSmH^kH18-wB&Mc0Rhol{5k@Ei2?5p64+Wd?v3$x*k5U*{eM|E z+bDSif?tzE;8)i!bVz{!vh|AlAW)hDsDFX_k#6|EpJ}G0xVSjqH%;vCAj|zGm~sw` z*8yI?yAkW^|Dm2~$v=9YS2)isfTKK?N)<7dWwVu7Uhzl;+?Z%hj(ZzpfLrLTgfL0I z3o0e#G9Asmugou=5ouMGk1`k@=u-s}zAaNc8x)r!|p2Jh5%A&03;A~&=^qW_YTjOs`F>F7oQGSmJpsc)1x|0SZTs{+6D%j8 zp1DNW5AWUBr>f_1)~d>-r-*o%e<{SZz`3)ue8|^XxyZL&el84Qc%Ubeace@6P&`B3 zaPSOxK6sXQ#1-c*@;MRUKo;1}%kpKAi5Q9T$A627a8d|ypH3Zre%5j-%Q|tdt`ptG zHQplAkj$uZFC2OV<=q9EJO-UryWi&CyYAQRg-@P=JT#ZT05x5)at=Qli%$%`%^R=& zEjFUPeSpaust2y|q4iVU083GLm`s8Z_vtv(Heh=Cp*}sN04Tl?v^u-FSth2eqSr4W zp>{d9${pPaM6tHJB===6C%m3qG=R%eNixnKx{f|(h?2d)_>-K{S&Ak{hK!bo)} z-fBjlV!i)Pl7dTLk)^R`==c0+iNtr8#MNitVQf|_MbnqYxO(yzEWNi*N^ALGq5PY8 zW>P1OW+7iVNPhR3#v6OBNQ+Hd>RUG_G1nKNa|Mw<6bAwBx5%c=C!+kF^am zG(=KFn9*OqTu)}Hxs5ClUGteAB>tHCB_Q>nOhMfK)1}9b9?ySJxGW~K__S&88T5AF zfS#?*3823*!S0jl{fX|*fla18HQvHL)~?ra*92o-JZD^s*B!+Yu`h;Pn`SRSiTl5L zfeH^qm|J$e=uT;#Fxa10Y#z*9PY&72*ocNh`z9uW`p zJ*o0R1GI()vyPd+G@Z;h5l<4!NH$v?Xfmx2UU!rZV$*wS2MTmmc4p$}>CNC+s(Ka_ z)v_E4gX+SFohMAe-U}OMz9tQ2AA?($u*v$jLql!COLWSb9vj?l%nlMa=Z}! zQH^qLTXt)tva&L1i}NYJAX?Ye?P7w}Lyj{rrRVsBPF3|Q=5RQDH8Y+S7@m@c49Heu zcf$+33m98Yq5QqkK{R(f!czcP;f6M$8k)os!5&ndwp0 zn#q+RAn(jonjTut$*(iW&j^QovT8{`I?uW1ClyyT8r$X&G zwPyCJR^pARU*=m-po5y+nQK{&o*oZ)b@!`fBtPci)1k*(OyDEkIRi-w?X~R0AupqX zJB;JUNGagMd#CjL$w}CF9!pO}5ny2Hf0&S@$RkaBr@yGB1-st%{A?-ciN)hGtDX?+ zKu3QUInG&$-PG5goazKhlT?pUTS!k=imhYo-8*r6WrVnLPKuu#iRG?X#Zw_peJ_-@ zt49v!khG;GZzbw*djY<~5g@*3>QjaHbbqNeDSh?p8*{`%bD7eqSH1@G{@cDjYfYoP zDr?+G1DDF}2FvX%eQRz#Ma~Op70LS5!}|lZq7ds@$~SNugYr~7yw&rGE$#9_>O<43 z@xu`*IP*)C3Z2dVQyQ}AZ@AT6b|zh?bm_BKvYwvvIzYdEKJALwX`A4dy z&{oyxuCr>gLA1J^<5XXR$<^Zc@w&RS^qe8-d`e30+c-JszAOZ01OggHHom$4F*g`N z2=MNpL>#gek)YJFwOuj-bskkWRdlmW9BzwcO^|F+@OVo_QzS6B|alI!?uUZCXp9yM3to`hTI#eAH z9TfV`Vm|T+m>>+2w*;rFDVy|^O*wd z4}o<{P1M-N>W6#bmp41!XPBgwrXZouoK@kR@9fu(u^HM*y+rx*`vqCT%#?TaZvE%% z@9HojH!E}C>3)n?{ilOgAoyxK{{;@CQ^&s7!byRYzS5|u(0OPmelgT}YqsCmDNTj$ zMYB=E`);g>>TE0;fE{8B$*nR>XBeTif@a@q^;9A0 zqhbA}@rg(1^mV(@G)RxH4d2kJb?ohfADUBPNZiC|<8?3JW5>r-ucB4-z52{8`l>n? z2LnL{#rmzHC-2@G)$ye{VXJeOG2(p z)=dV*iih|*S3SJw(}Tm9sOHxA5{4K6{VEU?=0JUqw03eD9v;a*gs5=tDsnXL0#wK^ zPo9cMx@JJw<;5UjB5RE&PMI`A-Xr*jc04pkbGt<07)t*}$qoG#3x|P?pjdL1J6n;b zxiEOy-SI)yRvs^4W)4Rk4iYCU2G6&lq*4YL8*g;^Ahpr%7vgWyWn&Q}T~+2+kIcL2 zBe0Q#ussnEx$6r65us;DNKt;i%pc+lT9@HnHQVZPa^*p>lR(B!lijs3KuGEbbG_bn zNp)suj;-|}>Nz9Sbt|rtj*x?Fl8{Jc$uapDf-%jEA7kfnKac-Utd)bUf6r3`$v!8f zqV|f|LY#0sfsd0Lcht|TW&vLu`oalh(;M`5s3G$+1ReU=ZJSHtpREFO&@g*kc=-LT z8=G-2x-Bf~hQ3rR%1U`{ZH8=%@*Hm6dLEmh%7^1XnTuaN=BpMH=wRb^!VV4_Na?5J z#PR6KE_W>-cR$Vr$hIhHE{%M;F-w|n0ZZ=Hjcoi01pB8*8Y44+-~La*Je3Dbk;glh i_#@hEFCS403aA`>BSHW@c?5JOV0iQH4fOTLFa86{C;Nv0 literal 0 HcmV?d00001 diff --git a/docs/validation/pr-28/hashes.json b/docs/validation/pr-28/hashes.json index e96d7406..886d2af6 100644 --- a/docs/validation/pr-28/hashes.json +++ b/docs/validation/pr-28/hashes.json @@ -12,5 +12,16 @@ "controlUiIndex": "73ac0e6f38896c9d491b45a6c3d23b4990dae139d8ff3cb93da7a33e640bb1e7", "controlUiEntry": "1430574e4d89d8c43b303057d918fdba41a4a940d436d7feaf8e0122a533e4f6", "screenshot": "1dd7153742614febf8d00aa08c50f3c3465cdd8a7a3b4cf87e8fa585177a0142" + }, + "evidenceFiles": { + "fixture-disabled.png": "9445d0a982b921b77113fa3889278c129b31ba2de50ea591caf2e5af40cd13b4", + "fixture-empty.png": "5b64cdc293b6fa1e6be4d04d5c37c7d0403293e9e8aaaf1576c3b55dcfc2a940", + "fixture-enabled.png": "6912ea4e768ae4a2f8fceff4a64c4f371eb44184b99b061ec6a9fe5599aa4fea", + "fixture-invalid.png": "5b64cdc293b6fa1e6be4d04d5c37c7d0403293e9e8aaaf1576c3b55dcfc2a940", + "fixture-missing.png": "5b64cdc293b6fa1e6be4d04d5c37c7d0403293e9e8aaaf1576c3b55dcfc2a940", + "fixture-uppercase.png": "5b64cdc293b6fa1e6be4d04d5c37c7d0403293e9e8aaaf1576c3b55dcfc2a940", + "fixture-whitespace.png": "5b64cdc293b6fa1e6be4d04d5c37c7d0403293e9e8aaaf1576c3b55dcfc2a940", + "gateway-isolation-e2e.png": "1dd7153742614febf8d00aa08c50f3c3465cdd8a7a3b4cf87e8fa585177a0142", + "launcher-disabled.png": "9445d0a982b921b77113fa3889278c129b31ba2de50ea591caf2e5af40cd13b4" } } diff --git a/docs/validation/pr-28/launcher-disabled.png b/docs/validation/pr-28/launcher-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..e3be96a07d9bab4293ef4d378cc98e101de84d44 GIT binary patch literal 41835 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≶6q`BwXQ%68lG*A*A?_B<5^2z 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 literal 0 HcmV?d00001 diff --git a/docs/validation/pr-28/launcher-tests.json b/docs/validation/pr-28/launcher-tests.json new file mode 100644 index 00000000..de169c25 --- /dev/null +++ b/docs/validation/pr-28/launcher-tests.json @@ -0,0 +1,234 @@ +{ + "command": "dotnet test .\\OpenClaw.Gateway.MSIX.slnx --configuration Release --no-restore", + "total": 57, + "results": [ + { + "name": "OpenClaw.Launcher.Tests.HostEntrypointResolverTests.OnlyArgvZeroSelectsTheEntrypoint", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ProgramTests.SetupChecksNodeAndPackagedApplicationWithoutMutation", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.HostDiagnosticLogTests.WritePersistsTimestampedProcessDiagnostics", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoRejectsInvalidGatewayIsolationMode(mode: -1)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ProgramTests.AgentResolvesNodeBeforeReportingMissingApplication", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.SupportedVersionsMatchPackagedOpenClawRequirement(major: 25, minor: 8, build: 99, expected: False)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlCommandTests.ParseRejectsCommandsOutsideThePublicManagementSurface(args: [\"doctor\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.WindowsKillOnCloseJobTests.FastExitRetainsExitCodeAfterDelayedObservation", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlCommandTests.ParseAcceptsOnlyThePublicManagementSurface(expected: Help, args: [])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.HostOptionsTests.ParseForwardsAllArgumentsUnchanged", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoPreservesExplicitArguments", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ProgramTests.AgentLaunchResolvesNodeAndRunsPackagedApplication", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.SupportedVersionsMatchPackagedOpenClawRequirement(major: 23, minor: 99, build: 0, expected: False)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.HostOptionsTests.ParseReportsMissingPackagedApplication", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoForwardsCommandsWithoutInterpretation(arguments: [\"--update\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlCommandTests.ParseAcceptsOnlyThePublicManagementSurface(expected: Setup, args: [\"setup\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlConsoleTests.WriteReadinessSummaryDescribesPackagedApplication", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoForwardsCommandsWithoutInterpretation(arguments: [\"update\", \"--yes\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.SupportedVersionsMatchPackagedOpenClawRequirement(major: 26, minor: 0, build: 0, expected: True)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoForwardsNoArgumentsUnchanged", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlCommandTests.ParseRejectsCommandsOutsideThePublicManagementSurface(args: [\"verify\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.SupportedVersionsMatchPackagedOpenClawRequirement(major: 24, minor: 14, build: 99, expected: False)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlCommandTests.ParseAcceptsOnlyThePublicManagementSurface(expected: Version, args: [\"--version\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoForwardsCommandsWithoutInterpretation(arguments: [\"onboard\", \"--mode\", \"local\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoRejectsInvalidGatewayIsolationMode(mode: 2147483647)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.HostEntrypointResolverTests.UnknownOrMalformedInvocationDefaultsToAgent", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoForwardsCommandsWithoutInterpretation(arguments: [\"setup\", \"--install-daemon\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlCommandTests.ParseRejectsCommandsOutsideThePublicManagementSurface(args: [\"gateway\", \"status\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.ResolveAcceptsCompatibleRuntime", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.ResolveRejectsPrereleaseVersion", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlCommandTests.ParseRejectsCommandsOutsideThePublicManagementSurface(args: [\"update-package\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoDefaultsToCurrentWorkingDirectory", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ProgramTests.SetupResolvesNodeBeforeReportingMissingApplication", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoRejectsInvalidGatewayIsolationMode(mode: 2)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlCommandTests.ParseRejectsCommandsOutsideThePublicManagementSurface(args: [\"setup\", \"--force\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.ResolveRejectsIncompatibleArchitecture", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.WindowsKillOnCloseJobTests.DisposingJobTerminatesAssignedProcess", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.ResolveRejectsMalformedVersion", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlConsoleTests.WriteHelpListsOnlyThePublicCommands", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlCommandTests.ParseRejectsCommandsOutsideThePublicManagementSurface(args: [\"prepare\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.ResolveReportsVersionQueryFailure", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.HostOptionsTests.ParseResolvesPackagedApplicationWhenEntryPointExists", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.PackageManifestTests.ManifestRegistersBothAliasesToTheSingleExecutable", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoReportsExactGatewayIsolationMode(mode: Disabled, expected: \"disabled\")", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.HostEntrypointResolverTests.AgentAliasSelectsThePassthroughEntrypoint", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.SupportedVersionsMatchPackagedOpenClawRequirement(major: 22, minor: 22, build: 2, expected: False)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.ClawCtlCommandTests.ParseRejectsCommandsOutsideThePublicManagementSurface(args: [\"repair\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.SupportedVersionsMatchPackagedOpenClawRequirement(major: 25, minor: 9, build: 0, expected: True)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.ResolveRejectsOutdatedRuntime", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.SupportedVersionsMatchPackagedOpenClawRequirement(major: 24, minor: 15, build: 0, expected: True)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoForwardsCommandsWithoutInterpretation(arguments: [\"gateway\", \"call\", \"update.run\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.ResolveReportsInstallCommandWhenRuntimeIsMissing", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoForwardsCommandsWithoutInterpretation(arguments: [\"gateway\", \"install\"])", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.NodeRuntimeResolverTests.SupportedVersionsMatchPackagedOpenClawRequirement(major: 22, minor: 22, build: 3, expected: True)", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.HostDiagnosticLogTests.ConcurrentInvocationsSerializeCompleteLogRecords", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.HostEntrypointResolverTests.ControlAliasSelectsTheManagementEntrypoint", + "outcome": "Passed" + }, + { + "name": "OpenClaw.Launcher.Tests.GatewayLauncherTests.CreateStartInfoReportsExactGatewayIsolationMode(mode: Enabled, expected: \"enabled\")", + "outcome": "Passed" + } + ] +} diff --git a/docs/validation/pr-28/payload-matrix.json b/docs/validation/pr-28/payload-matrix.json new file mode 100644 index 00000000..7f14d09c --- /dev/null +++ b/docs/validation/pr-28/payload-matrix.json @@ -0,0 +1,3656 @@ +{ + "schemaVersion": 1, + "fixtureType": "synthetic-local-npm-packages-and-synthetic-runtime-inspection-responses", + "scope": "Actual Build-Payload.ps1 x64 and ARM64 composition contract with controlled runtime-inspection fixtures.", + "productionSourceCommit": "9aa1df286c2b6fd59b4c101201ddae0ae6000324", + "evidenceCheckoutHead": "2ce86d5bf4b54809ab1b4dcf5930db74d36b6d84", + "verifiedSourceFiles": [ + { + "path": "scripts/Build-Payload.ps1", + "sha256": "7dbdc5b23b0b325a8338de26c8e00cb9b7c4475404c78090884c93ba7ae60691" + }, + { + "path": "plugins/gateway-isolation/package.json", + "sha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142" + }, + { + "path": "plugins/gateway-isolation/openclaw.plugin.json", + "sha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651" + }, + { + "path": "plugins/gateway-isolation/index.js", + "sha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd" + } + ], + "harness": "scripts/validation/Test-GatewayIsolationPayloadMatrix.ps1", + "harnessSha256": "a538e627a1eda0737557e052a68b44d5e591c1923fb4223b7eb52084481f86d9", + "environment": { + "powershell": "7.6.6", + "node": "v24.16.0", + "npm": "11.13.0", + "host": "Windows x64", + "npmOffline": true + }, + "command": "pwsh -NoProfile -File .\\scripts\\validation\\Test-GatewayIsolationPayloadMatrix.ps1", + "summary": { + "total": 66, + "passed": 66, + "failed": 0, + "accepted": 6, + "rejected": 60, + "architectures": [ + "x64", + "arm64" + ] + }, + "harnessEnvironmentRestored": true, + "harnessWorkingDirectoryRestored": true, + "generatedFixtureDirectoryRemoved": true, + "cases": [ + { + "id": "x64-accepted-existing-environment", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "accepted", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "accepted", + "actual": "accepted", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-accepted-existing-environment\\package -Architecture x64 -OutputDirectory \\x64-accepted-existing-environment\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + }, + { + "command": "version-smoke", + "args": [ + "--version" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "matrix-original-CLAWCTL_GATEWAY_ISOLATION", + "stateDirectoryMatchesExpected": false + } + ], + "content": { + "shippingFileCount": 3, + "files": [ + { + "file": "index.js", + "sourceSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "payloadSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "identical": true + }, + { + "file": "openclaw.plugin.json", + "sourceSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "payloadSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "identical": true + }, + { + "file": "package.json", + "sourceSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "payloadSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "identical": true + } + ], + "noTestFile": true, + "metadataArchitecture": "x64", + "metadataLayout": "expanded-directory", + "metadataNodeVersion": "v24.16.0", + "metadataNpmVersion": "11.13.0" + }, + "rejectedOutputAbsent": false + }, + { + "id": "x64-accepted-absent-environment", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "accepted", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "accepted", + "actual": "accepted", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-accepted-absent-environment\\package -Architecture x64 -OutputDirectory \\x64-accepted-absent-environment\\payload", + "environmentBefore": "absent", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + }, + { + "command": "version-smoke", + "args": [ + "--version" + ], + "nodeVersion": "v24.16.0", + "isolationMode": null, + "stateDirectoryMatchesExpected": false + } + ], + "content": { + "shippingFileCount": 3, + "files": [ + { + "file": "index.js", + "sourceSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "payloadSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "identical": true + }, + { + "file": "openclaw.plugin.json", + "sourceSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "payloadSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "identical": true + }, + { + "file": "package.json", + "sourceSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "payloadSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "identical": true + } + ], + "noTestFile": true, + "metadataArchitecture": "x64", + "metadataLayout": "expanded-directory", + "metadataNodeVersion": "v24.16.0", + "metadataNpmVersion": "11.13.0" + }, + "rejectedOutputAbsent": false + }, + { + "id": "x64-accepted-empty-environment", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "accepted", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "accepted", + "actual": "accepted", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-accepted-empty-environment\\package -Architecture x64 -OutputDirectory \\x64-accepted-empty-environment\\payload", + "environmentBefore": "empty", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + }, + { + "command": "version-smoke", + "args": [ + "--version" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "", + "stateDirectoryMatchesExpected": false + } + ], + "content": { + "shippingFileCount": 3, + "files": [ + { + "file": "index.js", + "sourceSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "payloadSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "identical": true + }, + { + "file": "openclaw.plugin.json", + "sourceSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "payloadSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "identical": true + }, + { + "file": "package.json", + "sourceSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "payloadSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "identical": true + } + ], + "noTestFile": true, + "metadataArchitecture": "x64", + "metadataLayout": "expanded-directory", + "metadataNodeVersion": "v24.16.0", + "metadataNpmVersion": "11.13.0" + }, + "rejectedOutputAbsent": false + }, + { + "id": "x64-missing-extensions", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing-extensions", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The pinned OpenClaw payload does not expose the supported bundled plugin directory: \\x64-missing-extensions\\runner\\openclaw-stage-x64\\node_modules\\openclaw\\dist\\extensions", + "actual": "The pinned OpenClaw payload does not expose the supported bundled plugin directory: \\x64-missing-extensions\\runner\\openclaw-stage-x64\\node_modules\\openclaw\\dist\\extensions", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-extensions\\package -Architecture x64 -OutputDirectory \\x64-missing-extensions\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-preexisting-plugin", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "preexisting-plugin", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The OpenClaw payload already contains a gateway-isolation plugin; refusing to replace upstream content.", + "actual": "The OpenClaw payload already contains a gateway-isolation plugin; refusing to replace upstream content.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-preexisting-plugin\\package -Architecture x64 -OutputDirectory \\x64-preexisting-plugin\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-inspection-exit-23", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "exit", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload cannot load the Gateway isolation plugin. Exit code: 23.", + "actual": "The selected OpenClaw payload cannot load the Gateway isolation plugin. Exit code: 23.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-inspection-exit-23\\package -Architecture x64 -OutputDirectory \\x64-inspection-exit-23\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-plugin-id", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.id", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "unexpected-plugin", + "imported": true, + "status": "loaded", + "httpRoutes": 1, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-plugin-id\\package -Architecture x64 -OutputDirectory \\x64-wrong-plugin-id\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-plugin-id", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.id", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-plugin-id\\package -Architecture x64 -OutputDirectory \\x64-missing-plugin-id\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-plugin-origin", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.origin", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "gateway-isolation", + "imported": true, + "status": "loaded", + "httpRoutes": 1, + "origin": "global" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-plugin-origin\\package -Architecture x64 -OutputDirectory \\x64-wrong-plugin-origin\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-plugin-origin", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.origin", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-plugin-origin\\package -Architecture x64 -OutputDirectory \\x64-missing-plugin-origin\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-plugin-enabled", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.enabled", + "fixtureInspection": { + "plugin": { + "enabled": false, + "activated": true, + "id": "gateway-isolation", + "imported": true, + "status": "loaded", + "httpRoutes": 1, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-plugin-enabled\\package -Architecture x64 -OutputDirectory \\x64-wrong-plugin-enabled\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-plugin-enabled", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.enabled", + "fixtureInspection": { + "plugin": { + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-plugin-enabled\\package -Architecture x64 -OutputDirectory \\x64-missing-plugin-enabled\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-plugin-activated", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.activated", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": false, + "id": "gateway-isolation", + "imported": true, + "status": "loaded", + "httpRoutes": 1, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-plugin-activated\\package -Architecture x64 -OutputDirectory \\x64-wrong-plugin-activated\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-plugin-activated", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.activated", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1 + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-plugin-activated\\package -Architecture x64 -OutputDirectory \\x64-missing-plugin-activated\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-plugin-status", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.status", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "gateway-isolation", + "imported": true, + "status": "error", + "httpRoutes": 1, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-plugin-status\\package -Architecture x64 -OutputDirectory \\x64-wrong-plugin-status\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-plugin-status", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.status", + "fixtureInspection": { + "plugin": { + "enabled": true, + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-plugin-status\\package -Architecture x64 -OutputDirectory \\x64-missing-plugin-status\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-plugin-imported", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.imported", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "gateway-isolation", + "imported": false, + "status": "loaded", + "httpRoutes": 1, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-plugin-imported\\package -Architecture x64 -OutputDirectory \\x64-wrong-plugin-imported\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-plugin-imported", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.imported", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-plugin-imported\\package -Architecture x64 -OutputDirectory \\x64-missing-plugin-imported\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-plugin-httpRoutes", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.httpRoutes", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "gateway-isolation", + "imported": true, + "status": "loaded", + "httpRoutes": 0, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-plugin-httpRoutes\\package -Architecture x64 -OutputDirectory \\x64-wrong-plugin-httpRoutes\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-plugin-httpRoutes", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.httpRoutes", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-plugin-httpRoutes\\package -Architecture x64 -OutputDirectory \\x64-missing-plugin-httpRoutes\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-httpRouteCount", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "httpRouteCount", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 0, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-httpRouteCount\\package -Architecture x64 -OutputDirectory \\x64-wrong-httpRouteCount\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-httpRouteCount", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "httpRouteCount", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-httpRouteCount\\package -Architecture x64 -OutputDirectory \\x64-missing-httpRouteCount\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-gatewayMethods", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "gatewayMethods", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [ + "fixture.method" + ], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-gatewayMethods\\package -Architecture x64 -OutputDirectory \\x64-wrong-gatewayMethods\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-gatewayMethods", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "gatewayMethods", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-gatewayMethods\\package -Architecture x64 -OutputDirectory \\x64-missing-gatewayMethods\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-tools", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "tools", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [ + "fixture.tool" + ], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-tools\\package -Architecture x64 -OutputDirectory \\x64-wrong-tools\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-tools", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "tools", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-tools\\package -Architecture x64 -OutputDirectory \\x64-missing-tools\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-services", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "services", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [ + "fixture.service" + ], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-services\\package -Architecture x64 -OutputDirectory \\x64-wrong-services\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-services", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "services", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-services\\package -Architecture x64 -OutputDirectory \\x64-missing-services\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-wrong-diagnostics", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "diagnostics", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [ + "fixture diagnostic" + ] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-wrong-diagnostics\\package -Architecture x64 -OutputDirectory \\x64-wrong-diagnostics\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-diagnostics", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "diagnostics", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-diagnostics\\package -Architecture x64 -OutputDirectory \\x64-missing-diagnostics\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-excess-plugin-httpRoutes", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.httpRoutes", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "gateway-isolation", + "imported": true, + "status": "loaded", + "httpRoutes": 2, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-excess-plugin-httpRoutes\\package -Architecture x64 -OutputDirectory \\x64-excess-plugin-httpRoutes\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-excess-httpRouteCount", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "httpRouteCount", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 2, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-excess-httpRouteCount\\package -Architecture x64 -OutputDirectory \\x64-excess-httpRouteCount\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "x64-missing-plugin-object", + "architecture": "x64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin", + "fixtureInspection": { + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\x64-missing-plugin-object\\package -Architecture x64 -OutputDirectory \\x64-missing-plugin-object\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-accepted-existing-environment", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "accepted", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "accepted", + "actual": "accepted", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-accepted-existing-environment\\package -Architecture arm64 -OutputDirectory \\arm64-accepted-existing-environment\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": { + "shippingFileCount": 3, + "files": [ + { + "file": "index.js", + "sourceSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "payloadSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "identical": true + }, + { + "file": "openclaw.plugin.json", + "sourceSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "payloadSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "identical": true + }, + { + "file": "package.json", + "sourceSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "payloadSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "identical": true + } + ], + "noTestFile": true, + "metadataArchitecture": "arm64", + "metadataLayout": "expanded-directory", + "metadataNodeVersion": "v24.16.0", + "metadataNpmVersion": "11.13.0" + }, + "rejectedOutputAbsent": false + }, + { + "id": "arm64-accepted-absent-environment", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "accepted", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "accepted", + "actual": "accepted", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-accepted-absent-environment\\package -Architecture arm64 -OutputDirectory \\arm64-accepted-absent-environment\\payload", + "environmentBefore": "absent", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": { + "shippingFileCount": 3, + "files": [ + { + "file": "index.js", + "sourceSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "payloadSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "identical": true + }, + { + "file": "openclaw.plugin.json", + "sourceSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "payloadSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "identical": true + }, + { + "file": "package.json", + "sourceSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "payloadSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "identical": true + } + ], + "noTestFile": true, + "metadataArchitecture": "arm64", + "metadataLayout": "expanded-directory", + "metadataNodeVersion": "v24.16.0", + "metadataNpmVersion": "11.13.0" + }, + "rejectedOutputAbsent": false + }, + { + "id": "arm64-accepted-empty-environment", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "accepted", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "accepted", + "actual": "accepted", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-accepted-empty-environment\\package -Architecture arm64 -OutputDirectory \\arm64-accepted-empty-environment\\payload", + "environmentBefore": "empty", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": { + "shippingFileCount": 3, + "files": [ + { + "file": "index.js", + "sourceSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "payloadSha256": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd", + "identical": true + }, + { + "file": "openclaw.plugin.json", + "sourceSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "payloadSha256": "a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651", + "identical": true + }, + { + "file": "package.json", + "sourceSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "payloadSha256": "5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142", + "identical": true + } + ], + "noTestFile": true, + "metadataArchitecture": "arm64", + "metadataLayout": "expanded-directory", + "metadataNodeVersion": "v24.16.0", + "metadataNpmVersion": "11.13.0" + }, + "rejectedOutputAbsent": false + }, + { + "id": "arm64-missing-extensions", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing-extensions", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The pinned OpenClaw payload does not expose the supported bundled plugin directory: \\arm64-missing-extensions\\runner\\openclaw-stage-arm64\\node_modules\\openclaw\\dist\\extensions", + "actual": "The pinned OpenClaw payload does not expose the supported bundled plugin directory: \\arm64-missing-extensions\\runner\\openclaw-stage-arm64\\node_modules\\openclaw\\dist\\extensions", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-extensions\\package -Architecture arm64 -OutputDirectory \\arm64-missing-extensions\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-preexisting-plugin", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "preexisting-plugin", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The OpenClaw payload already contains a gateway-isolation plugin; refusing to replace upstream content.", + "actual": "The OpenClaw payload already contains a gateway-isolation plugin; refusing to replace upstream content.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-preexisting-plugin\\package -Architecture arm64 -OutputDirectory \\arm64-preexisting-plugin\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-inspection-exit-23", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "exit", + "field": null, + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload cannot load the Gateway isolation plugin. Exit code: 23.", + "actual": "The selected OpenClaw payload cannot load the Gateway isolation plugin. Exit code: 23.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-inspection-exit-23\\package -Architecture arm64 -OutputDirectory \\arm64-inspection-exit-23\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-plugin-id", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.id", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "unexpected-plugin", + "imported": true, + "status": "loaded", + "httpRoutes": 1, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-plugin-id\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-plugin-id\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-plugin-id", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.id", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-plugin-id\\package -Architecture arm64 -OutputDirectory \\arm64-missing-plugin-id\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-plugin-origin", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.origin", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "gateway-isolation", + "imported": true, + "status": "loaded", + "httpRoutes": 1, + "origin": "global" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-plugin-origin\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-plugin-origin\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-plugin-origin", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.origin", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-plugin-origin\\package -Architecture arm64 -OutputDirectory \\arm64-missing-plugin-origin\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-plugin-enabled", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.enabled", + "fixtureInspection": { + "plugin": { + "enabled": false, + "activated": true, + "id": "gateway-isolation", + "imported": true, + "status": "loaded", + "httpRoutes": 1, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-plugin-enabled\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-plugin-enabled\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-plugin-enabled", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.enabled", + "fixtureInspection": { + "plugin": { + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-plugin-enabled\\package -Architecture arm64 -OutputDirectory \\arm64-missing-plugin-enabled\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-plugin-activated", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.activated", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": false, + "id": "gateway-isolation", + "imported": true, + "status": "loaded", + "httpRoutes": 1, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-plugin-activated\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-plugin-activated\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-plugin-activated", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.activated", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1 + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-plugin-activated\\package -Architecture arm64 -OutputDirectory \\arm64-missing-plugin-activated\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-plugin-status", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.status", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "gateway-isolation", + "imported": true, + "status": "error", + "httpRoutes": 1, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-plugin-status\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-plugin-status\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-plugin-status", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.status", + "fixtureInspection": { + "plugin": { + "enabled": true, + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-plugin-status\\package -Architecture arm64 -OutputDirectory \\arm64-missing-plugin-status\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-plugin-imported", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.imported", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "gateway-isolation", + "imported": false, + "status": "loaded", + "httpRoutes": 1, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-plugin-imported\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-plugin-imported\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-plugin-imported", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.imported", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-plugin-imported\\package -Architecture arm64 -OutputDirectory \\arm64-missing-plugin-imported\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-plugin-httpRoutes", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.httpRoutes", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "gateway-isolation", + "imported": true, + "status": "loaded", + "httpRoutes": 0, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-plugin-httpRoutes\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-plugin-httpRoutes\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-plugin-httpRoutes", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin.httpRoutes", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-plugin-httpRoutes\\package -Architecture arm64 -OutputDirectory \\arm64-missing-plugin-httpRoutes\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-httpRouteCount", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "httpRouteCount", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 0, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-httpRouteCount\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-httpRouteCount\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-httpRouteCount", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "httpRouteCount", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-httpRouteCount\\package -Architecture arm64 -OutputDirectory \\arm64-missing-httpRouteCount\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-gatewayMethods", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "gatewayMethods", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [ + "fixture.method" + ], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-gatewayMethods\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-gatewayMethods\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-gatewayMethods", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "gatewayMethods", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-gatewayMethods\\package -Architecture arm64 -OutputDirectory \\arm64-missing-gatewayMethods\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-tools", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "tools", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [ + "fixture.tool" + ], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-tools\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-tools\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-tools", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "tools", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-tools\\package -Architecture arm64 -OutputDirectory \\arm64-missing-tools\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-services", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "services", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [ + "fixture.service" + ], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-services\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-services\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-services", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "services", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-services\\package -Architecture arm64 -OutputDirectory \\arm64-missing-services\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-wrong-diagnostics", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "diagnostics", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [ + "fixture diagnostic" + ] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-wrong-diagnostics\\package -Architecture arm64 -OutputDirectory \\arm64-wrong-diagnostics\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-diagnostics", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "diagnostics", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-diagnostics\\package -Architecture arm64 -OutputDirectory \\arm64-missing-diagnostics\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-excess-plugin-httpRoutes", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "plugin.httpRoutes", + "fixtureInspection": { + "plugin": { + "enabled": true, + "activated": true, + "id": "gateway-isolation", + "imported": true, + "status": "loaded", + "httpRoutes": 2, + "origin": "bundled" + }, + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-excess-plugin-httpRoutes\\package -Architecture arm64 -OutputDirectory \\arm64-excess-plugin-httpRoutes\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-excess-httpRouteCount", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "wrong", + "field": "httpRouteCount", + "fixtureInspection": { + "plugin": { + "enabled": true, + "status": "loaded", + "imported": true, + "origin": "bundled", + "id": "gateway-isolation", + "httpRoutes": 1, + "activated": true + }, + "httpRouteCount": 2, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-excess-httpRouteCount\\package -Architecture arm64 -OutputDirectory \\arm64-excess-httpRouteCount\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + }, + { + "id": "arm64-missing-plugin-object", + "architecture": "arm64", + "outcome": "PASS", + "fixtureType": "synthetic-local-npm-package-and-runtime-inspection", + "mutation": "missing", + "field": "plugin", + "fixtureInspection": { + "httpRouteCount": 1, + "gatewayMethods": [], + "tools": [], + "services": [], + "diagnostics": [] + }, + "expected": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "actual": "The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape.", + "command": "& .\\scripts\\Build-Payload.ps1 -PackageDirectory \\arm64-missing-plugin-object\\package -Architecture arm64 -OutputDirectory \\arm64-missing-plugin-object\\payload", + "environmentBefore": "existing sentinels", + "environmentRestored": { + "npm_config_arch": true, + "npm_config_target_arch": true, + "OPENCLAW_STATE_DIR": true, + "CLAWCTL_GATEWAY_ISOLATION": true, + "RUNNER_TEMP": true + }, + "workingDirectoryRestored": true, + "runtimeObservations": [ + { + "command": "runtime-inspection", + "args": [ + "plugins", + "inspect", + "gateway-isolation", + "--runtime", + "--json" + ], + "nodeVersion": "v24.16.0", + "isolationMode": "disabled", + "stateDirectoryMatchesExpected": true + } + ], + "content": null, + "rejectedOutputAbsent": true + } + ] +} diff --git a/docs/validation/pr-28/payload-matrix.txt b/docs/validation/pr-28/payload-matrix.txt new file mode 100644 index 00000000..12a960ca --- /dev/null +++ b/docs/validation/pr-28/payload-matrix.txt @@ -0,0 +1,625 @@ +Gateway isolation payload composition matrix +Fixture type: synthetic local npm packages and synthetic runtime-inspection responses. +Real operations: npm pack, npm install, scripts\Build-Payload.ps1, file copy, runtime command invocation, payload metadata. +This matrix tests the x64 and ARM64 composition contract with controlled runtime-inspection fixtures. +Production source: 9aa1df286c2b6fd59b4c101201ddae0ae6000324 +Evidence checkout HEAD: 2ce86d5bf4b54809ab1b4dcf5930db74d36b6d84 +Runtime: pwsh 7.6.6; Node.js v24.16.0; npm 11.13.0; Windows x64 host +Command: $env:PATH = ";" + $env:PATH +Command: pwsh -NoProfile -File .\scripts\validation\Test-GatewayIsolationPayloadMatrix.ps1 +All npm operations use an isolated generated cache and npm_config_offline=true; packages have no dependencies or lifecycle scripts. + +CASE x64-accepted-existing-environment PASS +Command (from \x64-accepted-existing-environment\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-accepted-existing-environment\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-accepted-existing-environment\package -Architecture x64 -OutputDirectory \x64-accepted-existing-environment\payload +Expected: accepted +Actual: accepted +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection, version-smoke +Shipping plugin files: 3; all source/payload SHA-256 hashes identical; index.test.js absent; metadata architecture: x64 +SHA256 index.js 7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd +SHA256 openclaw.plugin.json a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651 +SHA256 package.json 5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142 + +CASE x64-accepted-absent-environment PASS +Command (from \x64-accepted-absent-environment\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-accepted-absent-environment\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-accepted-absent-environment\package -Architecture x64 -OutputDirectory \x64-accepted-absent-environment\payload +Expected: accepted +Actual: accepted +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection, version-smoke +Shipping plugin files: 3; all source/payload SHA-256 hashes identical; index.test.js absent; metadata architecture: x64 +SHA256 index.js 7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd +SHA256 openclaw.plugin.json a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651 +SHA256 package.json 5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142 + +CASE x64-accepted-empty-environment PASS +Command (from \x64-accepted-empty-environment\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-accepted-empty-environment\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-accepted-empty-environment\package -Architecture x64 -OutputDirectory \x64-accepted-empty-environment\payload +Expected: accepted +Actual: accepted +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection, version-smoke +Shipping plugin files: 3; all source/payload SHA-256 hashes identical; index.test.js absent; metadata architecture: x64 +SHA256 index.js 7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd +SHA256 openclaw.plugin.json a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651 +SHA256 package.json 5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142 + +CASE x64-missing-extensions PASS +Command (from \x64-missing-extensions\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-extensions\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-extensions\package -Architecture x64 -OutputDirectory \x64-missing-extensions\payload +Expected: The pinned OpenClaw payload does not expose the supported bundled plugin directory: \x64-missing-extensions\runner\openclaw-stage-x64\node_modules\openclaw\dist\extensions +Actual: The pinned OpenClaw payload does not expose the supported bundled plugin directory: \x64-missing-extensions\runner\openclaw-stage-x64\node_modules\openclaw\dist\extensions +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: +Rejected application and payload metadata absent. + +CASE x64-preexisting-plugin PASS +Command (from \x64-preexisting-plugin\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-preexisting-plugin\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-preexisting-plugin\package -Architecture x64 -OutputDirectory \x64-preexisting-plugin\payload +Expected: The OpenClaw payload already contains a gateway-isolation plugin; refusing to replace upstream content. +Actual: The OpenClaw payload already contains a gateway-isolation plugin; refusing to replace upstream content. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: +Rejected application and payload metadata absent. + +CASE x64-inspection-exit-23 PASS +Command (from \x64-inspection-exit-23\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-inspection-exit-23\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-inspection-exit-23\package -Architecture x64 -OutputDirectory \x64-inspection-exit-23\payload +Expected: The selected OpenClaw payload cannot load the Gateway isolation plugin. Exit code: 23. +Actual: The selected OpenClaw payload cannot load the Gateway isolation plugin. Exit code: 23. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-plugin-id PASS +Command (from \x64-wrong-plugin-id\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-plugin-id\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-plugin-id\package -Architecture x64 -OutputDirectory \x64-wrong-plugin-id\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-plugin-id PASS +Command (from \x64-missing-plugin-id\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-plugin-id\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-plugin-id\package -Architecture x64 -OutputDirectory \x64-missing-plugin-id\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-plugin-origin PASS +Command (from \x64-wrong-plugin-origin\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-plugin-origin\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-plugin-origin\package -Architecture x64 -OutputDirectory \x64-wrong-plugin-origin\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-plugin-origin PASS +Command (from \x64-missing-plugin-origin\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-plugin-origin\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-plugin-origin\package -Architecture x64 -OutputDirectory \x64-missing-plugin-origin\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-plugin-enabled PASS +Command (from \x64-wrong-plugin-enabled\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-plugin-enabled\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-plugin-enabled\package -Architecture x64 -OutputDirectory \x64-wrong-plugin-enabled\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-plugin-enabled PASS +Command (from \x64-missing-plugin-enabled\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-plugin-enabled\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-plugin-enabled\package -Architecture x64 -OutputDirectory \x64-missing-plugin-enabled\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-plugin-activated PASS +Command (from \x64-wrong-plugin-activated\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-plugin-activated\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-plugin-activated\package -Architecture x64 -OutputDirectory \x64-wrong-plugin-activated\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-plugin-activated PASS +Command (from \x64-missing-plugin-activated\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-plugin-activated\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-plugin-activated\package -Architecture x64 -OutputDirectory \x64-missing-plugin-activated\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-plugin-status PASS +Command (from \x64-wrong-plugin-status\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-plugin-status\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-plugin-status\package -Architecture x64 -OutputDirectory \x64-wrong-plugin-status\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-plugin-status PASS +Command (from \x64-missing-plugin-status\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-plugin-status\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-plugin-status\package -Architecture x64 -OutputDirectory \x64-missing-plugin-status\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-plugin-imported PASS +Command (from \x64-wrong-plugin-imported\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-plugin-imported\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-plugin-imported\package -Architecture x64 -OutputDirectory \x64-wrong-plugin-imported\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-plugin-imported PASS +Command (from \x64-missing-plugin-imported\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-plugin-imported\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-plugin-imported\package -Architecture x64 -OutputDirectory \x64-missing-plugin-imported\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-plugin-httpRoutes PASS +Command (from \x64-wrong-plugin-httpRoutes\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-plugin-httpRoutes\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-plugin-httpRoutes\package -Architecture x64 -OutputDirectory \x64-wrong-plugin-httpRoutes\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-plugin-httpRoutes PASS +Command (from \x64-missing-plugin-httpRoutes\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-plugin-httpRoutes\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-plugin-httpRoutes\package -Architecture x64 -OutputDirectory \x64-missing-plugin-httpRoutes\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-httpRouteCount PASS +Command (from \x64-wrong-httpRouteCount\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-httpRouteCount\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-httpRouteCount\package -Architecture x64 -OutputDirectory \x64-wrong-httpRouteCount\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-httpRouteCount PASS +Command (from \x64-missing-httpRouteCount\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-httpRouteCount\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-httpRouteCount\package -Architecture x64 -OutputDirectory \x64-missing-httpRouteCount\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-gatewayMethods PASS +Command (from \x64-wrong-gatewayMethods\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-gatewayMethods\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-gatewayMethods\package -Architecture x64 -OutputDirectory \x64-wrong-gatewayMethods\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-gatewayMethods PASS +Command (from \x64-missing-gatewayMethods\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-gatewayMethods\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-gatewayMethods\package -Architecture x64 -OutputDirectory \x64-missing-gatewayMethods\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-tools PASS +Command (from \x64-wrong-tools\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-tools\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-tools\package -Architecture x64 -OutputDirectory \x64-wrong-tools\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-tools PASS +Command (from \x64-missing-tools\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-tools\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-tools\package -Architecture x64 -OutputDirectory \x64-missing-tools\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-services PASS +Command (from \x64-wrong-services\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-services\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-services\package -Architecture x64 -OutputDirectory \x64-wrong-services\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-services PASS +Command (from \x64-missing-services\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-services\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-services\package -Architecture x64 -OutputDirectory \x64-missing-services\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-wrong-diagnostics PASS +Command (from \x64-wrong-diagnostics\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-wrong-diagnostics\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-wrong-diagnostics\package -Architecture x64 -OutputDirectory \x64-wrong-diagnostics\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-diagnostics PASS +Command (from \x64-missing-diagnostics\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-diagnostics\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-diagnostics\package -Architecture x64 -OutputDirectory \x64-missing-diagnostics\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-excess-plugin-httpRoutes PASS +Command (from \x64-excess-plugin-httpRoutes\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-excess-plugin-httpRoutes\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-excess-plugin-httpRoutes\package -Architecture x64 -OutputDirectory \x64-excess-plugin-httpRoutes\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-excess-httpRouteCount PASS +Command (from \x64-excess-httpRouteCount\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-excess-httpRouteCount\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-excess-httpRouteCount\package -Architecture x64 -OutputDirectory \x64-excess-httpRouteCount\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE x64-missing-plugin-object PASS +Command (from \x64-missing-plugin-object\package-source): npm pack --offline --ignore-scripts --pack-destination \x64-missing-plugin-object\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \x64-missing-plugin-object\package -Architecture x64 -OutputDirectory \x64-missing-plugin-object\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-accepted-existing-environment PASS +Command (from \arm64-accepted-existing-environment\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-accepted-existing-environment\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-accepted-existing-environment\package -Architecture arm64 -OutputDirectory \arm64-accepted-existing-environment\payload +Expected: accepted +Actual: accepted +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Shipping plugin files: 3; all source/payload SHA-256 hashes identical; index.test.js absent; metadata architecture: arm64 +SHA256 index.js 7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd +SHA256 openclaw.plugin.json a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651 +SHA256 package.json 5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142 + +CASE arm64-accepted-absent-environment PASS +Command (from \arm64-accepted-absent-environment\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-accepted-absent-environment\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-accepted-absent-environment\package -Architecture arm64 -OutputDirectory \arm64-accepted-absent-environment\payload +Expected: accepted +Actual: accepted +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Shipping plugin files: 3; all source/payload SHA-256 hashes identical; index.test.js absent; metadata architecture: arm64 +SHA256 index.js 7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd +SHA256 openclaw.plugin.json a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651 +SHA256 package.json 5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142 + +CASE arm64-accepted-empty-environment PASS +Command (from \arm64-accepted-empty-environment\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-accepted-empty-environment\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-accepted-empty-environment\package -Architecture arm64 -OutputDirectory \arm64-accepted-empty-environment\payload +Expected: accepted +Actual: accepted +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Shipping plugin files: 3; all source/payload SHA-256 hashes identical; index.test.js absent; metadata architecture: arm64 +SHA256 index.js 7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd +SHA256 openclaw.plugin.json a1359e966e39d799f400a7250a4366cd1ef0b0bb8be954100285a2c1da298651 +SHA256 package.json 5a4c1c3966c782455e6505dedc9427c8096917f520ca6486f169fc4db5e50142 + +CASE arm64-missing-extensions PASS +Command (from \arm64-missing-extensions\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-extensions\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-extensions\package -Architecture arm64 -OutputDirectory \arm64-missing-extensions\payload +Expected: The pinned OpenClaw payload does not expose the supported bundled plugin directory: \arm64-missing-extensions\runner\openclaw-stage-arm64\node_modules\openclaw\dist\extensions +Actual: The pinned OpenClaw payload does not expose the supported bundled plugin directory: \arm64-missing-extensions\runner\openclaw-stage-arm64\node_modules\openclaw\dist\extensions +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: +Rejected application and payload metadata absent. + +CASE arm64-preexisting-plugin PASS +Command (from \arm64-preexisting-plugin\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-preexisting-plugin\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-preexisting-plugin\package -Architecture arm64 -OutputDirectory \arm64-preexisting-plugin\payload +Expected: The OpenClaw payload already contains a gateway-isolation plugin; refusing to replace upstream content. +Actual: The OpenClaw payload already contains a gateway-isolation plugin; refusing to replace upstream content. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: +Rejected application and payload metadata absent. + +CASE arm64-inspection-exit-23 PASS +Command (from \arm64-inspection-exit-23\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-inspection-exit-23\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-inspection-exit-23\package -Architecture arm64 -OutputDirectory \arm64-inspection-exit-23\payload +Expected: The selected OpenClaw payload cannot load the Gateway isolation plugin. Exit code: 23. +Actual: The selected OpenClaw payload cannot load the Gateway isolation plugin. Exit code: 23. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-plugin-id PASS +Command (from \arm64-wrong-plugin-id\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-plugin-id\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-plugin-id\package -Architecture arm64 -OutputDirectory \arm64-wrong-plugin-id\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-plugin-id PASS +Command (from \arm64-missing-plugin-id\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-plugin-id\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-plugin-id\package -Architecture arm64 -OutputDirectory \arm64-missing-plugin-id\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-plugin-origin PASS +Command (from \arm64-wrong-plugin-origin\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-plugin-origin\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-plugin-origin\package -Architecture arm64 -OutputDirectory \arm64-wrong-plugin-origin\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-plugin-origin PASS +Command (from \arm64-missing-plugin-origin\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-plugin-origin\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-plugin-origin\package -Architecture arm64 -OutputDirectory \arm64-missing-plugin-origin\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-plugin-enabled PASS +Command (from \arm64-wrong-plugin-enabled\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-plugin-enabled\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-plugin-enabled\package -Architecture arm64 -OutputDirectory \arm64-wrong-plugin-enabled\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-plugin-enabled PASS +Command (from \arm64-missing-plugin-enabled\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-plugin-enabled\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-plugin-enabled\package -Architecture arm64 -OutputDirectory \arm64-missing-plugin-enabled\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-plugin-activated PASS +Command (from \arm64-wrong-plugin-activated\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-plugin-activated\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-plugin-activated\package -Architecture arm64 -OutputDirectory \arm64-wrong-plugin-activated\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-plugin-activated PASS +Command (from \arm64-missing-plugin-activated\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-plugin-activated\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-plugin-activated\package -Architecture arm64 -OutputDirectory \arm64-missing-plugin-activated\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-plugin-status PASS +Command (from \arm64-wrong-plugin-status\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-plugin-status\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-plugin-status\package -Architecture arm64 -OutputDirectory \arm64-wrong-plugin-status\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-plugin-status PASS +Command (from \arm64-missing-plugin-status\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-plugin-status\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-plugin-status\package -Architecture arm64 -OutputDirectory \arm64-missing-plugin-status\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-plugin-imported PASS +Command (from \arm64-wrong-plugin-imported\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-plugin-imported\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-plugin-imported\package -Architecture arm64 -OutputDirectory \arm64-wrong-plugin-imported\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-plugin-imported PASS +Command (from \arm64-missing-plugin-imported\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-plugin-imported\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-plugin-imported\package -Architecture arm64 -OutputDirectory \arm64-missing-plugin-imported\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-plugin-httpRoutes PASS +Command (from \arm64-wrong-plugin-httpRoutes\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-plugin-httpRoutes\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-plugin-httpRoutes\package -Architecture arm64 -OutputDirectory \arm64-wrong-plugin-httpRoutes\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-plugin-httpRoutes PASS +Command (from \arm64-missing-plugin-httpRoutes\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-plugin-httpRoutes\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-plugin-httpRoutes\package -Architecture arm64 -OutputDirectory \arm64-missing-plugin-httpRoutes\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-httpRouteCount PASS +Command (from \arm64-wrong-httpRouteCount\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-httpRouteCount\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-httpRouteCount\package -Architecture arm64 -OutputDirectory \arm64-wrong-httpRouteCount\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-httpRouteCount PASS +Command (from \arm64-missing-httpRouteCount\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-httpRouteCount\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-httpRouteCount\package -Architecture arm64 -OutputDirectory \arm64-missing-httpRouteCount\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-gatewayMethods PASS +Command (from \arm64-wrong-gatewayMethods\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-gatewayMethods\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-gatewayMethods\package -Architecture arm64 -OutputDirectory \arm64-wrong-gatewayMethods\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-gatewayMethods PASS +Command (from \arm64-missing-gatewayMethods\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-gatewayMethods\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-gatewayMethods\package -Architecture arm64 -OutputDirectory \arm64-missing-gatewayMethods\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-tools PASS +Command (from \arm64-wrong-tools\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-tools\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-tools\package -Architecture arm64 -OutputDirectory \arm64-wrong-tools\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-tools PASS +Command (from \arm64-missing-tools\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-tools\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-tools\package -Architecture arm64 -OutputDirectory \arm64-missing-tools\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-services PASS +Command (from \arm64-wrong-services\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-services\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-services\package -Architecture arm64 -OutputDirectory \arm64-wrong-services\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-services PASS +Command (from \arm64-missing-services\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-services\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-services\package -Architecture arm64 -OutputDirectory \arm64-missing-services\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-wrong-diagnostics PASS +Command (from \arm64-wrong-diagnostics\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-wrong-diagnostics\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-wrong-diagnostics\package -Architecture arm64 -OutputDirectory \arm64-wrong-diagnostics\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-diagnostics PASS +Command (from \arm64-missing-diagnostics\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-diagnostics\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-diagnostics\package -Architecture arm64 -OutputDirectory \arm64-missing-diagnostics\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-excess-plugin-httpRoutes PASS +Command (from \arm64-excess-plugin-httpRoutes\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-excess-plugin-httpRoutes\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-excess-plugin-httpRoutes\package -Architecture arm64 -OutputDirectory \arm64-excess-plugin-httpRoutes\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-excess-httpRouteCount PASS +Command (from \arm64-excess-httpRouteCount\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-excess-httpRouteCount\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-excess-httpRouteCount\package -Architecture arm64 -OutputDirectory \arm64-excess-httpRouteCount\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +CASE arm64-missing-plugin-object PASS +Command (from \arm64-missing-plugin-object\package-source): npm pack --offline --ignore-scripts --pack-destination \arm64-missing-plugin-object\package --silent +Command: & .\scripts\Build-Payload.ps1 -PackageDirectory \arm64-missing-plugin-object\package -Architecture arm64 -OutputDirectory \arm64-missing-plugin-object\payload +Expected: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Actual: The selected OpenClaw payload did not load the Gateway isolation plugin with the required read-only runtime shape. +Environment restored: npm_config_arch, npm_config_target_arch, OPENCLAW_STATE_DIR, CLAWCTL_GATEWAY_ISOLATION, RUNNER_TEMP; working directory restored: true +Runtime calls: runtime-inspection +Rejected application and payload metadata absent. + +RESULT: 66 passed; 6 accepted; 60 rejected as expected; 0 failed. +Harness environment and working directory restored. Generated TestRoot removed. No preexisting directories were removed. diff --git a/docs/validation/pr-28/plugin-tests.tap b/docs/validation/pr-28/plugin-tests.tap new file mode 100644 index 00000000..1d0ce224 --- /dev/null +++ b/docs/validation/pr-28/plugin-tests.tap @@ -0,0 +1,136 @@ +TAP version 13 +# Subtest: accepts only the exact launcher isolation values +ok 1 - accepts only the exact launcher isolation values + --- + duration_ms: 1.4354 + type: 'test' + ... +# Subtest: renders the exact enabled read-only status +ok 2 - renders the exact enabled read-only status + --- + duration_ms: 0.4472 + type: 'test' + ... +# Subtest: renders the exact disabled read-only status +ok 3 - renders the exact disabled read-only status + --- + duration_ms: 0.1477 + type: 'test' + ... +# Subtest: registers one read-only Control tab and one authenticated sandbox route +ok 4 - registers one read-only Control tab and one authenticated sandbox route + --- + duration_ms: 1.2608 + type: 'test' + ... +# Subtest: reads "enabled" exactly once and keeps every response stable +ok 5 - reads "enabled" exactly once and keeps every response stable + --- + duration_ms: 0.4925 + type: 'test' + ... +# Subtest: reads "disabled" exactly once and keeps every response stable +ok 6 - reads "disabled" exactly once and keeps every response stable + --- + duration_ms: 0.6573 + type: 'test' + ... +# Subtest: reads missing exactly once and keeps every response stable +ok 7 - reads missing exactly once and keeps every response stable + --- + duration_ms: 0.4355 + type: 'test' + ... +# Subtest: reads "" exactly once and keeps every response stable +ok 8 - reads "" exactly once and keeps every response stable + --- + duration_ms: 0.2525 + type: 'test' + ... +# Subtest: reads "invalid" exactly once and keeps every response stable +ok 9 - reads "invalid" exactly once and keeps every response stable + --- + duration_ms: 0.3347 + type: 'test' + ... +# Subtest: reads "ENABLED" exactly once and keeps every response stable +ok 10 - reads "ENABLED" exactly once and keeps every response stable + --- + duration_ms: 0.3578 + type: 'test' + ... +# Subtest: reads " enabled " exactly once and keeps every response stable +ok 11 - reads " enabled " exactly once and keeps every response stable + --- + duration_ms: 0.2516 + type: 'test' + ... +# Subtest: fails closed for missing with no status, command, or copy control +ok 12 - fails closed for missing with no status, command, or copy control + --- + duration_ms: 1.206 + type: 'test' + ... +# Subtest: renderer rejects missing +ok 13 - renderer rejects missing + --- + duration_ms: 0.7585 + type: 'test' + ... +# Subtest: fails closed for "" with no status, command, or copy control +ok 14 - fails closed for "" with no status, command, or copy control + --- + duration_ms: 0.2382 + type: 'test' + ... +# Subtest: renderer rejects "" +ok 15 - renderer rejects "" + --- + duration_ms: 0.08 + type: 'test' + ... +# Subtest: fails closed for "invalid" with no status, command, or copy control +ok 16 - fails closed for "invalid" with no status, command, or copy control + --- + duration_ms: 0.1374 + type: 'test' + ... +# Subtest: renderer rejects "invalid" +ok 17 - renderer rejects "invalid" + --- + duration_ms: 0.0748 + type: 'test' + ... +# Subtest: fails closed for "ENABLED" with no status, command, or copy control +ok 18 - fails closed for "ENABLED" with no status, command, or copy control + --- + duration_ms: 0.1684 + type: 'test' + ... +# Subtest: renderer rejects "ENABLED" +ok 19 - renderer rejects "ENABLED" + --- + duration_ms: 0.1728 + type: 'test' + ... +# Subtest: fails closed for " enabled " with no status, command, or copy control +ok 20 - fails closed for " enabled " with no status, command, or copy control + --- + duration_ms: 0.0809 + type: 'test' + ... +# Subtest: renderer rejects " enabled " +ok 21 - renderer rejects " enabled " + --- + duration_ms: 0.0741 + type: 'test' + ... +1..21 +# tests 21 +# suites 0 +# pass 21 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 172.9231 diff --git a/docs/validation/pr-28/policy-checks.txt b/docs/validation/pr-28/policy-checks.txt new file mode 100644 index 00000000..7a9a3383 --- /dev/null +++ b/docs/validation/pr-28/policy-checks.txt @@ -0,0 +1,4 @@ +Authorized official signing for OpenClaw commit 0965053fe6b9341776df147a6934b7485c60b5ca and Gateway MSIX version 0.1.1.0. +Authorized official signing for OpenClaw commit 0965053fe6b9341776df147a6934b7485c60b5ca and Gateway MSIX version 0.1.1.0. +Gateway MSIX signing policy tests passed. +Workflow package-version tests passed. diff --git a/docs/validation/pr-28/runtime-checks.txt b/docs/validation/pr-28/runtime-checks.txt new file mode 100644 index 00000000..313b6390 --- /dev/null +++ b/docs/validation/pr-28/runtime-checks.txt @@ -0,0 +1,8 @@ +PASS launcher-disabled: 10 HTTP assertions; GET/HEAD auth denial and valid auth; response hardening headers; write-method probes leave status unchanged; visible sidebar tab; sandboxed iframe; exact status/tone/inverse CLI; Copy writes exact command to clipboard +PASS fixture-enabled: 10 HTTP assertions; GET/HEAD auth denial and valid auth; response hardening headers; write-method probes leave status unchanged; visible sidebar tab; sandboxed iframe; exact status/tone/inverse CLI; Copy writes exact command to clipboard +PASS fixture-disabled: 10 HTTP assertions; GET/HEAD auth denial and valid auth; response hardening headers; write-method probes leave status unchanged; visible sidebar tab; sandboxed iframe; exact status/tone/inverse CLI; Copy writes exact command to clipboard +PASS fixture-missing: 10 HTTP assertions; GET/HEAD auth denial and valid auth; response hardening headers; write-method probes leave status unchanged; HTTP 503 fails closed; Control UI error without stale status or command +PASS fixture-invalid: 10 HTTP assertions; GET/HEAD auth denial and valid auth; response hardening headers; write-method probes leave status unchanged; HTTP 503 fails closed; Control UI error without stale status or command +PASS fixture-uppercase: 10 HTTP assertions; GET/HEAD auth denial and valid auth; response hardening headers; write-method probes leave status unchanged; HTTP 503 fails closed; Control UI error without stale status or command +PASS fixture-empty: 10 HTTP assertions; GET/HEAD auth denial and valid auth; response hardening headers; write-method probes leave status unchanged; HTTP 503 fails closed; Control UI error without stale status or command +PASS fixture-whitespace: 10 HTTP assertions; GET/HEAD auth denial and valid auth; response hardening headers; write-method probes leave status unchanged; HTTP 503 fails closed; Control UI error without stale status or command diff --git a/docs/validation/pr-28/runtime-matrix.json b/docs/validation/pr-28/runtime-matrix.json new file mode 100644 index 00000000..e97d3f08 --- /dev/null +++ b/docs/validation/pr-28/runtime-matrix.json @@ -0,0 +1,686 @@ +{ + "source": "9aa1df286c2b6fd59b4c101201ddae0ae6000324", + "build": { + "version": "2026.8.2", + "commit": "0965053fe6b9341776df147a6934b7485c60b5ca", + "builtAt": "2026-09-11T00:24:39.157Z", + "buildId": "2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z" + }, + "environment": { + "os": "Windows x64", + "node": "v24.16.0", + "layout": "expanded application", + "port": 19428, + "browser": "152.0.4191.66" + }, + "cases": [ + { + "id": "launcher-disabled", + "launch": "NativeAOT launcher", + "input": "enabled", + "expectedMode": "disabled", + "http": [ + { + "method": "GET", + "access": "anonymous", + "status": 401 + }, + { + "method": "GET", + "access": "wrong-token", + "status": 401 + }, + { + "method": "GET", + "access": "authenticated", + "status": 200 + }, + { + "method": "HEAD", + "access": "anonymous", + "status": 401 + }, + { + "method": "HEAD", + "access": "wrong-token", + "status": 401 + }, + { + "method": "HEAD", + "access": "authenticated", + "status": 200 + }, + { + "method": "POST", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + }, + { + "method": "PUT", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + }, + { + "method": "PATCH", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + }, + { + "method": "DELETE", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + } + ], + "assertions": [ + "GET/HEAD auth denial and valid auth", + "response hardening headers", + "write-method probes leave status unchanged", + "visible sidebar tab", + "sandboxed iframe", + "exact status/tone/inverse CLI", + "Copy writes exact command to clipboard" + ], + "ui": { + "state": "Disabled", + "tone": "warn", + "command": "clawctl gateway-isolation enable", + "sandbox": "allow-scripts", + "copy": "exact clipboard text verified" + }, + "hello": { + "version": "2026.8.2", + "buildId": "2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z", + "controlUiBuildSource": "bundled" + }, + "screenshot": "launcher-disabled.png", + "passed": true + }, + { + "id": "fixture-enabled", + "launch": "Node with launcher-input fixture", + "input": "enabled", + "expectedMode": "enabled", + "http": [ + { + "method": "GET", + "access": "anonymous", + "status": 401 + }, + { + "method": "GET", + "access": "wrong-token", + "status": 401 + }, + { + "method": "GET", + "access": "authenticated", + "status": 200 + }, + { + "method": "HEAD", + "access": "anonymous", + "status": 401 + }, + { + "method": "HEAD", + "access": "wrong-token", + "status": 401 + }, + { + "method": "HEAD", + "access": "authenticated", + "status": 200 + }, + { + "method": "POST", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + }, + { + "method": "PUT", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + }, + { + "method": "PATCH", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + }, + { + "method": "DELETE", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + } + ], + "assertions": [ + "GET/HEAD auth denial and valid auth", + "response hardening headers", + "write-method probes leave status unchanged", + "visible sidebar tab", + "sandboxed iframe", + "exact status/tone/inverse CLI", + "Copy writes exact command to clipboard" + ], + "ui": { + "state": "Enabled", + "tone": "ok", + "command": "clawctl gateway-isolation disable", + "sandbox": "allow-scripts", + "copy": "exact clipboard text verified" + }, + "hello": { + "version": "2026.8.2", + "buildId": "2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z", + "controlUiBuildSource": "bundled" + }, + "screenshot": "fixture-enabled.png", + "passed": true + }, + { + "id": "fixture-disabled", + "launch": "Node with launcher-input fixture", + "input": "disabled", + "expectedMode": "disabled", + "http": [ + { + "method": "GET", + "access": "anonymous", + "status": 401 + }, + { + "method": "GET", + "access": "wrong-token", + "status": 401 + }, + { + "method": "GET", + "access": "authenticated", + "status": 200 + }, + { + "method": "HEAD", + "access": "anonymous", + "status": 401 + }, + { + "method": "HEAD", + "access": "wrong-token", + "status": 401 + }, + { + "method": "HEAD", + "access": "authenticated", + "status": 200 + }, + { + "method": "POST", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + }, + { + "method": "PUT", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + }, + { + "method": "PATCH", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + }, + { + "method": "DELETE", + "access": "authenticated", + "status": 200, + "effect": "same read-only response" + } + ], + "assertions": [ + "GET/HEAD auth denial and valid auth", + "response hardening headers", + "write-method probes leave status unchanged", + "visible sidebar tab", + "sandboxed iframe", + "exact status/tone/inverse CLI", + "Copy writes exact command to clipboard" + ], + "ui": { + "state": "Disabled", + "tone": "warn", + "command": "clawctl gateway-isolation enable", + "sandbox": "allow-scripts", + "copy": "exact clipboard text verified" + }, + "hello": { + "version": "2026.8.2", + "buildId": "2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z", + "controlUiBuildSource": "bundled" + }, + "screenshot": "fixture-disabled.png", + "passed": true + }, + { + "id": "fixture-missing", + "launch": "Node with launcher-input fixture", + "input": "(missing)", + "expectedMode": null, + "http": [ + { + "method": "GET", + "access": "anonymous", + "status": 401 + }, + { + "method": "GET", + "access": "wrong-token", + "status": 401 + }, + { + "method": "GET", + "access": "authenticated", + "status": 503 + }, + { + "method": "HEAD", + "access": "anonymous", + "status": 401 + }, + { + "method": "HEAD", + "access": "wrong-token", + "status": 401 + }, + { + "method": "HEAD", + "access": "authenticated", + "status": 503 + }, + { + "method": "POST", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "PUT", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "PATCH", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "DELETE", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + } + ], + "assertions": [ + "GET/HEAD auth denial and valid auth", + "response hardening headers", + "write-method probes leave status unchanged", + "HTTP 503 fails closed", + "Control UI error without stale status or command" + ], + "ui": { + "status": "invalid launcher mode message", + "staleStatus": false, + "sandbox": "allow-scripts" + }, + "hello": { + "version": "2026.8.2", + "buildId": "2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z", + "controlUiBuildSource": "bundled" + }, + "screenshot": "fixture-missing.png", + "passed": true + }, + { + "id": "fixture-invalid", + "launch": "Node with launcher-input fixture", + "input": "invalid", + "expectedMode": null, + "http": [ + { + "method": "GET", + "access": "anonymous", + "status": 401 + }, + { + "method": "GET", + "access": "wrong-token", + "status": 401 + }, + { + "method": "GET", + "access": "authenticated", + "status": 503 + }, + { + "method": "HEAD", + "access": "anonymous", + "status": 401 + }, + { + "method": "HEAD", + "access": "wrong-token", + "status": 401 + }, + { + "method": "HEAD", + "access": "authenticated", + "status": 503 + }, + { + "method": "POST", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "PUT", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "PATCH", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "DELETE", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + } + ], + "assertions": [ + "GET/HEAD auth denial and valid auth", + "response hardening headers", + "write-method probes leave status unchanged", + "HTTP 503 fails closed", + "Control UI error without stale status or command" + ], + "ui": { + "status": "invalid launcher mode message", + "staleStatus": false, + "sandbox": "allow-scripts" + }, + "hello": { + "version": "2026.8.2", + "buildId": "2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z", + "controlUiBuildSource": "bundled" + }, + "screenshot": "fixture-invalid.png", + "passed": true + }, + { + "id": "fixture-uppercase", + "launch": "Node with launcher-input fixture", + "input": "ENABLED", + "expectedMode": null, + "http": [ + { + "method": "GET", + "access": "anonymous", + "status": 401 + }, + { + "method": "GET", + "access": "wrong-token", + "status": 401 + }, + { + "method": "GET", + "access": "authenticated", + "status": 503 + }, + { + "method": "HEAD", + "access": "anonymous", + "status": 401 + }, + { + "method": "HEAD", + "access": "wrong-token", + "status": 401 + }, + { + "method": "HEAD", + "access": "authenticated", + "status": 503 + }, + { + "method": "POST", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "PUT", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "PATCH", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "DELETE", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + } + ], + "assertions": [ + "GET/HEAD auth denial and valid auth", + "response hardening headers", + "write-method probes leave status unchanged", + "HTTP 503 fails closed", + "Control UI error without stale status or command" + ], + "ui": { + "status": "invalid launcher mode message", + "staleStatus": false, + "sandbox": "allow-scripts" + }, + "hello": { + "version": "2026.8.2", + "buildId": "2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z", + "controlUiBuildSource": "bundled" + }, + "screenshot": "fixture-uppercase.png", + "passed": true + }, + { + "id": "fixture-empty", + "launch": "Node with launcher-input fixture", + "input": "", + "expectedMode": null, + "http": [ + { + "method": "GET", + "access": "anonymous", + "status": 401 + }, + { + "method": "GET", + "access": "wrong-token", + "status": 401 + }, + { + "method": "GET", + "access": "authenticated", + "status": 503 + }, + { + "method": "HEAD", + "access": "anonymous", + "status": 401 + }, + { + "method": "HEAD", + "access": "wrong-token", + "status": 401 + }, + { + "method": "HEAD", + "access": "authenticated", + "status": 503 + }, + { + "method": "POST", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "PUT", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "PATCH", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "DELETE", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + } + ], + "assertions": [ + "GET/HEAD auth denial and valid auth", + "response hardening headers", + "write-method probes leave status unchanged", + "HTTP 503 fails closed", + "Control UI error without stale status or command" + ], + "ui": { + "status": "invalid launcher mode message", + "staleStatus": false, + "sandbox": "allow-scripts" + }, + "hello": { + "version": "2026.8.2", + "buildId": "2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z", + "controlUiBuildSource": "bundled" + }, + "screenshot": "fixture-empty.png", + "passed": true + }, + { + "id": "fixture-whitespace", + "launch": "Node with launcher-input fixture", + "input": " enabled ", + "expectedMode": null, + "http": [ + { + "method": "GET", + "access": "anonymous", + "status": 401 + }, + { + "method": "GET", + "access": "wrong-token", + "status": 401 + }, + { + "method": "GET", + "access": "authenticated", + "status": 503 + }, + { + "method": "HEAD", + "access": "anonymous", + "status": 401 + }, + { + "method": "HEAD", + "access": "wrong-token", + "status": 401 + }, + { + "method": "HEAD", + "access": "authenticated", + "status": 503 + }, + { + "method": "POST", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "PUT", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "PATCH", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + }, + { + "method": "DELETE", + "access": "authenticated", + "status": 503, + "effect": "same read-only response" + } + ], + "assertions": [ + "GET/HEAD auth denial and valid auth", + "response hardening headers", + "write-method probes leave status unchanged", + "HTTP 503 fails closed", + "Control UI error without stale status or command" + ], + "ui": { + "status": "invalid launcher mode message", + "staleStatus": false, + "sandbox": "allow-scripts" + }, + "hello": { + "version": "2026.8.2", + "buildId": "2026.8.2-release-0965053fe6b9-2026-09-11T00-24-39.157Z", + "controlUiBuildSource": "bundled" + }, + "screenshot": "fixture-whitespace.png", + "passed": true + } + ], + "sha256": { + "launcher": "a85063b9caedf346444db4da72fa3ab62a0bf913b6a4b6056b8d0b6d4a476def", + "node": "b3094d0b49f9ad602262a9921551737bb97637c05dd357a06ae98188d7290aa3", + "runtimeEntry": "4f4d29770da4f86dbd0e07cbd4d46deab785905dd89ac719033fcfd866fb5d17", + "plugin": "7f98aed21bf7773f78a25c94c47d4f0f4efd6998c314201869307b798f25d1cd" + }, + "completedAt": "2026-09-11T03:52:53.074Z", + "cleanup": "All validation-owned process trees stopped; port verified free" +} diff --git a/docs/validation/pr-28/runtime-registration.json b/docs/validation/pr-28/runtime-registration.json new file mode 100644 index 00000000..dd92ab42 --- /dev/null +++ b/docs/validation/pr-28/runtime-registration.json @@ -0,0 +1,28 @@ +{ + "command": "openclaw.exe plugins inspect gateway-isolation --runtime --json", + "plugin": { + "id": "gateway-isolation", + "origin": "bundled", + "enabled": true, + "activated": true, + "status": "loaded", + "imported": true, + "httpRoutes": 1 + }, + "capabilities": { + "httpRouteCount": 1, + "gatewayMethods": 0, + "tools": 0, + "services": 0, + "diagnostics": 0, + "typedHooks": 0, + "customHooks": 0, + "commands": 0, + "cliCommands": 0, + "gatewayDiscoveryServices": 0, + "mcpServers": 0, + "lspServers": 0 + }, + "shape": "non-capability", + "capabilityMode": "none" +} diff --git a/plugins/gateway-isolation/index.test.js b/plugins/gateway-isolation/index.test.js index 2e5c09dd..c8f35830 100644 --- a/plugins/gateway-isolation/index.test.js +++ b/plugins/gateway-isolation/index.test.js @@ -113,30 +113,50 @@ test("registers one read-only Control tab and one authenticated sandbox route", assert.match(response.body, />Enabled { - const env = { CLAWCTL_GATEWAY_ISOLATION: "enabled" }; - const plugin = createGatewayIsolationPlugin(env); - env.CLAWCTL_GATEWAY_ISOLATION = "disabled"; - const routes = []; - plugin.register({ - session: { - controls: { - registerControlUiDescriptor() {}, +for (const initial of ["enabled", "disabled", undefined, "", "invalid", "ENABLED", " enabled "]) { + test(`reads ${JSON.stringify(initial) ?? "missing"} exactly once and keeps every response stable`, () => { + let reads = 0; + let value = initial; + const plugin = createGatewayIsolationPlugin({ + get CLAWCTL_GATEWAY_ISOLATION() { + reads++; + return value; }, - }, - registerHttpRoute(route) { - routes.push(route); - }, - }); + }); + assert.equal(reads, 1); + value = initial === "enabled" ? "disabled" : "enabled"; + const routes = []; + plugin.register({ + session: { controls: { registerControlUiDescriptor() {} } }, + registerHttpRoute(route) { + routes.push(route); + }, + }); - const response = invokeRoute(routes[0]); - assert.match(response.body, />EnabledDisabledEnabledDisabled { - const { routes } = registerPlugin("invalid"); - const response = invokeRoute(routes[0]); - assert.equal(response.statusCode, 503); - assert.match(response.body, /did not provide a valid Gateway isolation mode/); -}); +for (const mode of [undefined, "", "invalid", "ENABLED", " enabled "]) { + const label = JSON.stringify(mode) ?? "missing"; + test(`fails closed for ${label} with no status, command, or copy control`, () => { + const { routes } = registerPlugin(mode); + const response = invokeRoute(routes[0]); + assert.equal(response.statusCode, 503); + assert.match(response.body, /did not provide a valid Gateway isolation mode/); + assert.doesNotMatch(response.body, /status--(?:ok|warn)|isolation-command|