Skip to content

Add a supported wait for the worktree setup pipeline - #1256

Merged
geodro merged 2 commits into
mainfrom
feat/worktree-wait
Jul 31, 2026
Merged

Add a supported wait for the worktree setup pipeline#1256
geodro merged 2 commits into
mainfrom
feat/worktree-wait

Conversation

@geodro

@geodro geodro commented Jul 31, 2026

Copy link
Copy Markdown
Member

The watcher's auto-setup pipeline is what makes a bare git worktree add from any tool a first-class flow, but a tool that then wants to act on the new tree had no supported way to ask whether that pipeline had finished. The wait existed only inside the interactive lerd worktree add wrapper, so everyone else was left probing the tree's contents or reverse-engineering the install lock.

Both of those are traps. Composer's extraction phase fills existing vendor/<org>/ directories, and node_modules/ exists from the very first extracted package, so neither a file count nor an mtime moves during the longest stretch of an install, and the tree reads as finished while it is being written. Two installers in one tree is how vendor/ ends up holding packages but no autoload.php, which then presents as a Composer autoload bug rather than as the race it is.

lerd worktree wait [path] blocks until the pipeline settles, defaulting to the current directory. It exits 0 once the tree is safe to touch, 1 on timeout, and 3 when the path is not a worktree lerd manages, so a caller can tell "ask someone else" apart from "still going" instead of waiting out a timeout nothing could ever satisfy.

Readiness now consults the install lock alongside the pipeline's outputs, which closes the same false-ready window in lerd worktree add's own wait, since node_modules/ alone was never enough to call an npm ci finished. The probe takes a shared non-blocking flock rather than the existing try-lock, so it neither overwrites the pid the real holder recorded nor claims an exclusive lock a starting installer would then have to poll for. A probe that fails outright counts as idle, so an unreadable lock directory degrades to the previous behaviour rather than blocking forever.

The MCP worktree tool carried the identical race in its add action, which ran bare git and handed the tree straight back to the assistant, so that is fixed here too rather than left for later. add now waits by default and reports whether the tree is provisioned, wait: false opts out, and a wait action covers a worktree created outside the tool. An install still running is reported as not-yet rather than as a failure. The reference injected into every assistant session now states that readiness must never be inferred from the tree's contents, which is the part an assistant would otherwise get wrong on its own.

Both size ceilings that guard the assistant-facing manifests fired on the additions. Each is raised only by the remainder that survived merging the new text into the sentences it supersedes, in the way the ceiling comments describe.

While smoke-testing this I hit an unrelated startup bug in the watcher and filed it as #1255.

Refs #1246

The watcher's auto-setup pipeline is what makes a bare git worktree add from any tool a first-class flow, but a tool that then wants to act on the new tree had no way to ask whether that pipeline had finished. The only wait lived inside the interactive worktree add wrapper, leaving everyone else to probe the tree's contents or reverse-engineer the install lock, and both are traps. Composer's extraction phase fills existing vendor directories, and node_modules exists from the very first extracted package, so file counts and mtimes sit still through the longest stretch of an install and read as finished. Two installers writing one tree is how vendor ends up holding packages but no autoload.php, which presents as a Composer autoload bug rather than as the race it is.

lerd worktree wait blocks until the pipeline settles for a path, defaulting to the current directory. It exits 0 once the tree is safe to touch, 1 on timeout, and 3 when the path is not a worktree lerd manages, so a caller can tell "ask someone else" apart from "still going" rather than waiting out a timeout that nothing could ever satisfy.

Readiness now consults the install lock alongside the pipeline's outputs, which closes the same false-ready window in worktree add's own wait. The probe takes a shared non-blocking flock rather than the existing try-lock, so it neither overwrites the pid the real holder recorded nor claims an exclusive lock a starting installer would then have to poll for. A probe that fails outright counts as idle, so an unreadable lock directory degrades to the previous behaviour instead of blocking forever.

The MCP worktree tool carried the identical race in its add action, which ran bare git and handed the tree straight back to the assistant. It now waits by default and reports whether the tree is provisioned, and a wait action covers a worktree created outside the tool. An install still running is reported as not-yet rather than as a failure, and the reference injected into assistants now states that readiness must never be inferred from the tree's contents.
@geodro
geodro requested a review from a team as a code owner July 31, 2026 12:18
@geodro
geodro merged commit 21e65ed into main Jul 31, 2026
3 checks passed
@geodro
geodro deleted the feat/worktree-wait branch July 31, 2026 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

External tools that create worktrees race the watcher's install pipeline, and there is no supported way to wait for it

1 participant