Skip to content

source-control:babysit-prs: worker assigned a detached-HEAD worktree (branch checked out in a sibling worktree) + stale local branch behind origin — happy-path checkout/merge/push is unsafe #548

Description

@kyle-sexton

Category: operational

Context: Babysitting PR #456 in the assigned worktree .../worktrees/melodic-software__claude-code-plugins__pr-456.

Observed: The assigned worktree was in detached HEAD, not on the PR branch, because feat/373-babysit-safety-enhancements was already checked out in a sibling worktree (D:/repos/.../.claude/worktrees/373-babysit-enhancements). Additionally, that sibling's local branch ref was stale — it pointed at 632d739 (one commit behind), while origin/feat/373 and the PR head were at 4211d31.

Two concrete hazards from this state:

  1. git checkout <pr-branch> in the assigned worktree fails (fatal: '<branch>' is already used by worktree at ...). A worker following a happy-path "checkout the branch, merge main, push" script dead-ends here.
  2. The detached HEAD happened to be at the origin PR head (4211d31), so operating on it was safe — but had it been left at the stale local tip (632d739), a naive git merge origin/main + push would have silently reverted the newest branch commit (the advisory-alias fix) onto the PR. The safety of the operation depended on luck, not on a guard.

Workaround that worked this cycle: verify HEAD == origin/<pr-branch> (the true PR head), do the merge in detached HEAD, and push via explicit refspec git push origin HEAD:<pr-branch> rather than relying on branch checkout. Fast-forwarded 4211d31..48a3096 cleanly, no force.

Suggested direction: the worker/worktree setup should (a) explicitly assert the assigned worktree HEAD equals origin/<pr-branch> before any merge/edit (safety.md already says "re-check PR head SHA before editing/pushing" but does not cover the detached-HEAD/stale-local-branch worktree assignment), and (b) prefer refspec push over branch checkout so a branch locked by a sibling worktree is not a dead-end. Distinct from the existing safety.md "two open PRs sharing one head" guard — this is two worktrees sharing one branch.

Filed per babysit self-observation. Not blocking — PR #456's conflict was resolved and pushed successfully.

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions