The album-bundle path COPIES slskd's completed files into private staging (then
on to the library) but never removed slskd's originals, so they piled up in the
download folder. (copy, not move, is correct for the torrent/usenet bundle paths
— those clients keep seeding — so the shared copier can't just always delete.)
Add an opt-in remove_source to copy_audio_files_atomically that deletes each
source ONLY after it copies successfully (never on a failed stage), and set it
for the Soulseek path only. Torrent/usenet keep their originals.
Tests: keeps source by default / removes when requested / keeps on failed copy.
When the preflight-selected Soulseek folder produces zero usable files —
every transfer failed/aborted/stalled (the Slipknot dead-peer case: all
tracks 'Completed, Aborted' at 0 bytes) — _poll_album_bundle_downloads
returns []. download_album_to_staging used to return that with
fallback=False, so try_dispatch marked the whole batch failed and nothing
was retried elsewhere until the next wishlist run.
Flip that branch to fallback=True so the existing, proven per-track flow
takes over and re-searches every missing track across ALL sources/peers.
This reuses the per-track multi-source robustness instead of reimplementing
candidate-folder retry inside the bundle.
Tests: tests/test_soulseek_album_fallback.py drives the preflight-reuse path
with a stubbed poll — empty poll -> fallback=True (differential-verified it
fails without the fix), healthy poll -> fallback stays False. Downstream
routing (fallback=True -> per-track) already covered by
test_album_bundle_dispatch.py.