Repository navigation
Conversation
Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs real behavior proof before merge. What this changesThis PR restricts automatic WSL rollback cleanup to the current creation attempt and a matching live registration, while preserving explicit uninstall. Example: OpenClawGateway already exists when the create step starts and rollback is enabled.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness⛔ Blocked before merge - 3 items remain Keep this PR open: it repairs a current data-loss path, follows explicit maintainer direction, and addresses the earlier code findings. Priority: P0 Before merge
Findings
Tests
Agent review detailsHow this fits togetherSetupPipeline invokes CreateWslInstanceStep during WSL provisioning and failure rollback; the step uses persisted ownership evidence, current-user WSL registration metadata, and command results to authorize unregister and filesystem cleanup. flowchart TD
A[SetupPipeline] --> B[CreateWslInstanceStep]
B --> C[Current attempt guard]
C --> D[ManagedDistroOwnership]
D --> E[Live WSL registration]
E --> F[Targeted unregister]
F --> G[Managed directory cleanup]
Technical reviewBest possible solution: Land the approved narrow repair after validating automatic rollback and consented teardown through their actual production paths. Do we have a high-confidence way to reproduce the issue? Current main's create step refuses an existing distro, then SetupPipeline invokes failed-step rollback, whose cleanup unregisters that name without proving this attempt owns it; no target code was executed during this read-only review. Is this the best way to solve the issue? The attempt guard and reuse of ManagedDistroOwnership address the stated cause at the existing owner, preserve explicit uninstall, and match the maintainer's requested scope. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 817b0b586c1e. Merge-risk optionsMaintainer options:
Provenance checked
TestingProof path: in-process harness. SecurityNeeds attention: No introduced exploit was established, but the destructive retry boundary still needs final-effect authority evidence. EvidenceSecurity concerns:
What I checked:
Likely related people:
Review metrics
LabelsLabel changes: No label changes. Label justifications:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale6/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. WorkflowClawSweeper edits this one comment on every review. Comment HistoryReview history (10 earlier review cycles; latest 8 shown)
Reviewed October 13, 2026, 8:51 PM ET / October 14, 2026, 00:51 UTC (Revision 11). |
|
Thanks, Seb. This is a useful narrowing of a real data-loss path, and I want to land it on your PR rather than replace it. Reviewed head: One ownership gap remains in Please keep the repair small:
The existing architecture ledger already states the live-registration invariant, so this should use the current owner rather than add a parallel policy. After that, the remaining gate is isolated real Windows/WSL rollback proof, not a larger redesign. |
|
Global triage: HOLD_FOR_AUTHOR. Take confidence 40%; recommendation confidence 90%; effort small-to-moderate; risk high. Reviewed exact head |
…es this install A path marker from an earlier attempt is not enough. Failed setup cleanup now requires the current WSL registration base path before terminate or unregister. Consented uninstall is unchanged. Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
Consented uninstall still unregisters when wsl --list fails. Automatic rollback unregisters only after this run started the install and the live base path matches. Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
|
Thanks for the two follow-ups. At One adjacent deletion path still bypasses the new attempt guard:
This is pre-existing behavior left open by the narrowing, not a new regression. Please extend the no-authority-before-this-attempt rule to directory/marker cleanup as well as unregister. A top-level automatic-cleanup guard before the attempt owns creation is a small option; explicit uninstall consent remains separate. Add the regression “nonempty orphan directory refused by Execute, then rollback preserves it.” I am not asking for a new registration-GUID ownership architecture or a broad redesign. The immediate requirement is that refusing unknown pre-existing state must not be followed by deleting that state during automatic rollback. |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: bdf13a3c-c9a5-4844-8c6f-c2253c403c2e
Guard rollback before this execution starts WSL creation, preserving preexisting directories, markers, and empty parents. Reset attempt authority on reuse while retaining explicit uninstall and live-registration cleanup checks. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: bdf13a3c-c9a5-4844-8c6f-c2253c403c2e
Uninstall called terminate and unregister even after --list --quiet proved the distro was absent. A refused unregister also deleted the ownership marker when the install directory was already gone, so a surviving same-name registration lost its recovery record. Known-absent uninstall now skips unregister. A refusal while the registration still exists keeps the marker. Unknown and present registrations still use the existing unregister attempt. Tests: CreateWslInstance cleanup filter 9 passed. ./build.ps1 exit 0. Shared 4099 passed, 32 skipped. Tray 3064 passed. Five source contract tests still fail on an LF checkout because they expect CRLF snippets. Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
|
Global triage: HOLD_FOR_AUTHOR. Take confidence 10%; recommendation confidence 99%; effort small; risk high. Reviewed exact head Author: update from current main, resolve conflicts or branch-policy blockers, then rerun exact-head validation and request review. This is a triage classification, not a merge action. No branch changes were made. |
GitHub reported this pull blocked on an old setup E2E run. The merge with current main is clean. Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
|
Global triage: HOLD_FOR_AUTHOR. Take confidence 20%; recommendation confidence 96%; effort medium; risk high. Reviewed exact head Author: ownership-gate uninstall and every retry (or explicitly narrow the product contract), then provide current-head owned rollback, foreign/pre-existing preservation, reassignment-before-retry, and signed installer/uninstall proof. No fixes or branch changes were made by this review. |
What Problem
If the target distro name was already registered, create returned failure before writing an ownership marker. Rollback still ran wsl --unregister for that name. A failed wsl --list still attempted unregister.
Why
Rollback is on by default. A pre-existing distro was removed.
User Impact
Unregister now happens only when the ownership marker matches this install path. An already-registered name is left alone. A failed list does not unregister.
Maintainer clarification: automatic unregister also retains the author's live-registration BasePath and current-attempt checks. Automatic rollback now preserves the install directory, ownership marker, and empty parent when this execution never started creating the distro. Reusing the step does not inherit cleanup authority. Explicit, consented uninstall remains separate.
Evidence
Current head
50f93e89d481f6c1041e832f7ce4cc0ffe8ca642.CleanupStaleDistroStepran in an isolated data directory. The only distro it was allowed to name wasOpenClawProof1479.Ubuntu-24.04andOpenClawGatewaywere registered before both runs and after both runs.Foreign registration: that disposable distro was imported outside the managed install path, while
setup-managed-distro.jsonnamed the same distro at the managed path. The step returnedFailedTerminal: the live registration is bound to a different base path, and the distro was preserved. It did not callwsl --terminateorwsl --unregister. AKEEP.txtfile on the foreign directory was still there, andwsl --list --quietstill listedOpenClawProof1479. That refusal returns before either unregister attempt, so the retry cannot reach a registration this install does not own.Owned registration: the same name was then imported at the managed path with a matching marker. The step terminated
OpenClawProof1479, andwsl --unregister OpenClawProof1479exited 0. The list that followed contained onlyUbuntu-24.04andOpenClawGateway. The first unregister succeeded, so the retry branch did not run.The Setup and connect E2E job on this head was cancelled earlier and was not rerun.
Original author evidence, before the maintainer follow-up:
Red: two tests failed because --unregister ran for an existing distro and after a failed list. Green: the WSL-create filter passed 16. Setup-engine suite 1193 passed. The host wsl --version UTF-16 test failed and does not touch this change. .\build.ps1 passed.
Maintainer follow-up
Preserved the original contributor PR, branch, and all three author commits through
08e10063f5c3ed9ce1d6fd197f0da9c62a534a2c. Normally merged main42c562f91a42ae0251ac971c44f6ce0f8028e88din7ab2cca5f3c6c767173d407f5ac18983e55c02ab, then added one repair commit,e1abdb5dc2abc33114bb19964a407886f43684de, and nonforce-pushed the original branch.The repair adds 10 production lines at the existing
CreateWslInstanceStepboundary, focused regressions, and 8 documentation lines. No registration-GUID framework, unrelated install-path rewrite, or workflow changes.Required proof pools
windows-wsl-gateway-e2e: real WSL creation and automatic rollback behavior. Not verified / blocked on the shared host; no runtime-proof authorization.windows-clean-installer-upgrade: signed installer/uninstall integration with the shared teardown path. Not verified / blocked; no disposable signed-artifact installer proof performed.Validation
Repair head:
e1abdb5dc2abc33114bb19964a407886f43684de. Validated source tree:0e3c32052ee2458bb7021b05c546647165cb1dd7(unchanged when committed). Native Windows ARM64, task-private .NET SDK10.0.400.Process-local isolation set
OPENCLAW_REPO_ROOTto the isolated worktree and uniqueOPENCLAW_TRAY_DATA_DIR/OPENCLAW_TRAY_APPDATA_DIR; unset fixture-conflicting state/local-data overrides and E2E/integration flags. Explicitly built each test project first to prevent fresh-worktree--no-restoreno-ops..\build.ps1dotnet build .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --nologo -v minimaldotnet build .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --nologo -v minimaldotnet build .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj --nologo -v minimaldotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --no-restoredotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --no-restoredotnet test .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj --no-restoredotnet test .\tests\OpenClaw.SetupEngine.Tests\OpenClaw.SetupEngine.Tests.csproj --no-restore --filter 'FullyQualifiedName~CreateWslInstance|FullyQualifiedName~UninstallPipeline_RemovesSafeLegacyDistro'All test runs also supplied
--logger 'trx;LogFileName=<suite>.trx' --results-directory '<session-artifacts>\results'. Full-suite files areShared.trx,Tray.trx, andSetupEngine.trx; focused proof isgreen-rollback.trx. Actual TRX counters were checked. The unchangedCommandRunnerTests.RunAsync_WslVersion_DecodesOutputBeforeLoggingpassed: only its exact read-onlywsl.exe --versionmetadata invocation was authorized. No tests were filtered out of the full SetupEngine suite. Its one skip requires a separately configured volume; Shared skips remain the existing integration/hardware gates.Focused rubber-duck review: no blockers. Conservative preservation if setup stops between marker writing and install start is intentional; cleanup authority was not moved earlier to remove a harmless leftover marker. Existing defensive unregister checks were retained.
Exact-commit structured autoreview:
python .\.agents\skills\autoreview\scripts\autoreview --mode commit --commit e1abdb5dc2abc33114bb19964a407886f43684de --engine codex --codex-bin <verified-private-Codex-0.156.1>with the bounded repair context and saved text/JSON outputs.gpt-5.6-sol, high reasoning; exit 0, no findings, no accepted/actionable issues. This is source-review evidence, not merge confidence or a runtime-gate waiver.Real behavior proof
Current head
4422ba5357007afbc9ff1c159fa614d45db25ad1, 2026-09-27../build.ps1exit 0. Shared 4099 passed, 32 skipped. Tray 3064 passed. Five source-contract tests failed on this LF checkout because they look for CRLF snippets in files this change does not touch. Focused cleanup tests 9 passed.Uninstall whose
--list --quietalready excludes the distro does not call--terminateor--unregister. When the same-name registration survives and the install directory is already absent, the ownership marker stays and unregister is not called. A failed list during uninstall still unregisters.Not verified / blocked: a live
wsl --unregisteron this head. The counts above the next paragraph are the parent heade1abdb5dc2abc33114bb19964a407886f43684de.The fake command log shows --unregister is absent when the distro already existed. Not verified: no live wsl --unregister.
The maintainer regression executes production
ExecuteAsyncand both directRollbackAsyncand realSetupPipeline.RunAsyncrollback orchestration against actual task-owned temporary directories and marker files. WSL/process calls are faked, not executed.red-rollback.trx: 5 failed, 0 passed).--list --quietcall occurs. A warning explicitly reports preservation.Not verified / blocked: live Windows/WSL setup, distro creation or unregister, real VHD behavior, full Gateway/MXC E2E, WinUI interaction, and signed installer/uninstall/upgrade pools. No existing distro, service, probe, or normal installed app was manipulated. Temporary-filesystem and fake-process proof does not satisfy these runtime pools; merge remains a separately coordinated decision.