You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Docs Governance / Worktree Helper (Windows PowerShell) reddened main on 2026-09-03. The failing case is scenario 28, codex-505-fsmonitor-hidden-git-add-timeout, in scripts/git/Test-New-CodexIssueWorktree.ps1. It is not #2378 and it is not covered by #1635 or #2400.
Failing step: 3, Validate detached-first worktree helper. Scenarios 1 through 27 passed; this is the next one.
Frequency: 1 failure in 20 observed runs of this job across the last 40 ci-required.yml runs (14 success, 1 failure, 1 cancelled, 4 still running at the time of counting). Rare, but it landed on main.
Failure
Index-hidden partial-registration cleanup did not explain its preservation decision.
Expected substring: <index contains assume-unchanged, skip-worktree, or fsmonitor-valid
entries that can hide modified data>
Actual output:
git worktree add failed for '...\.worktrees\codex-505-fsmonitor-hidden-git-add-timeout'
from 'origin/main' (exit code -1). Git: Git command timed out after 5 seconds; its
helper-owned process tree was terminated and reaped. HEAD is now at 24695b8
Preparing worktree (detached HEAD 24695b8)
Updating files: 33% (2/6) ... 100% (6/6), done.
Thrown from Test-New-CodexIssueWorktree.ps1:265 via the assertion at scenario 28.
Mechanism
This scenario deliberately forces a timeout: it passes -GitCommandTimeoutSeconds 5 (against the helper's default of 45 at New-CodexIssueWorktree.ps1:14) and installs a hook fixture that hangs git add. The intent is that git worktree add times out while the hook is hanging, leaving a partial registration whose index carries assume-unchanged / skip-worktree / fsmonitor-valid entries. The helper's cleanup should then detect those, preserve rather than delete, and say why. The assertion checks for that explanation.
The scenario therefore depends on an unstated timing assumption: that 5 seconds is comfortably more than the checkout takes and comfortably less than the hung git add takes.
On this run the first half of that assumption broke. The captured Git output shows the checkout ran to Updating files: 100% (6/6), done., so the 5 second budget was consumed by the checkout itself rather than by the hook. The timeout landed at the wrong phase, the index-hidden cleanup path that emits the explanation was never reached, and the assertion failed against the generic timeout message.
So the helper is not obviously wrong here. The test's timing assumption is what does not hold on a slow Windows runner.
Same family, different budget and different script, and it should not be folded in. #2378 is scripts/ci/dev-up.test.mjs on the Frontend Unit (windows-latest) leg, where a hardcoded 20 s spawnSync budget at :774 is simply too small for the work. Here the budget is deliberately small and the defect is that its landing point is timing-dependent. A fix to one does nothing for the other.
The common thread is worth naming, because it is now three separate places: hosted Windows runners are slow enough that fixed Git and process budgets written against a fast machine produce spurious reds. #2378 and this issue are two instances; #2157 is arguably a third.
Suggested fix
Make the timeout land deterministically at the hook rather than relying on the checkout being fast relative to a fixed 5 seconds. Options, in rough order of preference:
Have the hook signal readiness (touch a canary the test waits on) and only start the constrained-timeout Git invocation after the checkout phase has completed, so the budget can only be consumed by the hang.
Size the budget from an observed baseline (measure an unhung git worktree add in the same fixture, then set the constrained budget below the hang but above that baseline) instead of hardcoding 5.
Assert on the cleanup's preservation behaviour directly (registration retained, populated target retained, guard bytes intact) and treat the explanation substring as a secondary assertion, so a mistimed timeout fails with a message that says the timeout landed in the wrong phase.
Option 3 alone would turn this from a spurious red into a clear diagnostic even if the timing still drifts, and it is the cheapest.
Please do not simply raise the 5 to a larger number: that widens the window in which the checkout fits, but it also widens the window in which the hung git add might itself complete, so it trades one flake for another without making the landing point deterministic.
Why this matters beyond the flake
docs/REVIVAL_PLAN.md:50 makes "main green" part of the v0.3.0 exit gate. Two distinct Windows-lane failures reddened main within four hours on 2026-09-03: run 33713409999 at 468d76dc8 (Frontend Unit (windows-latest), recorded on #2378 and #1898) and this one. Neither is tracked as a release blocker today. Whatever the burn-down list says, the gate clause is measured against the branch, not the issue list.
Not verified
I read the job log and the two PowerShell scripts. I did not run the suite locally, did not reproduce the failure, and did not measure how long an unhung git worktree add takes in that fixture on a hosted Windows runner, which is the number option 2 would need. I checked 20 runs of this job, not the full history, so the 1-in-20 rate is a sample and not a base rate. I did not check whether this scenario has failed before 2026-09-03.
Docs Governance / Worktree Helper (Windows PowerShell)reddenedmainon 2026-09-03. The failing case is scenario 28,codex-505-fsmonitor-hidden-git-add-timeout, inscripts/git/Test-New-CodexIssueWorktree.ps1. It is not #2378 and it is not covered by #1635 or #2400.Occurrence
33730061189, job100567701501, branchmain, heade1ea14fad40885a53907e8e8be762dc235c9e318(the merge of PR Sanitize Ops CLI unexpected failure persistence #2422), 2026-09-03T07:49Z.Validate detached-first worktree helper. Scenarios 1 through 27 passed; this is the next one.ci-required.ymlruns (14 success, 1 failure, 1 cancelled, 4 still running at the time of counting). Rare, but it landed onmain.Failure
Thrown from
Test-New-CodexIssueWorktree.ps1:265via the assertion at scenario 28.Mechanism
This scenario deliberately forces a timeout: it passes
-GitCommandTimeoutSeconds 5(against the helper's default of 45 atNew-CodexIssueWorktree.ps1:14) and installs a hook fixture that hangsgit add. The intent is thatgit worktree addtimes out while the hook is hanging, leaving a partial registration whose index carriesassume-unchanged/skip-worktree/fsmonitor-validentries. The helper's cleanup should then detect those, preserve rather than delete, and say why. The assertion checks for that explanation.The scenario therefore depends on an unstated timing assumption: that 5 seconds is comfortably more than the checkout takes and comfortably less than the hung
git addtakes.On this run the first half of that assumption broke. The captured Git output shows the checkout ran to
Updating files: 100% (6/6), done., so the 5 second budget was consumed by the checkout itself rather than by the hook. The timeout landed at the wrong phase, the index-hidden cleanup path that emits the explanation was never reached, and the assertion failed against the generic timeout message.So the helper is not obviously wrong here. The test's timing assumption is what does not hold on a slow Windows runner.
Relationship to #2378
Same family, different budget and different script, and it should not be folded in. #2378 is
scripts/ci/dev-up.test.mjson theFrontend Unit (windows-latest)leg, where a hardcoded 20 sspawnSyncbudget at:774is simply too small for the work. Here the budget is deliberately small and the defect is that its landing point is timing-dependent. A fix to one does nothing for the other.The common thread is worth naming, because it is now three separate places: hosted Windows runners are slow enough that fixed Git and process budgets written against a fast machine produce spurious reds. #2378 and this issue are two instances; #2157 is arguably a third.
Suggested fix
Make the timeout land deterministically at the hook rather than relying on the checkout being fast relative to a fixed 5 seconds. Options, in rough order of preference:
git worktree addin the same fixture, then set the constrained budget below the hang but above that baseline) instead of hardcoding 5.Option 3 alone would turn this from a spurious red into a clear diagnostic even if the timing still drifts, and it is the cheapest.
Please do not simply raise the 5 to a larger number: that widens the window in which the checkout fits, but it also widens the window in which the hung
git addmight itself complete, so it trades one flake for another without making the landing point deterministic.Why this matters beyond the flake
docs/REVIVAL_PLAN.md:50makes "maingreen" part of the v0.3.0 exit gate. Two distinct Windows-lane failures reddenedmainwithin four hours on 2026-09-03: run33713409999at468d76dc8(Frontend Unit (windows-latest), recorded on #2378 and #1898) and this one. Neither is tracked as a release blocker today. Whatever the burn-down list says, the gate clause is measured against the branch, not the issue list.Not verified
I read the job log and the two PowerShell scripts. I did not run the suite locally, did not reproduce the failure, and did not measure how long an unhung
git worktree addtakes in that fixture on a hosted Windows runner, which is the number option 2 would need. I checked 20 runs of this job, not the full history, so the 1-in-20 rate is a sample and not a base rate. I did not check whether this scenario has failed before 2026-09-03.