pingdotgg / pingdotgg/t3code

Worktree path comparisons use exact string equality, so symlinked paths split identity on macOS

Open
#9,245 0 comments 0 reactions 0 assignees View on GitHub

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
  1. On macOS, register a project whose root lives under /tmp/... (which is a symlink to /private/tmp/...).
  2. Get two threads pointing at the same worktree directory, where one stored its worktreePath as /tmp/foo and the other as /private/tmp/foo (for example one created through a path the user typed and one through a resolved picker path).
  3. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.