Skip to content

fix(setup): stop console flashes when Gateway cleanup runs - #1782

Open
paulcam206 wants to merge 9 commits into
openclaw:mainfrom
paulcam206:paulcam206-gateway-cleanup-draft
Open

paulcam206 wants to merge 9 commits into
openclaw:mainfrom
paulcam206:paulcam206-gateway-cleanup-draft

Conversation

@paulcam206

@paulcam206 paulcam206 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes: the Gateway cleanup scheduled task briefly shows a console or taskbar entry when its once-per-minute action starts.

User Impact

User impact: automatic Gateway cleanup continues without interrupting the desktop. The cleanup cadence, current-user identity and cleanup policy remain unchanged. This ships with Companion, not Gateway-only repackaging.

Why This Change Was Made

The task currently launches Windows PowerShell directly with -WindowStyle Hidden. A console can be created before PowerShell handles that option.

The task instead starts a small .NET Framework 4.8 GUI-subsystem helper. It launches the existing PowerShell worker with creation-time CreateNoWindow, drains output, records failure diagnostics and returns the worker exit code. The hash-versioned helper and worker are copied outside the Companion package. Natural cleanup after real bundle removal is now verified for the qualified combined candidate below; uninstall window-event collection remains blocked.

Both this helper (A) and the evaluated JScript prototype met the measured visible-window/taskbar contract. A avoids adding WSH/JScript/COM policy dependence. It does add a small custom executable and build wiring; that executable can itself be blocked by application control. The JScript prototype is not included in this PR.

The signing follow-up signs the cleanup EXE through the existing Azure Artifact Signing identity before x64, ARM64 and Store/Dev MSIX builds embed it. Signing the outer SetupEngine DLL cannot sign an embedded EXE. Non-dev Release builds now require signed input by default; unsigned Debug/Dev builds and explicitly non-published PR smoke builds remain supported. Pre-embed signature checks, post-build resource byte/signature checks and final payload verification prevent an unsigned or substituted nested helper from silently reaching a signed release.

Evidence

Current-head signed native acceptance: 9c521dd8e0e1e0f5397148f4d30935f80f5db1fa

The three commits after d3a9bc46 correct tests/observers only; the sign-before-embed product implementation is unchanged. This exact head now passes actual signed-helper execution, correlated enforcing-policy controls and finalized uninstall visibility in a disposable native x64 guest. These results supersede the corresponding earlier proof blockers below, without rewriting failed attempts as passes.

Provider/target/mode: Hyper-V / Windows / normal, lease cbx_0bada2c7f851. No hosted run URL exists for this local Hyper-V run. Proof CLI pin 6bd7156a, executable SHA256 02E320F040005AE40C6F4445FECB3948F4FF762B2B7786FCAE29A9B80B4C2F40. Actual release helper was built, signed with a guest-only test signer, then embedded through OpenClawSignedCleanupHostPath and RequireSignedCleanupHost=true. The shipped verifier and an independent extraction verified the actual named resource: Authenticode Valid and byte-identical signed/extracted SHA256 3925A87C6912C405DA84D4A5FDC9081DAD9EDD3A1B2EDACC26F1C752C203F02B. Release SetupEngine SHA256 07DC4F9CEA1EB412DA26272F120807E8394E4973CD4CD9109D7D5E37AC7EA08A. This is not Azure production signing or Store signing.

AppLocker ENFORCE: policy application was qualified with event 8001 and a record-ID boundary. The actual extracted signed helper returned 37, produced its intended fixture effect and correlated to event 8002. Unsigned and wrong-signer controls both failed with native 1260, produced no forbidden effect and correlated to distinct 8004 events. Records were reconciled from the EXE and DLL channel by exact provider, path, target user, rule and process identity; no requirement or timeout was relaxed. All three controls passed. Original policy was restored.

Real uninstall lifecycle: production deployment and actual Task Scheduler invoked the signed resource after real disposable MSIX removal. An adjacent wrapper synchronized entry; the untouched production cleanup worker then ran. Actual GUI helper parent and worker were observed through final release/exit, helper native exit 0, production complete marker present, task retired. Finalized observer: 294 window samples, 15 taskbar samples, zero visible-console/taskbar observations, zero observer errors, 9.368 seconds. Maximum measured gaps: window 674.04 ms, taskbar 1234.25 ms. This is bounded sampled no-flash proof, not a guarantee against every shorter transient or a full Store Companion settings-migration pass.

The proof owner copied current-head receipts/TRX and restored guest policy, removed owned tasks/packages/processes, and released the exact lease (stop exit 0, nonexpired); no host/shared Gateway state was changed. Receipt manifest binds the final evidence JSON to SHA256 5069093D48C53DC177DCB0DF07647775E9E53E2E4514D413AC11789F8AFB393D. Raw archives remain private; only sanitized copied outcomes are published here.

Limits: Smart App Control reputation is not covered. Native ARM64 validation is in progress via the validation package. Official-signed install/upgrade/uninstall will run on the first prerelease containing this change, before stable promotion. Broader AV/EDR diversity and the historical reporter-build/settings-migration limitations remain; no blanket proof-pool completion is claimed.

Historical signing fix: d3a9bc46d10f4177dd9ad5d1b0fcfe32ffc315de

Addresses the real P2 from the preceding 4947736e review (3/3/3). Five actual-build regression cases pass: unsigned development resource allowed; default non-dev Release without signing input rejected; unsigned supplied input rejected; a valid existing OS-signed fixture embedded byte-for-byte with its signature retained; mismatched resource/input rejected. These build the actual SetupEngine project and inspect the actual compiled resource, not implementation text. No certificate, trust or installed runtime change was made.

The existing protected Azure signing account/profile signs the AnyCPU helper once, before every release consumer compiles SetupEngine. CI release tags/promotions require that artifact, including Store submissions whose outer package is unsigned. Expected OpenClaw signer identity is also checked before artifact upload and again in final release-payload verification.

Limits: Azure production signing was not executed locally. The OS-signed fixture proves the build/resource boundary, not production cleanup-host execution or signed AppLocker acceptance. Historical runtime and guest proof below retains its original source scope; references to "current-head" in that retained history mean 4947736e, not this signing-fix head. Native ARM64, signed-policy acceptance and uninstall window-event finalization remain open. PR stays ready, not asserted merge-ready.

Expanded disposable Windows-host execution, 2026-10-22

This later authorized execution supersedes the acquisition-only limits of the earlier attempt below, not its recorded failure. Provider/target/mode: Hyper-V / windows / normal; lease cbx_ea5b9ce73e93, VMID 490cc5f9-83b8-40e0-a733-5d03db32f1f6, guest WIN-A65IQ651TA1, x64 Windows 10.0.29683. No hosted run URL exists for this local Hyper-V run. Pinned Crabbox source db7687e5, executable SHA256 587884DFACC22196889B7EFF5D593A080EAFE1730D4771A627F8E5CD11D6D5D3. The previously live-qualified 1f79f365 desktop route was retained; the verified product difference to this pin was the Direct-readiness budget changing from five to ten minutes. Actual warmup --desktop succeeded in 296 seconds against the verified read-only differencing parent. Actual passive observation qualified session 1, WinSta0 Default/input Default with input-desktop access.

Official hash-verified portable .NET SDK 10.0.402 and PowerShell 7.6.7 were staged only in the disposable guest, under explicit authority. SDK first-use generated a guest development certificate; subsequent runs disabled that generation. No host installation, host certificate/policy, shared Gateway or parent-VHDX change occurred. All 54 transferred guest evidence files matched their guest SHA256. Outcomes below are sanitized copied receipts retained privately, not publicly downloadable local-path links.

Supported invocation vectors used, with the exact script selected per receipt:

run --provider hyperv --target windows --windows-mode normal --id cbx_ea5b9ce73e93 --no-sync --script <exact artifact script path> --timing-json --timing-record off
desktop launch --provider hyperv --target windows --windows-mode normal --id cbx_ea5b9ce73e93 -- C:\crabbox\hub-proof-tools\pwsh\pwsh.exe -NoProfile -NonInteractive -EncodedCommand <UTF16LE encoding of reviewed artifact body>

Both used the trusted lease controller and pinned CLI, not an unsupported execution route. These are recorded command vectors, not instructions to replay expired authorization.
1782 result at 4947736e6819c965107eb21a60cc0b9a6dbfb033: actual enforced denial established; signed acceptance blocked. The exact cleanup-host project and four owner/collector files were acquired from full-SHA public URLs with source/hash bindings. The actual project built x64 with LangVersion=latest, retaining PE version metadata. A nonexportable guest-local test signer signed the actual host and adjacent original worker/task scripts; source bindings, pre/post hashes and actual signatures were retained. Signing and trust were guest-only test preparation, not production signing or reputation proof.

A real ENFORCING AppLocker Exe collection, starting from actually empty baseline XML, scoped denial to the task restricted executables except the actual test publisher while allowing other execution. Effective policy was unchanged across the recorded second control. Actual unsigned start failed with native error 1260, a real matching 8004 event identified the exact unsigned path and deny rule, and no forbidden sentinel effect occurred. The failed immediate-event collection and fresh 15-second subscription remain failures. A later finalizer attempted event reconciliation and signed-host launch, but transport expired: signed acceptance remains UNVERIFIED, not inferred from a valid signature.

actual cleanup-host x64 build=passed
unsigned execution=native error 1260; matching AppLocker 8004 event
forbidden sentinel effect=absent
signed-host acceptance=unverified (finalizer transport expired)
native uninstall-window scenario=not run; MSIX fixture=not created/installed
native ARM64=unavailable

This closes only the actual unsigned-denial observation, not the acceptance pair, full application-control diversity or any complete proof pool. No native uninstall scenario or finalized uninstall-window receipt was produced in this guest. Earlier Scheduler and qualified combined installed evidence remain separate. The PR remains READY (not draft); this evidence update does not declare it merge-ready.

Transport and disposal: the signed-acceptance finalizer and read-only desktop-actor probe each expired at 120 seconds; the final read-only normal run --no-sync recovery expired at 660 seconds. No output established their execution point. No further retries occurred. Final guest process/desktop cleanup before disposal is unverified. Parent exact-ID release completed at 2026-10-22T07:04:47.9589568Z, exit 0, nonexpired. Independent Get-VM confirmed this exact VM absent; parent-template length and last-write UTC ticks were unchanged. No task-owned VM remains. VM disposal is not a claim that pre-teardown process cleanup passed.

Overnight native-host proof attempt, 2026-10-22

This is an infrastructure preflight failure, not a product test failure or pass. The source head is unchanged. An authorized, unelevated native Windows Hyper-V desktop lease was requested from the approved read-only differencing parent. No managed/SDK/native application controls ran because the guest never reached readiness.

  • Provider/target: hyperv, native windows, mode normal, desktop requested.
  • Raw lease ID: cbx_dd88578c30c0.
  • Run URL: not emitted; acquisition failed before a remote proof run existed.
  • CLI pin: source 1a23239012e0906ecb82acb173f9855f6f53aa36, Go1.27.3; local executable SHA-256 F2036C256DB744AF00403D24193FECBDD09EA260696D2AF2D4752C1DBB13A69B. This is an identified local interim build, not a claimed published Crabbox release.

Exact acquisition command (the CLI's normal credential handling was used; no credential value was read or printed):

& 'E:\crabbox-proof\pins\1a232390-windows-hyperv\crabbox.exe' warmup --provider hyperv --target windows --windows-mode normal --hyperv-image 'E:\crabbox-proof\windows-readiness-template-v3\windows-primed-template.vhdx' --hyperv-switch 'Default Switch' --hyperv-user crabbox --desktop --keep --idle-timeout 45m --ttl 120m --timing-json

Copied acquisition result:

provider=hyperv lease=cbx_dd88578c30c0
stage=powershell-direct state=waiting budget=5m0s
guest readiness probe failed: exit status 1
context deadline exceeded
warmup exit=1; native controls executed=0

The cause beyond that PowerShell Direct/readiness failure remains unknown. It is not attributed to these PR changes, CPU load, credentials or desktop support without further evidence. No load-based start gate, elevation, checkpoint or unsupported exec command was used.

Exact cleanup command and independently checked outcome:

crabbox stop --provider hyperv cbx_dd88578c30c0
stop exit=0
exact task VM absent=True
read-only parent length unchanged=True
read-only parent last-write UTC ticks unchanged=True

No other lease was stopped. The parent image was not hashed or modified. This evidence establishes the attempted environment and cleanup only; it does not qualify an interactive desktop, native startup behavior, signed execution or enforcement.

At the earlier acquisition-only stop, finalized signed-artifact uninstall-window observation and actual enforcing application-control execution were unverified; no policy or certificate was changed in that attempt. The later explicitly authorized guest-only signer/policy preparation and actual denial evidence above supersede that application-control acquisition limit; signed acceptance and uninstall-window proof remain unverified. Native ARM64 is unavailable. Existing current-head x64 Scheduler and separately labeled combined installed evidence retain their original scope; the failed host acquisition does not complete those missing cases.

Current-head hosted checks refreshed 2026-10-22T03:14:06.1175377Z: 11 skipped, 24 success. Existing per-test CI classifications elsewhere in this body remain unchanged; this preflight ran no product tests.

Current-head Windows x64 tests detect a deliberately visible classic console through WinEvent, periodic window enumeration and taskbar UI Automation. Helper A produces no visible-window or taskbar observations for worker exits 0 and 37; missing/throwing workers, complex paths and registration refresh are covered.

An additional current-head run used one uniquely named disposable Task Scheduler task, production helper deployment and production action registration/refresh, with a harmless event-synchronized worker. It detected the original direct PowerShell launch and observed no visible replacement launch. The copied output is below. This is actual Scheduler proof, not installed-package or post-uninstall proof.

Earlier three-run comparisons, including bounded light load, detected the original action and found zero visible-window/taskbar observations for A and a JScript prototype. Those comparisons are historical, not rerun JScript evidence on this head. A avoids adding WSH/JScript/COM policy dependencies.

Finite sampling cannot exclude every arbitrarily short transient. A desktop capture attempt did not reliably capture the console compositor surface, so no screenshot is presented as evidence of absence. The current-head behavioral observer and positive calibration are the supporting evidence.

Read-only rubber-duck review found no remaining correctness findings. ClawSweeper's review of the earlier d9e30f17 head found no actionable code findings (patch quality 4/6), but requested installed/upgrade/uninstall, ARM64 and application-control proof before merge (readiness 2/6). Installed task refresh, natural AFTER comparison, natural uninstall cleanup and fresh-agent restoration now have qualified combined-build evidence below. Uninstall window-event finalization, complete Hub-settings migration, native ARM64 and application-control gaps remain; before this bounded proof update, a new-head review had not been manually requested. One exact @clawsweeper re-review is authorized after body verification; draft state and reviewers remain unchanged.

Change Type

  • Bug fix
  • Feature
  • Refactor
  • Docs or instructions
  • Tests or validation
  • Security hardening
  • Chore or infrastructure

Scope

  • Tray or WinUI UX
  • Windows node capability
  • Local MCP or winnode
  • Gateway, connection, or pairing
  • Setup or onboarding
  • Permissions, privacy, or security
  • Tests, CI, or docs

Required proof pools

  • windows-clean-installer-upgrade: the official-signed install/upgrade/uninstall lane requires an official signed artifact. The CI release-signing environment signs on v* release tags (and the explicit alpha-promotion path), not ordinary PR builds. Verify this lane on the first prerelease containing this change, before promotion to stable. Current-head disposable test-signed uninstall and earlier qualified combined-build refresh evidence remain below.
  • windows-winui-interactive: visible-window and taskbar regression proof. Local process and disposable Scheduler proof passed; this does not claim full isolated-app pool completion.
  • windows-11-arm64: native ARM64 validation is in progress through a carryable Release validation package from exact head 9c521dd8; results will be added after execution on native ARM64 Windows 11 hardware.

Validation

Current-head corrective validation: 9c521dd8e0e1e0f5397148f4d30935f80f5db1fa

Executed in the disposable native Windows guest, exact clean source head. Final copied TRX outcomes:

Command / lane Result
.\build.ps1 Passed
dotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restore 4486 passed, 0 failed, 35 configured skips
dotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --no-restore 4304 passed, 0 failed, all 4304 executed
dotnet test .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj --no-restore --filter 'FullyQualifiedName~CleanupAppLockerEvidenceTests|FullyQualifiedName~CleanupVisibilityRunStateTests' 27/27 passed, 0 failed
dotnet test .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj --no-restore -p:OpenClawSignedCleanupHostPath=<actual guest signed helper> -p:RequireSignedCleanupHost=true --filter 'FullyQualifiedName~GatewayCleanupTaskTests|FullyQualifiedName~CleanupProofWorkerTests' 8/8 passed, 0 failed
Actual signed resource verification + three correlated AppLocker controls + finalized real uninstall observer Passed; see current-head evidence

An earlier full Tray run had 4303 passes and one failure in OpenClawChatDataProviderTests.CompactAuthoritativeReload_RetriesAfterTransientFailureWhenHistoryWasLoaded. Its request-entry count can reach three before reload application completes. Test/provider/loader source blobs are identical to the published d3a9bc46 baseline, supporting a pre-existing asynchronous synchronization defect; failure on a baseline binary was not reproduced. One focused rerun passed, then the entire required block above passed. No chat source/assertion changes, sleep or deadline increases were made in this PR. Earlier failed guest attempts and their limits remain in the historical record. These guest outcomes do not imply newly queued hosted CI has passed.

Historical signing-fix validation

Validated source: d3a9bc46d10f4177dd9ad5d1b0fcfe32ffc315de. Test data/results were isolated. Tray and SetupEngine used the existing private-desktop runner, with nonzero TRX execution and verified native exit/desktop receipts; no shared app, package, Gateway or profile operations.

Command or lane Result
.\build.ps1 Passed, including 63 Markdown files
dotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restore 4486 passed, 35 configured skips
pwsh -NoProfile -File Invoke-PrivateProof.ps1 -Repository <this checkout> -Evidence <new owned output> -Project .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj -Report tray 4304 passed, 0 skipped
pwsh -NoProfile -File Invoke-PrivateProof.ps1 -Repository <this checkout> -Evidence <new owned output> -Project .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj -Report setup 2418 passed, 3 configured skips
.\scripts\test-cleanup-host-signing.ps1 All 5 actual-build cases passed
.\scripts\test-ci-workflow-contract.ps1 Passed, preserving original dependency edges plus signing prerequisites
.\scripts\validate-agent-skills.ps1 Passed: 11 skills / 20 Markdown files
Workflow YAML parse; git diff --check Passed: 20 jobs; clean whitespace

An earlier Shared run had one fixture WebSocket teardown cancellation. Its exact targeted rerun and subsequent full runs passed without code/test changes. Read-only rubber-duck review of the sign-before-embed implementation found no findings; the final default-Release guard additionally passed the actual missing-input build regression. Hosted checks for this new head are not inferred from the historical results below.

Historical pre-signing validation

Validated commit: 4947736e6819c965107eb21a60cc0b9a6dbfb033, based on upstream main 431bd8f9. Isolated test data roots were used for full suites. OPENCLAW_REPO_ROOT selected this worktree; OPENCLAW_RUN_INTEGRATION=1 enabled desktop proof.

Exact command Result
.\build.ps1 Passed
dotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restore 4520 passed, 1 configured skip
dotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --no-restore 4304 passed, 0 skipped
dotnet test .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj --no-restore 2420 passed, 1 configured cross-volume skip
dotnet test .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj --no-restore --filter 'FullyQualifiedName~GatewayCleanup|FullyQualifiedName~PackageCleanup' 38 passed, 0 skipped, including desktop positive/negative proof
.\scripts\validate-docs.ps1 Passed: 63 Markdown files
.\scripts\validate-agent-skills.ps1 Passed: 11 skills / 20 Markdown files
git diff --check Passed

Hosted CI refreshed for current head 4947736e6819c965107eb21a60cc0b9a6dbfb033: 21 successful checks, 7 skipped, no failing conclusions. The previous-head failures are not the current check state. Configured CI skips do not close the separate installed-package, ARM64 or policy proof lanes below.

Prior Release/ARM64 compilation is supporting evidence only, not current-head native ARM64 execution.

Real Behavior Proof

Historical signing-build boundary

  • Environment: native Windows x64; actual SetupEngine Release build; existing valid OS-signed executable as the signature fixture.
  • Source: d3a9bc46d10f4177dd9ad5d1b0fcfe32ffc315de.
  • Command: .\scripts\test-cleanup-host-signing.ps1.
  • Result: five cases passed; the actual embedded resource matched the signed fixture SHA256 and retained Authenticode Valid; default Release missing-input, unsigned-input and mismatch cases failed as required. Unsigned development build succeeded.
  • No public artifact link. Local receipts are retained. Production Azure signer execution and actual signed-helper enforcement acceptance remain unverified.

Historical runtime proof

  • Environment tested: native Windows 10.0.26713.0 x64, Windows PowerShell 5.1, interactive desktop with a custom desktop shell.
  • PR head or commit tested: 4947736e6819c965107eb21a60cc0b9a6dbfb033.
  • Exact steps or command run: integration-enabled focused SetupEngine command listed above, then full build/suites; additionally pwsh -NoProfile -File current-head-cleanup-task-proof.ps1 (local disposable harness: GatewayPackageCleanup.DeployAsync, production cleanup-task.ps1, Start-ScheduledTask, native visibility observer, Get-ScheduledTaskInfo). Only its nonce-named scratch task/folder and harmless worker were used, not the installed cleanup task or package/profile state.
  • Evidence after fix, copied current-head Scheduler output:
Case       TaskResult VisibleWindows TaskbarEntries
original            0              1              0
helper-0            0              0              0
helper-37          37              0              0
  • Observed result: original launch visibly detected; helper exits 0/37 propagated with no visible-window/taskbar observations. The focused positive fixture independently requires both window observers and taskbar discovery to detect a visible console. Hidden HWNDs are diagnostic, not failures.
  • Measurement limits: maximum observed window-sampling gaps were 99.62/82.15/76.84 ms (original/helper-0/helper-37); taskbar snapshot gaps were 969.34/798.59/804.39 ms. All three runs reported zero observer errors. These are measured observations, not a guarantee against shorter transients.
  • Cleanup: disposable task absent before/after; scratch removed; owned worker processes exited.
  • Screenshot or artifact links verified? N/A. Copied redacted live output above. Visual capture was not reliable; no misleading screenshot is attached.
  • Real Store BEFORE baseline, separate from current-head synthetic proof: the original shipping Companion 2026.10.401.0 performed normal setup with Gateway genuinely absent, installed Store Gateway 2026.10.400.0, and created its own production ownership receipt and original PowerShell PT1M task. No ownership receipt was fabricated and no task was manually triggered or edited.
  • Native-event BEFORE observation, 2026-10-20 18:05:50-18:09:21 PT: four exact cleanup-worker PowerShell roots started naturally at 18:06, 18:07, 18:08 and 18:09. The system-wide WinEvent observer recorded seven raw visible foreground events and three SHOW events for WindowsTerminal.exe, class CASCADIA_HOSTING_WINDOW_CLASS, correlated with those launches. Five foreground receipts additionally satisfy on-monitor and noncloaked checks, spanning all four launches. LastTaskResult was 0. Seven title-masked window-only rendered snapshots were retained privately; these are not desktop video or a flash-duration measurement.
  • Attribution limits: the Terminal broker is outside the cleanup process ancestry, so this is repeated temporal correlation with exact cleanup command metadata, not direct ancestry attribution. Win32_ProcessStartTrace was denied without elevation and the Scheduler Operational log was disabled. Process creation times/ancestry were read only in response to native console/Terminal window events, not periodic window/process polling. The earlier process-owned polling/UIA capture missed flashes that the developer saw; its taskbar UIA probe errored and it is not absence-of-flash proof.
  • Installed upgrade/task-refresh proof: the first locally test-signed standalone Hub402 MSIX failed atomic update with 0x80073CF3 before staging/registration commit; the old working baseline was recovered. The original Store install is bundle-distributed. A standard signed bundle succeeded on the one coordinated retry without force/removal/reset/trust changes or UAC. Bundle SHA256 0ACB55DFB2043562630B41A71AB9288B1E7C08953840C836255349D0031171F5; source 63a8130977fa091647226b553857f418d9d7007d, not a pure PR1782 binary. Cleanup source matches this PR except an equivalent home-name constant. Independent comparison found all 1,068 non-signing files byte-identical; only catalog/signature envelopes changed during bundling. No precise deployment subreason beyond the generic CF3 was established.
  • After normal packaged Hub402 activation, production startup refreshed the real existing task to durable cleanup-host-4ADA4355ECB4C527A707E6C0FC62770B4274816396E6C1B25D4D0EBE9DA19FEB.exe; its on-disk hash matches the candidate's embedded helper. Gateway400 is running, Hub402 has a main window, and the real agent's Coproxilot route and exact configuration hash match the fresh stopped backup. These establish installed refresh and agent-config preservation, not complete Hub-settings migration.
  • Real natural-interval AFTER comparison, 2026-10-21 02:41:11.780-02:44:41.886 UTC: the same native observer received 516 window events with zero ConsoleWindowClass/Terminal events and no observer errors. The separate Scheduler sampler recorded three natural launches at 02:41:41, 02:42:41 and 02:43:41 UTC, all result zero, expected helper/hash. Both collectors exited zero. The native final task query coincided with a fourth running launch; a subsequent real-task query returned zero. Process-start access remains denied; no UIA/taskbar/continuous-video or complete broker-ancestry claim. No AFTER console PNG exists because no console/Terminal event was observed.
  • Real uninstall survival: after a fresh stopped POST-REPAIR export, exact Hub402 bundle removal returned successfully. The unchanged worker subsequently removed the genuinely owned Gateway, its ownership receipt and its own scheduled task without manual Gateway removal or task invocation/edit/unregistration. Independent exact-name Main/Bundle/Resource inventory found Hub and Gateway absent; exact COM task lookup returned FILE_NOT_FOUND; a fresh complete marker postdated the removal request. The durable helper remained present with unchanged 4ADA4355... hash. Self-unregistration means no final task result is inferred.
  • Uninstall observer blocker: native readiness was established before removal, but the requested 210-second observer did not finalize after more than six minutes. Only that identity-verified task-owned collector was stopped. Its final event receipt/counts are absent; the hang stage is not established. No zero-console uninstall claim. This does not invalidate the separate completed natural AFTER collection above.
  • Fresh restoration: normally reinstalled the pinned combined Hub402 bundle, acquired Store Gateway400 through normal native setup while Gateway was absent, and selected a genuinely different agent SID/profile. Restored only agent .openclaw data from the immutable stopped POST-REPAIR export. Explicit reviewed-source-root rebasing changed exactly three canonical agents.entries workspace/agentDir paths. Source immutability, exact expected transformed configuration hash and preserved provider/primary route were verified; date-looking strings stayed strings. No old Gateway LocalState/session/setup records were replayed. The agent transfer is an opaque overlay, not a whole-tree mirror.
  • Recovery runtime proof: normal existing-model verification reached Ready, and one Finish invocation completed a product-owned Hub restart. Authenticated MCP discovery/status reported schema2 Ready, connected operator, connected/paired node and running local MCP. One fresh real-Gateway-listed conversation returned the exact requested RESTORE_OK, visibly rendered and privately captured. Final settings were MCP=true, Node=true, AutoStart=false; route/model remained unchanged. This proves a working recovered runtime, not complete Hub-settings migration, node.invoke execution or absence of an uninstall flash.
  • Not verified or blocked: uninstall native-window receipt/counts, complete latest-stable Hub-settings preservation; exact reporter Windows 26706 environment; native ARM64 execution; AV/EDR and enforcing application-control diversity, including signed acceptance under the guest AppLocker policy above. The combined candidate's unrelated fail-closed provenance P2 remains open; it is not claimed Claw-clear. The sealed ARM64 carry is delivered for hardware execution, not an ARM64 pass.

Security Impact

  • New permissions or capabilities? No
  • Secrets or tokens handling changed? No
  • New or changed network calls? No
  • Command or tool execution surface changed? Yes
  • Data access scope changed? No
  • If any answer is Yes, explain the risk and mitigation: task entry point changes to a copied GUI helper; fixed system PowerShell path, validated package-family argument, unchanged current-user Interactive/Limited principal and unchanged cleanup policy. No elevation, new logon type or new runtime download.

Compatibility and Migration

  • Backward compatible? Yes
  • Config or environment changes? No new user configuration.
  • Migration needed? Yes, automatic task-action refresh.
  • If yes, list the exact upgrade steps: packaged Companion startup copies the versioned helper/worker and replaces the existing task action; managed Gateway creation also registers it. Users need an updated Companion build. Installed refresh/AFTER, natural uninstall cleanup and fresh restoration have qualified combined-build evidence; uninstall window-event finalization and complete Hub-settings migration remain open.

Cleanup storage formats, ownership receipts/sentinels and destructive-cleanup policy are unchanged. The worker diff extracts task registration and changes the launch action; behavioral cleanup-policy coverage still runs. ClawSweeper's generic data-model compatibility request identifies no specific changed schema or demonstrated incompatibility. Real installed task refresh and exact agent-config preservation are verified for the qualified combined build; full Hub-settings migration is not claimed.

Review Conversations

  • I replied to or resolved every bot review conversation addressed by this PR.
  • I left unresolved only conversations that still need maintainer judgment.

@clawsweeper

clawsweeper Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@clawsweeper clawsweeper Bot added clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-repro Preliminary submission classification; full source review pending. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-repro Preliminary submission classification; full source review pending. labels Oct 20, 2026
@clawsweeper

clawsweeper Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge.

What this changes

This PR launches scheduled Gateway cleanup through a durable windowless helper and signs that helper before embedding it in release builds.

Example: The Gateway cleanup task starts at its one-minute interval.

  • Before: PowerShell can briefly display a console despite receiving -WindowStyle Hidden.
  • After: A GUI-subsystem helper starts PowerShell with CreateNoWindow and forwards worker exit codes, including 0 and 37.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) The implementation is focused and the x64 native evidence is substantial, but the repository's remaining declared platform and official-signing acceptance requirements are unfinished.
Proof confidence 🦐 gold shrimp (3/6) Real behavior proof is necessary before merge. See Before merge.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Product

Kind: Bug fix · Worth it: Yes · Fix scope: Complete
User problem: Automatic Gateway cleanup can interrupt the desktop with a console or taskbar appearance every minute.
Reason: Suppressing console creation fixes a concrete recurring interruption while preserving cleanup cadence, identity, ownership checks, and recovery behavior.

Merge readiness

⛔ Blocked before merge - 1 item remains

Keep open: current main still launches cleanup through PowerShell directly, and this PR provides a useful fix with no actionable code findings.

Priority: P2
Reviewed head: 9c521dd8e0e1e0f5397148f4d30935f80f5db1fa

Before merge

  • Add real behavior proof - Current-head copied native x64 receipts exercise the actual signed embedded helper through production deployment and Task Scheduler after disposable MSIX removal, with exit propagation, completed cleanup, finalized visibility observation, and correlated AppLocker acceptance/denial controls. Historical installed-task refresh evidence is explicitly attributed to a combined candidate. The declared native ARM64 and official signed-artifact install/upgrade and Smart App Control lanes remain incomplete; provide focused terminal captures or redacted logs identifying the tested artifacts and outcomes, with credentials, IPs, user identities, and non-public endpoints removed. After adding proof, update the PR body, then request a new review with @clawsweeper re-review. The PR author or someone with repository write access can request it.

Findings

None.

Tests

  • Missing end-to-end proof: Native ARM64 execution and official signed-artifact install/upgrade and cleanup execution under enforcing Smart App Control remain unverified.
Agent review details

How this fits together

SetupEngine deploys cleanup resources outside the Companion package and registers a limited current-user scheduled task; the helper invokes the existing ownership-checked cleanup worker and returns its result to Task Scheduler.

flowchart LR
  A[Companion startup] --> B[SetupEngine deployment]
  B --> C[Durable cleanup resources]
  B --> D[Current-user scheduled task]
  D --> E[Windowless helper]
  C --> E
  E --> F[PowerShell cleanup worker]
  F --> G[Ownership-checked Gateway removal]
Loading

Technical review

Best possible solution:

Land the focused windowless launcher with sign-before-embed integrity and the existing cleanup ownership safeguards preserved.

Do we have a high-confidence way to reproduce the issue?

Current-main source retains direct PowerShell task execution, and supplied before traces detect a visible launch; this read-only review did not execute the application.

Is this the best way to solve the issue?

A small GUI-subsystem helper addresses console creation at process startup, survives package removal, and avoids introducing WSH/JScript dependence; the new build-only properties support the existing release-signing contract.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against fb45902950fd.

Provenance checked

  • Scheduled cleanup launch and durable deployment changes intended behavior with a stated reason (62752f4: Keep current-user, ownership-checked Gateway cleanup available after Companion MSIX removal.)
  • First-party executable signing keeps the original intent (adef8fc: Require valid signatures from the exact OpenClaw signer for all first-party shipped binaries.)
  • Release build dependency ordering keeps the original intent (969fe6d: Select conservative validation lanes while retaining full release validation; this PR preserves existing dependencies and adds signing prerequisites.)

Testing

Proof path: shipped entry point.

Security

None.

Evidence

What I checked:

  • Current main retains the reported launch path: The fetched default branch still registers powershell.exe directly with -WindowStyle Hidden; the requested windowless helper is absent from this registration path. (src/OpenClaw.SetupEngine/GatewayPackageCleanup.ps1:81, fb45902950fd)
  • Introduced production behavior: The pinned introduction diff adds a GUI-subsystem helper, creation-time console suppression, hash-versioned deployment, and extracted task registration while preserving the existing cleanup policy. (src/OpenClaw.GatewayCleanupHost/Program.cs:23, 9c521dd8e0e1)
  • Previous signing finding addressed: Release builds require signed input, verify it before embedding, and verify the compiled resource afterward; release payload verification additionally checks the expected OpenClaw signer. (src/OpenClaw.SetupEngine/OpenClaw.SetupEngine.csproj:29, 9c521dd8e0e1)
  • Current-head native acceptance: The full PR body records native x64 execution of the actual guest-test-signed embedded helper, exit 37 and its intended effect, AppLocker 8002 acceptance, and unsigned/wrong-signer rejection with error 1260, distinct 8004 events, and no forbidden effects. Production Task Scheduler execution after disposable MSIX removal returned 0, completed cleanup, retired the task, and finalized visibility observation without reported visible-console or taskbar observations. These supersede the corresponding earlier blockers. (9c521dd8e0e1)
  • Remaining scoped proof requirements: The proof inventory requires Smart App Control validation for changed executable layout or signing and native ARM64 validation for changed runtime dependencies; the PR explicitly declares both pools and records their remaining limits. (.github/proof-pools.json:67, 9c521dd8e0e1)
  • Cleanup provenance and ownership: History and discussion on fix(setup): clean up owned Gateways after Companion uninstall #1715 establish the durable cleanup owner, limited current-user execution, replacement protection, and preservation recovery that this PR retains. (src/OpenClaw.SetupEngine/GatewayPackageCleanup.ps1:81, 62752f44cda2)

Likely related people:

  • Joel: Raw commit 62752f4 adds src/OpenClaw.SetupEngine/GatewayPackageCleanup.cs:16 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: 62752f44cda2; files: src/OpenClaw.SetupEngine/GatewayPackageCleanup.cs)
  • Scott Hanselman: Raw commit adef8fc adds scripts/Test-ReleaseExecutableSignatures.ps1:27 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: adef8fcf30d7; files: scripts/Test-ReleaseExecutableSignatures.ps1)

Review metrics

Metric Value Why it matters
Production and test growth Production +144/-14 lines; tests +1635/-0 lines Most growth implements native visibility and enforcement observers needed to distinguish real execution from misleading proof outcomes.

Labels

Label changes:

No label changes.

Label justifications:

  • P2: Repeated desktop interruptions affect normal use, while the existing cleanup workflow remains functional.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

History

Review history (5 earlier review cycles)
  • reviewed 2026-10-20T18:17:48.282Z sha d9e30f1 :: needs real behavior proof before merge. :: none
  • reviewed 2026-10-21T22:58:55.617Z sha 4947736 :: needs real behavior proof before merge. :: none
  • reviewed 2026-10-22T03:29:11.806Z sha 4947736 :: needs real behavior proof before merge. :: none
  • reviewed 2026-10-22T07:33:24.039Z sha 4947736 :: needs real behavior proof before merge. :: [P2] Sign the cleanup executable before embedding it
  • reviewed 2026-10-22T08:23:56.588Z sha d3a9bc4 :: needs real behavior proof before merge. :: none

Reviewed October 23, 2026, 2:08 PM ET / 18:08 UTC (Revision 6).

@paulcam206
paulcam206 marked this pull request as ready for review October 21, 2026 17:55
@paulcam206

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

🦞👀
Exact review queued.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Oct 21, 2026
@paulcam206

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🦞👀
Exact review queued.

Re-review progress:

@paulcam206

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🦞👀
Exact review queued.

Re-review progress:

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. label Oct 22, 2026
@paulcam206

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🦞👀
Exact review queued.

Re-review progress:

@clawsweeper clawsweeper Bot removed the merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. label Oct 22, 2026
Record actual nullable native exits and window sample gaps on failure.
Require observer release, retain startup observations, and qualify the
scheduled signed host parent by executable path and creation identity.

Add native AppLocker capture with explicit callback errors, record-boundary
replay, policy-applied gating, and exact provider/channel/SID/rule evidence.
Add a proof worker that records handshake failures and handles successful
PowerShell workers without requiring a populated LASTEXITCODE.

Validation: 24/24 pure behavior cases; Framework native compilation;
four PowerShell parsers; full build.ps1 passed.
Shared: 4485 passed, 1 failed, 35 skipped. Failure is the MXC shell PATH
readonly-grant expectation under the current isolated host work path.
No assertions or budgets were relaxed.

Pending: isolated Tray tests, worker process integration, fresh native
AppLocker event qualification, signed-resource enforcing acceptance,
and actual uninstall-window proof. Event-loss cause remains unproven.
Local checkpoint only; all pushes held.
Keep exact event identity and unchanged observation deadlines. Reconcile readable records when live subscription notifications do not arrive, deduplicate replay, and propagate query failures. Native guest diagnosis showed readable 8001 records despite live waits expiring; parser and historical replay worked. Owned-path diagnostic later correlated 8001, 8002 and 8004. Final deadline guard is fail closed after reader I/O. Host validation: 27 focused cases passed; Framework native compile and full build passed; Shared 4486 passed, 35 skipped. Preserve earlier transient Shared fixture pending-outcome failure separately. Full current-head guest, Tray, signed cleanup and uninstall proof remain pending. Local only, all pushes held.
@paulcam206

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

🦞👀
Exact review queued.

Re-review progress:

@paulcam206

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

🦞👀
Exact review queued.

Re-review progress:

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant