git/intake/main
issues/0027-fix-the-archive-write-path-loses-tracks-and-destro.md
25 lines2 KB last change raw · source · history

title: fix: the archive write path loses tracks and destroys albums when it fails status: closed labels: [] created: 2026-09-14 closed:


Found by the audit of 2026-09-14. Every item below was reproduced with a Go test against the real code.

  • Two tracks in one album that share a track number and a title are both given the same target name, and the copy truncates, so the second silently replaces the first. The album is filed a track short and verification passes, because it compares each written file against the plan entry in the same position. normalize.DetectCollisions groups by the title half of a name and folds repeats of a title together, so it never saw this pair. There is now a plan-level issue and a hard guard in execute.Run that refuses before the first copy.

  • Collision "both" renames the album to " (2)" but every later step kept using the path the plan asked for: the journal recorded the pre-existing album, the library was transcoded from the pre-existing masters, and the bytes reported were the pre-existing album's. The promoted directory is now returned and followed.

  • "replace" ran RemoveAll on the destination and only then renamed the new album in. A failed rename, a permission problem part-way through RemoveAll, or a power cut left the album gone with nothing to restore. The old album is now moved aside first and moved back if the new one cannot land.

  • "merge" checked for conflicts as it moved files, so a clash on the second file left the destination holding part of one album and part of another. Every name is now checked before anything moves.

  • A staged file that could not be deleted after a successful promotion made Run return an error; FilePlan then called forget() and deleted the journal record of an album that is complete and on disk. Staging cleanup failures are now reported without failing the run.

  • cleanStaging walked up to four empty ancestor directories, which reached past the album and past staging: filing the last album could delete the staging directory itself, making the next scan fail. It now stops at the staging root, and clears the album folder the scan named rather than the disc folder the first track happened to sit in, so a CD1/CD2 rip no longer leaves CD2 and the album sidecars behind for ever.

  • A failed run left the artist folder it had created, empty, in the archive.

  • Run panicked on a plan with no tracks.