Skip to content

[Bug]: native Windows --write-worktree scoped observation rejects every in-scope path #7805

Closed

Description

@JasonBuildAI

Impact

Native Windows users cannot acquire the documented --write-worktree hard lease for isolated code edits. On current main (70f643153ea773b7bc1ef71bdb06095b0744bd6d), any existing file or directory that matches the requested write scope is classified as a redirected path, so loopx task-lease acquire --write-worktree ... fails before creating the lease. New canonical Goals default to hard_lease, and the canonical lease guide recommends --write-worktree for independent worktree edits, so this blocks a primary multi-Agent editing workflow on Windows rather than an optional edge path.

This is a follow-up to #6653: that change supplied Windows machine identity, but scoped observation still fails before it can use that identity. It is not the same failure as closed #6640.

Minimal reproduction

Prerequisites: native Windows, Node.js with TypeScript stripping, and an independent Git worktree whose scope contains at least one existing entry.

From the root of such a worktree:

node --no-warnings --experimental-strip-types --input-type=module -e "import {observeLeaseWorktree} from './loopx/control_plane/work_items/task_lease_workspace.ts'; try { console.log(await observeLeaseWorktree(process.cwd(), p => p.startsWith('docs/'))); } catch(e) { console.error(e.name + ': ' + e.message); process.exitCode = 1; }"

Observed:

LeaseWorktreeObservationError: worktree scope contains a redirected path

The underlying path comparison also reproduces directly:

node --no-warnings --experimental-strip-types --input-type=module -e "import {realpath} from 'node:fs/promises'; import {join} from 'node:path'; const root=await realpath(process.cwd()); const full=await realpath(join(root,'docs')); console.log(JSON.stringify({root,full,prefix:root+'/',startsWith:full.startsWith(root+'/')},null,2));"

Observed with a synthetic checkout under C:\work\loopx-worktree:

{
  "root": "C:\\work\\loopx-worktree",
  "full": "C:\\work\\loopx-worktree\\docs",
  "prefix": "C:\\work\\loopx-worktree/",
  "startsWith": false
}

The write-scope oracle itself correctly reports the scope as overlapping:

{"overlap":true}
{"overlap":true}

Expected behavior

A regular directory or file physically inside the verified worktree must be accepted, including on Windows. Only an actual redirect outside the worktree (or a disallowed link) should raise worktree scope contains a redirected path. The observation should return the same path-free host/common-directory/worktree/repository identity used on macOS and Linux.

Actual behavior

At loopx/control_plane/work_items/task_lease_workspace.ts:130, the check compares:

!(await realpath(full)).startsWith(`${root}/`)

On Windows, realpath() returns a backslash-separated absolute path while the prefix is slash-terminated. The comparison is false for every child path. Once at least one scoped entry exists, every --write-worktree observation fails, even when no symlink, junction, or redirect exists.

The existing cross-platform observation test passes () => false as the overlap predicate, so it never enters this branch; the link test that does exercise scoped traversal is skipped on Windows.

Why this meets the importance bar

  • Affected users and scale: every native-Windows user of the recommended independent-worktree code-edit flow; hard leases are the default for new canonical Goals, so the affected path is a normal multi-Agent workflow.
  • Consequence: lease acquisition is deterministically blocked; agents must either abandon isolation or omit the documented flag, losing the checked checkout identity and overlap advisories.
  • Persistence: the failure exists in the shipped source today and is not a transient environment issue; all Windows test lanes miss it because the scoped-observation branch is not exercised there.
  • Actionable evidence: the minimal reproduction above fails on the exact baseline commit and the masked comparison is visible in the shared observation owner.

Environment

  • LoopX commit: 70f643153ea773b7bc1ef71bdb06095b0744bd6d
  • OS: native Windows 11 (Microsoft Windows NT 10.0.26200.0)
  • Node.js: v26.11.1
  • Git: 2.49.0.windows.1
  • Host surface: Codex CLI / canonical task-lease command

Additional context

The unrelated Unicode case-folding/glob overlap work recently merged in #7243/#7252/#7786 is not involved. This report is about native path normalization in worktree observation.

AI disclosure: this issue was prepared with AI assistance and the reproduction was executed in a real native-Windows checkout.

Activity

  1. added
    bugSomething isn't working
    triageNeeds maintainer triage or routing.
    on Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriageNeeds maintainer triage or routing.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions