mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 17:45:53 +01:00
Stale-gate recovery still removed a gate by pathname after a separate content check. Two calls can never make a read-then-unlink pair atomic by moving the read closer to the unlink: a replacement gate could still land in the remaining gap, so the unlink could remove a live gate instead of the dead one recovery inspected, letting a claim and a teardown critical section overlap. Recovery now renames the gate to a private path in one syscall before it inspects it at all. That rename is the only step that touches the shared path, so no later, separate step is left for a replacement to land in front of. When the captured bytes match the dead gate, deleting the private copy is always safe. When they do not, another admission already replaced the gate; recovery puts it back with `link`, which fails instead of overwriting when a further replacement has since claimed the path. Co-authored-by: Paperclip <noreply@paperclip.ing>