Worktree path comparisons use exact string equality, so symlinked paths split identity on macOS
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
Server / checkpointing
Steps to reproduce
- On macOS, register a project whose root lives under
/tmp/...(which is a symlink to/private/tmp/...). - Get two threads pointing at the same worktree directory, where one stored its
worktreePathas/tmp/fooand the other as/private/tmp/foo(for example one created through a path the user typed and one through a resolved picker path). - Trigger the branch drift check after a turn completes.
Expected behavior
Both threads are treated as sharing one worktree, so the drift check refuses to adopt a drifted checkout and any shared-worktree guard counts both references.
Actual behavior
The comparison is raw string equality (other.worktreePath === thread.worktreePath in CheckpointReactor.ts), so the two spellings of the same directory count as different worktrees. The guard proposed in #9185 compares the same way in SQL (worktree_path = ?), so it would inherit the same blind spot: a removal that should be refused can slip through.
Impact
Low in practice, most people keep projects under their home directory. But when it hits, the failure mode is the bad one these checks exist to prevent: a worktree removed or a branch adopted while another thread still points at the same directory through a different spelling. Normalizing with realpath before comparing (or at write time) would close it. Happy to send a small PR if this is worth fixing.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in CheckpointReactor.ts at the worktreePath comparison, then inspect the SQL guard proposed in #9185 and its worktree_path = ? query. Reproduce the macOS /tmp and /private/tmp case, and confirm that branch-drift and shared-worktree checks treat both spellings as one directory without allowing unsafe removal or adoption.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sql, typescript
- Domain
- backend, database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100