fix: preserve Core updates across restart timeouts - #1181
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. |
|
Codex review: needs maintainer review before merge. Reviewed August 21, 2026, 4:48 PM ET / 20:48 UTC. ClawSweeper reviewWhat this changesThe branch carries a WSL command timeout through gateway restart recovery so an ambiguous timeout skips forced distro termination while confirmed failures still cold-restart. Merge readinessThis PR remains necessary: current main still collapses a WSL timeout into ordinary failure and then force-terminates the distro. The focused patch preserves definitive-failure recovery, has no blocking correctness findings, and the updated real Windows/WSL proof is sufficient. Priority: P2 Review scores
Verification
Live VerificationCommand: Result: FAIL (failed) — execution before step 1 Assertions:
How this fits togetherThe tray’s managed-local gateway repair restarts an app-owned WSL gateway after a verified transport failure. Its restart result determines whether the repair coordinator reconnects normally or performs a destructive cold restart of the distro. flowchart LR
A[Core update handoff] --> B[Gateway repair monitor]
B --> C[In-distro gateway restart]
C --> D{Restart result}
D -->|Confirmed failure| E[Terminate and cold restart]
D -->|Timed out| F[Wait for later recovery]
E --> G[Gateway reconnect]
F --> G
Before merge
Agent review detailsSecurityNone. Review metrics
Merge-risk optionsMaintainer options:
Technical reviewBest possible solution: Keep timeout as an explicit indeterminate outcome, reserve cold restart for confirmed failures, and let the existing bounded repair monitor observe later recovery. Do we have a high-confidence way to reproduce the issue? Yes. Current main still routes any unsuccessful in-distro restart to force termination, and the contributor supplied a current-head real WSL 2 before-and-after recovery run for that exact path. Is this the best way to solve the issue? Yes. Propagating an explicit timeout state at the WSL runner boundary is the narrowest maintainable way to distinguish unknown completion from a confirmed restart failure. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against d3ed6c78bf14. LabelsLabel changes:
Label justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (1 earlier review cycle)
|
Exact-head real Windows/WSL recovery proof (
|
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
Related: openclaw/openclaw#99666
What Problem This Solves
Fixes an issue where the Windows Companion could interrupt a supported OpenClaw Core update when its automatic gateway repair timed out. After waiting 30 seconds for an in-distro restart, the Companion treated the timeout as a definitive failure and terminated the entire WSL distro, killing the detached Core updater.
Why This Change Was Made
The WSL command runner now carries an explicit timeout result through the gateway controller. Automatic repair treats that result as indeterminate and skips forced distro termination. Definitive non-timeout restart failures retain the existing terminate-and-cold-restart recovery path.
This stays on the Windows Companion boundary. Core already owns the managed-service update handoff and its parent wait budget; the destructive escalation happened later in the external Windows supervisor.
User Impact
Long-running Core updates are no longer killed merely because the Companion's host-side restart wait expired. Users still retain automatic recovery when an in-distro restart fails definitively.
Evidence
Observed before the fix:
21:02:57: Core acceptedupdate.runand started the managed-service handoff.21:03:21: Companion auto-repair invoked an in-distro gateway restart.21:03:51: the 30-second wait timed out and Companion invokedwsl.exe --terminate, killing the detached updater.FETCH_HEADadvanced.The regression test now proves that a timed-out in-place restart makes zero terminate calls, while existing tests continue to prove that a definitive failure performs the terminate-and-cold-restart path.
Change Type
Scope
winnodeValidation
dotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --no-restore --filter "FullyQualifiedName~WslGatewayControllerTests": 11 passed, 0 failed, 0 skipped..\build.ps1: all 5 projects built; 46 documentation files validated.dotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restore: 3,698 passed, 0 failed, 32 intentional environment/integration skips.dotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --no-restore: 2,621 passed, 0 failed, 0 skipped.git diff --check: clean apart from Git line-ending conversion notices.Real Behavior Proof
origin/main12b84457a46492b8e3f4df99ea1ea17370f75992.e4dd1735b47eb7cadc19e0c73e9fea1c93d87e09.test_provenfor the timeout decision and preserved definitive-failure path.Yes/No/N/A): N/A.runtime_provenorend_to_end_proven.Security Impact
Yes/No): No.Yes/No): No.Yes/No): No.Yes/No): Yes.Yes/No): No.Yes, explain the risk and mitigation: automatic repair no longer invokes the destructive host-side terminate command after an ambiguous timeout. The existing forced recovery remains available after a definitive non-timeout failure.Compatibility and Migration
Yes/No): Yes.Yes/No): No.Yes/No): No.Review Conversations