Skip to content

fix(release): stop Windows package descendants after timeout#111956

Merged
steipete merged 4 commits into
openclaw:mainfrom
TheAngryPit:codex/windows-package-runner-tree-timeout
Jul 25, 2026
Merged

fix(release): stop Windows package descendants after timeout#111956
steipete merged 4 commits into
openclaw:mainfrom
TheAngryPit:codex/windows-package-runner-tree-timeout

Conversation

@TheAngryPit

@TheAngryPit TheAngryPit commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Closes #111948

What Problem This Solves

Windows release and CI workflows using the Docker package helper could resolve npm/pnpm command shims inconsistently or leave a descendant process alive after a timed-out package step.

Why This Change Was Made

The package helper uses OpenClaw's existing cross-platform npm/pnpm runners and canonical managed-child termination helper. This keeps command resolution and timeout cleanup at the existing ownership boundary without adding dependencies or another Windows process implementation.

The change is limited to the package helper and its E2E coverage. It does not alter package contents, release policy, timeout values, or the managed-child helper itself.

User Impact

Windows packaging honors its timeout contract across real .cmd process trees. Developers and CI jobs should not retain a pnpm.cmd -> node descendant after the package command times out.

Evidence

  • Frozen reviewed base: upstream main at b9a28cde42872cfe13051ddd8f1667e34bf59b17.
  • Exact tested head: 070527ddfe32f0156a6258a638e226f731458ecd.
  • Scope: 3 files, +130/-14; no dependency or lockfile changes.
  • Host toolchain: Node 24.18.0, pnpm 11.2.2.
  • Direct module smoke proved terminateManagedChild imports as a function.
  • Managed-child suite: 8 passed, 1 platform skip.
  • Package helper E2E: 30 passed, 1 platform skip.
  • Windows regression uses a real pnpm.cmd -> node process tree, records the descendant PID, triggers timeout, and proves that PID is absent afterward.
  • Unit coverage verifies taskkill /PID <pid> /T, forced /T /F, and child-only fallback only after taskkill failure.
  • tsgo:scripts and tsgo:test:root: passed.
  • Script declarations: all 241 contracts matched.
  • A clean host-owned exact-head lane corrected an earlier sandbox-only 120s timeout followed by EPERM: the restricted process boundary prevented the real Windows taskkill /T cleanup from completing. Identical relevant source across the prior passing head and rebased head, followed by the passing real .cmd -> node E2E, classified this as proof-lane tooling rather than a product regression.
  • Final context-complete scoped Auto-review on this exact head: no accepted/actionable findings; verdict patch is correct, confidence 0.96.

Proof level: test_proven in a fresh exact-head repository clone. Public CI on the published head remains the merge gate; this does not claim package publication or operator-runtime proof.

AI-assisted implementation and review. Maintainer edits are welcome.

Security Impact

No secret, permission, download, dependency, lockfile, workflow, or package-publishing surface is added. The change narrows timeout cleanup to existing shared process-management helpers.

Compatibility And Migration

No migration is required. npm/pnpm resolution remains platform-aware through existing repository helpers; timeout values and package output remain unchanged.

Review Conversations

  • Rejected Auto-review P1: terminateManagedChild is explicitly exported from scripts/lib/managed-child-process.mjs, imported by the package helper, and imported successfully in a fresh-clone smoke test.
  • Rejected Auto-review P1: Windows termination does not rely only on child.kill(signal); it uses taskkill /PID <pid> /T, escalates with /F, and falls back to child.kill only after taskkill failure. Unit and real .cmd -> node E2E coverage prove the path.
  • Source and tests falsified both claims. After the final frozen-base rebase, scoped Auto-review was rerun and returned no accepted/actionable findings on the exact tested head.
  • No unresolved inline review threads were present at publication preflight.

Agent Transcript

Bounded redacted operator/agent timeline
  • Operator decision: keep this as a narrow Core packaging fix, separate from Companion/runtime work, and publish only after exact-source validation and fresh package/type gates.
  • Failed-first evidence: the original timeout path could leave a real pnpm.cmd -> node descendant alive. Earlier implementation review also found resolver-provided environment changes needed to be preserved by the package helper.
  • Fix: route npm/pnpm through existing cross-platform runners and terminate managed process trees through the canonical helper. The E2E fixture was corrected to include the helper modules imported by production code.
  • Tests: a fresh exact-head clone passed direct export smoke, managed-child unit coverage, package-helper E2E, both script/root type lanes, and all 241 script declarations under Node 24.18.0 and pnpm 11.2.2. An earlier sandbox-only timeout/EPERM was reproduced and isolated to the restricted process boundary, then corrected in a clean host-owned proof lane.
  • Review: two later P1 claims were rejected with direct source and test evidence: the helper is exported, and Windows uses taskkill /T with /F escalation before child-only fallback. Final frozen-head Auto-review returned no accepted/actionable findings on 070527ddfe32f0156a6258a638e226f731458ecd.
  • Boundary: proof is local and test_proven; public CI and maintainer review remain outstanding after publication. No package was published and no operator runtime was mutated.

Generated from local session history with openclaw-agent-transcript, then bounded and redacted. No secrets, credentials, raw logs, private prompts, local paths, or operator data are included.

@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts docker Docker and sandbox tooling size: S labels Jul 20, 2026
@TheAngryPit
TheAngryPit force-pushed the codex/windows-package-runner-tree-timeout branch from 125a76d to 7f7b2f6 Compare July 21, 2026 00:17

Copy link
Copy Markdown
Contributor Author

Current-main refresh and type-contract correction

Exact head: 7f7b2f65f6d4034444dc090fdddc8e167fa086a0

  • Rebased cleanly onto upstream main at 2220e9f8418.
  • The rebase reproduced the CI TS18046 failure: the canonical declaration exposed runCommandForTest as Promise<unknown> while the runtime contract returns command stdout as a string.
  • The declaration now matches the runtime contract; no dependency or lockfile changed.
  • Direct type lanes passed for core tests, extensions tests, root tests, and scripts.
  • Package helper E2E: 30/30 passed with one platform skip.
  • Fresh three-file scoped Auto-review: no accepted/actionable findings, patch is correct, confidence 0.90.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels Jul 21, 2026
@clawsweeper

clawsweeper Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 25, 2026, 5:03 AM ET / 09:03 UTC.

ClawSweeper review

What this changes

The branch resolves Windows npm and pnpm package commands through the shared runners, uses shared process-tree cleanup after package-step timeouts, and adds Windows coverage for the real command-shim descendant path.

Merge readiness

⚠️ Ready for maintainer review - 2 items remain

Keep this PR open for maintainer merge review. It is the active candidate fix for #111948, has maintainer engagement and current-head CI in progress, and its implementation reuses the repository’s existing Windows command-resolution and managed-child termination boundaries rather than adding a parallel process implementation. No concrete patch defect was found from the supplied exact-head diff and evidence. Likely related people: steipete (high confidence, recent area changes and assignee) and CassieMei (medium confidence, earlier implementation commits on this repair).

Priority: P2
Reviewed head: f4443d29017ee537b3cf0ff933595be086b2682d

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) The patch is focused, follows existing process-management boundaries, and has strong real Windows regression evidence; the remaining merge gate is the running exact-head Windows CI lane.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (terminal): The supplied PR body and successful Real behavior proof check describe and validate an after-fix Windows pnpm.cmd-to-Node descendant timeout path, including independent PID disappearance; the latest head only adds that E2E to Windows CI coverage.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (terminal): The supplied PR body and successful Real behavior proof check describe and validate an after-fix Windows pnpm.cmd-to-Node descendant timeout path, including independent PID disappearance; the latest head only adds that E2E to Windows CI coverage.
Evidence reviewed 5 items Current branch implementation: The PR changes the package helper to select resolvePnpmRunner or resolveNpmRunner only on Windows, preserve runner-provided environment and spawn options, and call terminateManagedChild for timeout cleanup. This is the existing ownership boundary described by the linked issue.
Regression coverage: The branch adds a Windows-only E2E case that launches a real pnpm.cmd-to-Node descendant, forces a timeout, records the descendant PID, and asserts that the PID is gone; it also adds that E2E file to the Windows CI package-script list.
Current-head proof and CI state: The supplied PR context records successful real-behavior proof and focused fresh-clone Windows process-tree evidence. The latest head adds the E2E file to the Windows CI list; the exact-head Windows check is still running, so merge should remain gated on that result.
Findings None None.
Security None None.

How this fits together

The Docker package helper launches npm or pnpm while assembling OpenClaw’s package artifacts for release and CI. It must resolve the platform-specific command correctly, capture command output, and stop every managed descendant before returning a timeout failure.

flowchart LR
  A[Release or CI package step] --> B[Docker package helper]
  B --> C[Windows npm or pnpm runner]
  C --> D[Spawned command shim]
  D --> E[Node descendant process]
  E --> F{Package step times out?}
  F -->|Yes| G[Managed process-tree termination]
  F -->|No| H[Package output and completion]
  G --> I[Timeout failure returned to CI]
Loading

Before merge

  • Resolve merge risk (P1) - Windows npm/pnpm resolution intentionally changes from direct spawning to the shared runner contract; the final exact-head Windows CI lane should pass before merge so command lookup and shim arguments are exercised in the target environment.
  • Resolve merge risk (P2) - Timeout cleanup intentionally becomes process-tree termination; merge should remain gated on the exact-head Windows regression so the helper stops the intended descendant tree without leaving packaging jobs stalled.
Agent review details

Security

None.

PR surface

Tests +104, Config 0, Other +5. Total +109 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 2 106 2 +104
Docs 0 0 0 0
Config 1 1 1 0
Generated 0 0 0 0
Other 2 17 12 +5
Total 5 124 15 +109

Review metrics

Metric Value Why it matters
Windows timeout contract coverage 1 real process-tree E2E added to Windows CI The branch promotes the pnpm.cmd-to-Node timeout case from focused coverage into the repository’s Windows CI package-test list.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #111948
Summary: This PR is the active candidate fix for the Windows package-helper timeout bug; the other provided cross-references are unrelated tracker material.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge-risk options

Maintainer options:

  1. Gate on the current Windows run (recommended)
    Merge after the exact-head Windows package-test lane passes, confirming that the shared runner preserves command resolution while the managed-child helper removes the timed-out descendant tree.
  2. Pause if the Windows regression is unstable
    If the current-head Windows regression flakes or leaves a descendant alive, pause this PR and narrow the failure before accepting a process-management behavior change.

Technical review

Best possible solution:

Land the narrow shared-runner and managed-child-helper fix after the running exact-head Windows CI check passes, retaining the real pnpm.cmd-to-Node timeout regression as the long-term contract.

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

Yes, from source and supplied proof: on Windows, run the Docker package helper against a pnpm.cmd shim that starts a long-lived Node child, impose a short timeout, and verify the recorded descendant PID exits. The PR’s E2E coverage encodes that path, although this read-only review did not execute it.

Is this the best way to solve the issue?

Yes. Reusing the existing npm/pnpm runners and managed-child termination helper keeps command resolution and timeout cleanup at their established ownership boundaries, avoiding a separate Windows process-management implementation.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against aba0b12014a3.

Labels

Label justifications:

  • P2: This is a bounded Windows release and CI reliability fix; it can leak package-process descendants but does not make the core runtime unusable.
  • merge-risk: 🚨 compatibility: Windows npm and pnpm invocation now flows through shared runner resolution rather than direct spawning, so existing shim and environment behavior must remain compatible.
  • merge-risk: 🚨 availability: The patch changes timeout cleanup from direct-child killing to managed process-tree termination, which directly affects whether packaging jobs recover or remain blocked.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The supplied PR body and successful Real behavior proof check describe and validate an after-fix Windows pnpm.cmd-to-Node descendant timeout path, including independent PID disappearance; the latest head only adds that E2E to Windows CI coverage.
  • proof: sufficient: Contributor real behavior proof is sufficient. The supplied PR body and successful Real behavior proof check describe and validate an after-fix Windows pnpm.cmd-to-Node descendant timeout path, including independent PID disappearance; the latest head only adds that E2E to Windows CI coverage.

Evidence

What I checked:

  • Current branch implementation: The PR changes the package helper to select resolvePnpmRunner or resolveNpmRunner only on Windows, preserve runner-provided environment and spawn options, and call terminateManagedChild for timeout cleanup. This is the existing ownership boundary described by the linked issue. (scripts/package-openclaw-for-docker.mjs:221, f4443d29017e)
  • Regression coverage: The branch adds a Windows-only E2E case that launches a real pnpm.cmd-to-Node descendant, forces a timeout, records the descendant PID, and asserts that the PID is gone; it also adds that E2E file to the Windows CI package-script list. (test/e2e/qa-lab/runtime/package-openclaw-for-docker.e2e.test.ts:87, f4443d29017e)
  • Current-head proof and CI state: The supplied PR context records successful real-behavior proof and focused fresh-clone Windows process-tree evidence. The latest head adds the E2E file to the Windows CI list; the exact-head Windows check is still running, so merge should remain gated on that result. (package.json:1847, f4443d29017e)
  • Feature history from supplied pull commits: The repair was introduced in commit 02a3ddd, then narrowed to Windows-only runner normalization in d95611f and wired into Windows CI in the current-head commit. (scripts/package-openclaw-for-docker.mjs:221, d95611f538fb)
  • Prior ClawSweeper continuity: The prior completed review at 7f7b2f6 had no findings. The supplied history shows later changes were type-contract correction, Windows-only scoping, and Windows-CI coverage; no prior blocker remains to re-raise. (scripts/package-openclaw-for-docker.d.mts:42, f4443d29017e)

Likely related people:

  • steipete: The current PR includes steipete-authored commits that scope the runner normalization to Windows and add the Windows CI coverage; the timeline also records assignment to steipete. (role: recent area contributor and assigned reviewer; confidence: high; commits: d95611f538fb, f4443d29017e; files: scripts/package-openclaw-for-docker.mjs, package.json, test/package-scripts.test.ts)
  • CassieMei: The supplied pull-commit history credits CassieMei with the initial Windows package-command-tree repair and the matching test declaration correction. (role: initial repair contributor; confidence: medium; commits: 02a3dddcea4e, b4e58221569c; files: scripts/package-openclaw-for-docker.mjs, scripts/package-openclaw-for-docker.d.mts)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Wait for the current-head Windows package-test check to complete successfully before merge.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • 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.

History

Review history (1 earlier review cycle)
  • reviewed 2026-07-21T00:21:27.994Z sha 7f7b2f6 :: needs maintainer review before merge. :: none

@TheAngryPit

Copy link
Copy Markdown
Contributor Author

Exact-head publication update

  • Published head: 04813a97f29afd45ee026017648a53b047d26efd
  • Reviewed base: 988e640c7a248b15ee26930dce3699a36c5c5078
  • Fresh proof: direct export smoke, managed-child 8 passed / 1 platform skip, package E2E 30 passed / 1 platform skip, both type lanes, and all 239 script declarations passed.
  • Two P1 review claims were rejected by direct evidence: terminateManagedChild is exported, and Windows uses taskkill /T with /F escalation before child-only fallback.
  • No code changed after those findings, so no redundant Auto-review was started.
  • Public CI and maintainer review remain the merge boundary. No package publication or operator-runtime mutation was performed.

The PR body now contains the bounded redacted agent transcript and full evidence map. No manual ClawSweeper re-review command was issued.

@TheAngryPit
TheAngryPit force-pushed the codex/windows-package-runner-tree-timeout branch from 04813a9 to 070527d Compare July 23, 2026 07:52

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@steipete steipete self-assigned this Jul 25, 2026
@steipete
steipete force-pushed the codex/windows-package-runner-tree-timeout branch from d4e05a6 to d95611f Compare July 25, 2026 08:50
@steipete

Copy link
Copy Markdown
Contributor

Maintainer rewrite and exact-head proof are complete for f4443d29017ee537b3cf0ff933595be086b2682d.

The defect is present on current main at the package helper's timeout boundary: Windows disables process groups, falls back to direct child.kill, and treats group liveness as false, so descendants are never targeted. The branch now keeps the package helper's specialized timeout/output state machine, delegates tree cleanup to terminateManagedChild, and resolves npm/pnpm through the existing runners only on Windows. It also adds the real process-tree E2E to the permanent Windows CI shard.

Proof:

ClawSweeper's current rank-up move and both merge-risk gates are satisfied by the exact-head Windows and aggregate CI results. Contributor authorship remains preserved in the original commits.

@steipete
steipete merged commit 2296e89 into openclaw:main Jul 25, 2026
102 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Merged via squash.

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

Labels

docker Docker and sandbox tooling merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. scripts Repository scripts size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Windows package timeout can leave command-shim descendants running

3 participants