Skip to content

[CI][Windows] Worktree helper: the late-branch-collision scenario's fixed 5 s poll expires before the scheduled orphan removal finishes on the hosted runner #2664

Description

@Chris0Jeky

Occurrence

Docs Governance / Worktree Helper (Windows PowerShell) failed on PR #2662 (alpha lane, review components and catalogs only, nothing under scripts/) at head 5cd7f5e50, run 33951635415, job 101267419144, 2026-09-05T07:07:57Z. Scenarios 1 through 10 passed in the 44 seconds before it; the same job passed on PR #2658 (ab1ebcdcc) in the same window. One identical-head rerun was requested by the alpha lane. This is not #2378 (a different suite) and not #2425 (scenario 28, closed by PR #2447).

Failure

Late branch collision must not leave an orphan helper-created worktree.
    + CategoryInfo          : OperationStopped: (Late branch col...eated worktree.:String) [], RuntimeException
    + FullyQualifiedErrorId : Late branch collision must not leave an orphan helper-created worktree.

Thrown by the assertion at scripts/git/Test-New-CodexIssueWorktree.ps1 line 1224 (main at 86ca9078c).

Mechanism

The late-branch-collision scenario runs the printed initializer handoff against a worktree whose branch was created behind the helper's back. The initializer fails git switch -c, prints "removal of the unused helper-created worktree was scheduled" (the test asserts that line, and it passed), and hands the removal to a scheduled background step: Initialize-CodexIssueWorktree.ps1 lines 170 to 214 launch a hidden, detached PowerShell host with an encoded cleanup script that re-verifies the worktree's top level, common directory and HEAD, re-inventories tracked, untracked, ignored and index-hidden content with two more Git calls, and only then runs git worktree remove. That is one PowerShell host start plus six Git invocations against a fresh checkout before the directory can disappear. The test then polls Test-Path on the worktree directory 50 times at 100 ms, a fixed 5 second ceiling, before asserting the directory is gone (lines 1221 to 1224). On the hosted Windows runner the scheduled git worktree remove of a freshly checked-out fixture took longer than 5 seconds, so the assertion fired while the removal was still in progress. The next assertion (the registration is gone from git worktree list) never ran, so nothing here says the cleanup itself misbehaved; the sibling refused-cleanup scenario uses a fixed 500 ms sleep for the opposite expectation.

Fixed short polls are the same shape the Windows dev-up deadlines went through (#1898, #2157, #2159, #2161): a wall-clock bound sized for a developer box is not a bound for a hosted runner under load.

Ask

  1. Replace the fixed 5 second poll with a deadline-based wait sized from the initializer's own scheduling contract (read scripts/git/Initialize-CodexIssueWorktree.ps1 for what "scheduled" launches and whether it exposes a completion signal the test can await, such as the scheduled process handle or a marker file), and fail with the elapsed time and the current git worktree list in the message so a genuine orphan is diagnosable.
  2. Keep the assertion strict: a genuine orphan must still fail; only the ceiling changes.
  3. Apply the same deadline to the separate-Git-dir sibling at lines 1299 to 1302, which has the identical shape with a 10 second ceiling (100 polls at 100 ms) and the same scheduled removal behind it.
  4. Leave the refused-cleanup 500 ms sleep alone unless the same reading shows it is also racy.

scripts/git/** is not an SC-10 control path, so the fix is a normal T3 PR. Refs #2425, #2378, PR #2662.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingciCI/CD pipeline, workflow, and build infrastructure changes.testingTest coverage, harnesses, regression prevention, and verification pipeline work.

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions