You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Host checkouts on a case-insensitive host merge paths (staging clone, rebase worktree) #179
createTaskWorkspace (runner/workspace.ts) checks out the task head into a host folder, <runner.root>/<owner>/attempts/<attemptId> (git/clone.ts, clone --no-checkout then checkout --detach). The seeder then copies that folder into the tmpfs work volume (agents/container/storage.ts). The work volume is case-sensitive and compares names as bytes. The host folder may not be: macOS APFS folds case and Unicode normalization by default.
When the head has two paths that differ only by case (or only by normalization), the host checkout keeps one file. The copy to /work then has one file, while the index has two entries.
Reproduced on macOS 26 (APFS) with the same clone and checkout commands:
# tree has README.md ("upper") and readme.md ("lower")
$ ls
readme.md
$ git status --short
M README.md
So the agent starts from a tree that does not match the head, and change inspection sees an edit nobody made. #162 now checks pathIdentity against the work volume, so the plan keys are correct for /work. That check does not cover this earlier step.
Acceptance
A head with paths that collide on the host filesystem reaches /work with every entry intact, or the attempt is refused before launch with a message that names the colliding paths.
A test with two paths that differ only by case fails today on a case-insensitive host.
Record the choice in docs/implementation/runner-lifecycle.md.
A second host checkout has the same exposure: the F5 rebase worktree under <runner.root>/<owner>/rebases (runner/rebase.ts, git worktree add), whose conflict leaves are read and written by copyConflictPaths (runner/rebase-conflict.ts). Its starting head is already guarded: #assertCheckout hashes the checkout against the reviewed head and fails closed when the host cannot represent the tree. Commits replayed during the rebase, and the conflict copy, are not covered by that check. Found by the independent review of #180.
changed the title [-]Staging clone on a case-insensitive host merges paths before they reach task storage[/-][+]Host checkouts on a case-insensitive host merge paths (staging clone, rebase worktree)[/+]on Oct 19, 2026
Activity
mchwang commentedon Oct 19, 2026
A second host checkout has the same exposure: the F5 rebase worktree under
<runner.root>/<owner>/rebases(runner/rebase.ts,git worktree add), whose conflict leaves are read and written bycopyConflictPaths(runner/rebase-conflict.ts). Its starting head is already guarded:#assertCheckouthashes the checkout against the reviewed head and fails closed when the host cannot represent the tree. Commits replayed during the rebase, and the conflict copy, are not covered by that check. Found by the independent review of #180.[-]Staging clone on a case-insensitive host merges paths before they reach task storage[/-][+]Host checkouts on a case-insensitive host merge paths (staging clone, rebase worktree)[/+]Narrow the task storage claim and test the probe script on the host
Probe task storage path identity at runner startup (#162) (#180)