Skip to content

worktree-fs refuses an absolute in-worktree destination on Windows #541

Description

@SUaDtL

The failure

worktree-fs.test.ts > symlink-safe worktree writer — refusal paths > judges an absolute destination by where it … fails on windows-latest:

UnsafeWorktreePathError: unsafe worktree path rejected
 ❯ unsafe worktree-fs.ts:26:9
 ❯ writeWorktreeFile worktree-fs.ts:75:116
 ❯ worktree-fs.test.ts:220:7

The test asserts that an absolute destination is judged by where it resolves, not by its spelling. On Windows it is refused outright.

Passes on ubuntu-latest. Passes on a developer Windows box.

How it surfaced

plugins/ca/tools had never run on Windows in CI — the tools job is ubuntu-latest only. #521's coverage-union job added a windows-latest cell; #539 fixed the containment bug that was masking everything behind it, and this is one of two failures left standing underneath.

Why it is NOT #539

#539 was validateWorktreeRoot in farm.ts comparing two spellings of one directory lexically. This is writeWorktreeFile in worktree-fs.ts, a different module with its own path judgment, and it survives the #539 fix. Filed separately so neither investigation inherits the other's lead — the same reasoning that split #504 from #495 and #515.

The likely shape is related though, and worth checking first: worktree-fs.ts does its own containment reasoning, and the runner's C:\Users\RUNNER~1\… short path plus a D:-drive workspace give it two ways to disagree with itself that a developer box does not reproduce.

Acceptance criteria

  • AC-1: the cause is identified — specifically whether the refusal comes from a short-name/long-name mismatch, a drive-letter or UNC difference, or a genuine platform difference in how the destination resolves.
  • AC-2: an absolute destination that resolves inside the worktree is accepted on Windows, and the test asserts its own precondition so it cannot silently stop testing that.
  • AC-3: every genuinely-escaping destination is still refused on Windows, including via a junction — the refusal is a security boundary and must not be relaxed to fix a false positive. farm's worktree containment refuses a legitimate root when two path spellings disagree (Windows 8.3) #539's fix is the precedent: canonicalize, which tightened the guard rather than loosening it.
  • AC-4: worktree-fs.test.ts passes on windows-latest in CI.

Not in scope

Found while closing #539. That issue's fix is complete and verified independently; this is a separate defect in a separate module.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions