- Imported tracks are created directly under their final name with
O_EXCL (never overwriting; " (2)" on conflict), fsync'ed and checked
against SHA-256 — no hidden .pipu-tmp file next to them any more.
- On any failure the agent removes its own partial file and the empty
directories it created for it.
- The write check uses access(W_OK) and the read-only mount flag instead
of creating and deleting .pipu-write-test in the storage root.
- Tests assert the storage tree holds only audio files after successful
and failed writes and after the write check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- storage-agent: POST /internal/files copies a staged file into a source
(temp file, fsync, SHA-256 check, hard link so nothing is overwritten,
" (2)" suffix on conflict, owner PIPU_FILE_UID/GID) and
POST /internal/files/test. NFS sources that accept uploads are mounted
rw in an agent-only /library-rw and bind-mounted read-only for others;
local sources are written through /library-host-rw.
- meta: write templates ({track:02}, {disc:1-}, [optional]) with name
sanitising and length limits, suggestion from the source's regexes
and a reversibility check against 50 catalogue tracks.
- API and admin UI: accepts_uploads / write_template on sources,
write-template suggest and check endpoints, write test result.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>