Refs #250 — deliberately not Closes. The reported tree was never captured and 200 repeat cached installs did not reproduce it, so this does not claim to be that failure. It identifies and closes a colliding operation on the implicated path, which is what the issue's acceptance asks for ("retain … a public-interface regression that identifies the colliding path and operation").
What collides
copyDirectoryStructure — reached through MaterializationOperations.copy, i.e. cache materialization — was not repeatable:
| entry kind | operation | repeatable over an existing tree? |
|---|---|---|
| directory | makePath | yes |
| regular file | copyFile → createFile (truncates) | yes |
| symlink | bare symlink(2) | no — EEXIST |
That EEXIST escaped as error.PathAlreadyExists. git is the most symlink-dense package in the failing cohort — its libexec is a wall of links to git — which is consistent with git-scm.org@2.53.0 failing while the other fourteen packages installed.
Established by execution, not by reading the syscall
The regression test was written before the fix and asserted expectError(error.PathAlreadyExists, …) on a second copy pass over the same destination. That probe passed, which is what pins the operation; the assertion was then inverted to the repeatability check the test now carries, and the comment records that history so nobody mistakes it for a happy-path test.
It also covers the stale case: a destination link pointing elsewhere must end up at the source's target, since a half-materialized tree is exactly how that arises.
The fix
A link already pointing where the source says is accepted. One pointing elsewhere — or a non-link squatting on the path — is replaced, because the source is authoritative. Unrelated symlink failures still propagate (else => return err), so this is not a broad catch.
zig build test: 574 pass / 6 skip. The 2 failures (shell.install_route bash + zsh) are pre-existing on main on this machine and unrelated.
What this does not do
It does not explain why that specific runner's restored tree already contained the link, and the issue is right that a later green run proves nothing. If the diagnostic capture Craft added ever fires again, the evidence is still worth having — this change means one repeatability hole can no longer be the cause.
🤖 Generated with Claude Code