Skip to content

fix(windows): verify scheduled task launch source#91486

Closed
xiaobao-k8s wants to merge 3 commits into
openclaw:mainfrom
xiaobao-k8s:fix/windows-scheduled-task-launch-proof
Closed

fix(windows): verify scheduled task launch source#91486
xiaobao-k8s wants to merge 3 commits into
openclaw:mainfrom
xiaobao-k8s:fix/windows-scheduled-task-launch-proof

Conversation

@xiaobao-k8s

Copy link
Copy Markdown
Contributor

Summary

Fix Windows Scheduled Task launch verification so an unrelated foreground gateway listener on the same port no longer counts as evidence that the managed Scheduled Task started.

Changes

  • Query raw schtasks /Query /TN ... /V /FO LIST state inside the launch fallback decision instead of reusing listener-backed runtime status.
  • Stop treating arbitrary gateway listener PIDs on the configured port as Scheduled Task launch evidence.
  • Normalize empty/default never-run Task Scheduler observations as stable not-yet-run, while still respecting real Last Run Time/status changes as launch progress.
  • Add regression coverage for the reported case: foreground listener exists, /Run is accepted, task never starts, fallback launcher still runs.

Real behavior proof

Behavior or issue addressed: After the fix, Windows gateway install/start/restart launch verification distinguishes Scheduled Task/script evidence from an unrelated foreground gateway listener, so an already-running foreground openclaw gateway listener cannot suppress the fallback launcher when schtasks /Run accepts but the task never starts.
Real environment tested: Repository openclaw/openclaw, worktree /datad/github/openclaw-issue91144, branch fix/windows-scheduled-task-launch-proof, commit d184b5c38b66, on Linux host running the project's daemon test suite with mocked Windows schtasks/process APIs.
Exact steps or command run after this patch:

git diff --check
pnpm exec oxlint src/daemon/schtasks.ts src/daemon/schtasks.startup-fallback.test.ts
OPENCLAW_TEST_FAST=1 node scripts/test-projects.mjs src/daemon/schtasks.startup-fallback.test.ts
OPENCLAW_TEST_FAST=1 node scripts/test-projects.mjs src/daemon/schtasks.test.ts
pnpm tsgo:core:test
OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 CI=1 PNPM_CONFIG_VERIFY_DEPS_BEFORE_RUN=false pnpm check:changed
pnpm deadcode:ci

Evidence after fix: Terminal output from the verification:

=== git diff --check ===

=== oxlint ===
Found 0 warnings and 0 errors.
Finished in 49ms on 2 files with 208 rules using 8 threads.

=== targeted startup fallback tests ===
✓ src/daemon/schtasks.startup-fallback.test.ts (28 tests)
Test Files  1 passed (1)
Tests  28 passed (28)
[test] passed 1 Vitest shard in 33.35s

=== targeted schtasks tests ===
✓ src/daemon/schtasks.test.ts (29 tests)
Test Files  1 passed (1)
Tests  29 passed (29)
[test] passed 1 Vitest shard in 33.30s

pnpm tsgo:core:test exited 0.

[check:changed] lanes=core, coreTests
[check:changed] src/daemon/schtasks.startup-fallback.test.ts: core test
[check:changed] src/daemon/schtasks.ts: core production
[check:changed] dependency pin guard
PASS direct dependency pin guard: checked 465 directly declared dependency specs across 155 tracked package manifests; 0 violations.
[check:changed] package patch guard
PASS package patch guard: no new pnpm patches; 4 legacy patches allowlisted.
[check:changed] lint core changed files
Found 0 warnings and 0 errors.
runtime-sidecar-loaders: local runtime sidecar loaders look OK.
Import cycle check: 0 runtime value cycle(s).
check:changed exited 0 in local child mode.

pnpm deadcode:ci exited 0.

Observed result after fix: The new regression test passes: when findVerifiedGatewayListenerPidsOnPortSync reports an existing gateway listener and mocked schtasks /Run never advances the Scheduled Task beyond never-run state, installScheduledTask still launches the Startup-style fallback instead of treating that listener as task launch evidence.
What was not tested: A native Windows live run with real Task Scheduler was not available in this environment; the PR includes source-level Windows lifecycle coverage using the repository's existing Windows schtasks mocks.

Test Plan

  • git diff --check
  • pnpm exec oxlint src/daemon/schtasks.ts src/daemon/schtasks.startup-fallback.test.ts
  • OPENCLAW_TEST_FAST=1 node scripts/test-projects.mjs src/daemon/schtasks.startup-fallback.test.ts
  • OPENCLAW_TEST_FAST=1 node scripts/test-projects.mjs src/daemon/schtasks.test.ts
  • pnpm tsgo:core:test
  • OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 CI=1 PNPM_CONFIG_VERIFY_DEPS_BEFORE_RUN=false pnpm check:changed
  • pnpm deadcode:ci

Note: plain pnpm check:changed delegated to Blacksmith Testbox on this machine but crabbox failed its local binary sanity check before running project checks, so I ran the project check in the same remote-child mode locally and it exited 0.

Risk

Low. The change is limited to the post-schtasks /Run launch-proof path. Listener-backed status reporting remains available for installed Startup fallback runtime status; only the launch fallback decision stops accepting an unrelated listener as task-start evidence.

Fixes #91144

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: S proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 8, 2026
@clawsweeper

clawsweeper Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 9, 2026, 1:48 AM ET / 05:48 UTC.

Summary
The PR changes Windows Scheduled Task launch fallback verification to query raw schtasks state, removes one listener-PID shortcut from launch evidence, and adjusts daemon tests/mocks.

PR surface: Source -2, Tests +84. Total +82 across 4 files.

Reproducibility: yes. at source level: the current and PR-head launch evidence paths can still count an existing foreground gateway process on the task port instead of proving the Scheduled Task or generated script started. Native Windows proof is still needed for the full Task Scheduler handoff.

Review metrics: none identified.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦪 silver shellfish
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Filter or baseline pre-existing foreground gateway process evidence before treating launch evidence as managed-task progress.
  • Clear or wait on the existing gateway port before the fallback launcher is treated as successful.
  • [P1] Add redacted native Windows Task Scheduler proof for install or restart with a foreground gateway, foreground closure, and successful managed gateway status.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR supplies mocked Linux daemon-test output, but no native Windows Task Scheduler terminal/log/screenshot proof shows the after-fix install or restart handoff; add redacted proof and update the PR body for re-review.

Risk before merge

  • [P1] A foreground gateway process visible in the Windows process snapshot can still be accepted as task launch evidence, leaving the linked availability bug unresolved.
  • [P2] The fallback launcher can be spawned while the foreground gateway still owns the configured port, so the managed fallback may fail to bind and disappear after the foreground window closes.
  • [P1] The PR body supplies mocked Linux daemon-test output only; native Windows Task Scheduler handoff proof is still missing for this external PR.

Maintainer options:

  1. Repair launch ownership and prove Windows (recommended)
    Filter baseline foreground process evidence, make fallback ownership of the port explicit, then require redacted native Windows Task Scheduler proof before merge.
  2. Accept source-only coverage deliberately
    Maintainers could merge with mocked coverage only, but that would leave the reported Windows availability handoff unproven.
  3. Pause behind the linked bug
    Hold this PR open or replace it with a maintainer-owned fix path if native Windows proof and the remaining ownership repair are not available here.

Next step before merge

  • [P1] Contributor or maintainer follow-up is needed because the remaining blockers require code-path repair plus native Windows proof that automation cannot supply for the contributor's setup.

Security
Cleared: No dependency, workflow, package, secret-handling, or third-party code-execution surface is changed by this daemon/test diff.

Review findings

  • [P2] Filter foreground gateways from launch proof — src/daemon/schtasks.ts:1104-1105
  • [P2] Prove the fallback owns the gateway port — src/daemon/schtasks.startup-fallback.test.ts:395
Review details

Best possible solution:

Make launch proof require the managed Scheduled Task/generated script or a baseline-new process, ensure the fallback owns or reaches the configured port, and add redacted native Windows proof for the install/restart handoff.

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

Yes at source level: the current and PR-head launch evidence paths can still count an existing foreground gateway process on the task port instead of proving the Scheduled Task or generated script started. Native Windows proof is still needed for the full Task Scheduler handoff.

Is this the best way to solve the issue?

No. Querying raw schtasks state is the right layer, but this is not the best fix until foreground process evidence is filtered/baselined, fallback port ownership is proven, and native Windows proof is supplied.

Full review comments:

  • [P2] Filter foreground gateways from launch proof — src/daemon/schtasks.ts:1104-1105
    After the raw schtasks observation path, hasLaunchEvidence still accepts any gateway argv whose parsed port matches the task port. A pre-existing foreground openclaw gateway --port 18789 can still make launch verification skip the fallback; snapshot a baseline before /Run or require generated task/script evidence.
    Confidence: 0.86
  • [P2] Prove the fallback owns the gateway port — src/daemon/schtasks.startup-fallback.test.ts:395
    The added regression expects fallback spawn while a verified listener is still present, but the fallback starts the same gateway command without --force or port cleanup. If the foreground process still owns the port, the fallback can fail to bind and no durable managed gateway remains after that window closes.
    Confidence: 0.84

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against e1978cf73cbd.

Label changes

Label justifications:

  • P2: The PR targets a real but platform-limited Windows gateway Scheduled Task availability bug with a foreground workaround.
  • merge-risk: 🚨 availability: The diff changes gateway launch fallback behavior, and the current path can still leave the managed gateway unavailable after install/start/restart.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR supplies mocked Linux daemon-test output, but no native Windows Task Scheduler terminal/log/screenshot proof shows the after-fix install or restart handoff; add redacted proof and update the PR body for re-review.
Evidence reviewed

PR surface:

Source -2, Tests +84. Total +82 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 1 22 24 -2
Tests 3 88 4 +84
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 110 28 +82

What I checked:

  • Repository policy: Root AGENTS.md was read fully; its PR review, Windows startup/fallback, and external real-behavior proof guidance affected this verdict. (AGENTS.md:1, e1978cf73cbd)
  • PR head still accepts foreground process evidence: After the raw schtasks observation change, hasLaunchEvidence still returns true for any gateway argv on the task port, so a pre-existing foreground gateway process can still suppress fallback launch. (src/daemon/schtasks.ts:1104, 9f78da5ae10b)
  • Fallback spawn does not clear the port: launchFallbackTaskScript spawns the installed gateway command as-is; it does not add --force, terminate the foreground gateway, or wait for the configured port to become bindable. (src/daemon/schtasks.ts:481, e1978cf73cbd)
  • Supported port cleanup path is explicit: Gateway --force is the path that kills listeners and waits for bindability before startup; the fallback launch path does not use that option. (src/cli/gateway-cli/run.ts:595, e1978cf73cbd)
  • Added regression is too weak: The new test asserts only that fallback was spawned while a listener is mocked; it does not prove the spawned managed gateway can bind, answer health/RPC, or survive after the foreground window closes. (src/daemon/schtasks.startup-fallback.test.ts:387, 9f78da5ae10b)
  • Documented Windows behavior: Windows managed startup is documented as using Scheduled Tasks when available and falling back to a Startup-folder login item when task creation is denied, so a managed gateway should not depend on a visible foreground window. Public docs: docs/platforms/windows.md. (docs/platforms/windows.md:124, e1978cf73cbd)

Likely related people:

  • steipete: Recent commit history shows repeated Windows daemon lifecycle, startup fallback, daemon docs, and gateway port handling work in the central files. (role: recent area contributor; confidence: high; commits: 433e65711f78, 32d8ec948262, 5ea03efe92d6; files: src/daemon/schtasks.ts, src/daemon/schtasks.startup-fallback.test.ts, src/cli/gateway-cli/run.ts)
  • vincentkoc: Recent history includes deduping schtasks startup fallback helpers and the local shallow blame currently attributes the central schtasks file to a recent repo-wide test release commit. (role: adjacent test/runtime contributor; confidence: medium; commits: ffd517b513fe, 50130d32a997; files: src/daemon/schtasks.startup-fallback.test.ts, src/daemon/schtasks.ts)
  • giodl73-repo: Authored recent Windows node/gateway Scheduled Task cleanup work that shares the listener-ownership and startup-fallback invariant. (role: recent Windows daemon contributor; confidence: medium; commits: a4e0b6ef472b; files: src/daemon/schtasks.ts, src/daemon/schtasks.startup-fallback.test.ts, src/daemon/schtasks.stop.test.ts)
  • tmimmanuel: Authored recent Windows Scheduled Task restart/install behavior work touching the same lifecycle surface. (role: adjacent lifecycle contributor; confidence: medium; commits: 0fef95b17d72; files: src/daemon/schtasks.ts, src/daemon/schtasks.startup-fallback.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels Jun 8, 2026
@xiaobao-k8s

Copy link
Copy Markdown
Contributor Author

Thanks for the review. This PR requires real Windows Task Scheduler validation, but I don't currently have access to a suitable Windows environment to provide the requested real-behavior proof.

To avoid keeping an unmergeable PR open, I'm closing this for now. I'm happy to reopen or submit a refreshed PR if I can get access to a real Windows setup later.

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

Labels

gateway Gateway runtime merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

1 participant