soulsync/core/downloads
BoulderBadgeDad 4487a9d2dc unverified-history reconcile + orphan-clean: hardening follow-up to #938
four fixes from the review (and a self-correction):

1) close the connection. reconcile_unverified_history_from_tracks opened a connection with no
   finally/close. runs once per boot so GC reclaimed it, but now it's consistent + robust.

2) scope the tracks scan to the review queue. it built lookup dicts from EVERY verified/
   human_verified track (~350k on a large library) on every boot while anything is unverified
   (the normal state). now it loads the stuck rows first and skips verified tracks whose path
   AND basename can't match any queued row, so dicts stay proportional to the queue, not the
   library. behaviour identical (all 13 PR reconcile tests still pass).

3) close the title-less basename collision. a title-less history row fell back to filename-only
   matching with no ambiguity check, so a generic name like "01 - Intro.flac" could heal a
   DIFFERENT song to verified. now a title-less basename heal only fires when that basename is
   unique among verified tracks; unique-basename rows still heal (recall preserved).

4) "Clean orphaned" protects force_imported rows (deliberate user decision, keep for human
   approval) without weakening the mount-down safety gate. CRUCIAL self-correction: filtering
   them out BEFORE the orphan check (my first cut) shrank the checked count below the threshold
   and would have let a few unverified orphans be deleted during a mount outage. instead,
   find_orphan_history_ids now takes a deletable predicate: protected rows still count toward
   checked / all-missing (gate stays strong) but never enter the orphan_ids delete set.

3 new regression tests (title-less collision; deletable protects from delete; protected rows
still count toward the gate). 936 verification/acoustid/history/downloads tests green. builds
on nick2000713's #938.
2026-06-27 22:35:16 -07:00
..
__init__.py PR4a: lift sync history recording to core/downloads/history.py 2026-04-27 20:37:16 -07:00
album_bundle_dispatch.py Album bundle: fall back to per-track on an I/O error, don't hard-fail the batch 2026-06-01 13:29:05 -07:00
cancel.py fix(downloads): keep terminal tasks visible during active batch + concurrent pool 2026-06-14 20:08:56 +02:00
candidates.py Merge pull request #896 from nick2000713/feature/best-quality-search-mode 2026-06-24 20:27:38 -07:00
cleanup.py PR4c: lift _automatic_wishlist_cleanup_after_db_update to core/downloads/cleanup.py 2026-04-27 22:23:41 -07:00
file_finder.py Fix: a '/' in a song title was treated as a path separator (#835) 2026-06-10 16:29:09 -07:00
history.py PR4a: lift sync history recording to core/downloads/history.py 2026-04-27 20:37:16 -07:00
history_match.py downloads: stop AcoustID scan duplicating history rows / leaving verified tracks 'unverified' (#934) 2026-06-27 09:52:39 -07:00
lifecycle.py fix(downloads): stop phantom-completing stuck post_processing tasks 2026-06-14 23:25:33 +02:00
master.py Playlists: all-owned trigger makes batch dict authoritative + logs when nothing rebuilt 2026-06-12 17:34:06 -07:00
monitor.py feat(quality): derive per-source download tier from the global profile 2026-06-14 13:18:01 +02:00
origin.py Download Origins: see (and delete) exactly what watchlist + playlist syncs downloaded 2026-06-07 00:15:31 -07:00
orphan_history.py unverified-history reconcile + orphan-clean: hardening follow-up to #938 2026-06-27 22:35:16 -07:00
playlist_folder.py Fix #780: Deezer/non-Spotify organize-by-playlist resolved the wrong row 2026-06-03 20:41:04 -07:00
post_processing.py fix(post-processing): prevent double-claim race that fails imported tracks 2026-06-25 21:03:33 +02:00
staging.py Staging match: log rejection reason on every silent-False exit 2026-05-27 14:12:55 -07:00
status.py fix(downloads): always surface all unverified history on Downloads page 2026-06-15 19:46:26 +02:00
task_worker.py feat(quality): rank-based candidate ordering toggle for priority mode 2026-06-25 22:00:57 +02:00
track_detail.py Downloads: add per-track detail endpoint for the track-detail modal 2026-05-31 20:18:35 -07:00
track_link.py manual search: float the pasted Qobuz/Tidal track to the top (#932) 2026-06-26 21:45:41 -07:00
track_metadata_backfill.py #915: post-processing hydrates lean album context from the PRIMARY source (parity with Reorganize) 2026-06-23 18:46:35 -07:00
validation.py Add torrent and usenet release staging support 2026-05-21 14:22:21 -07:00
wishlist_aggregator.py Wishlist modal: surface most-advanced live phase, not least-complete 2026-05-26 22:35:53 -07:00
wishlist_failed.py Fix album-bundle staging match + wishlist provenance (#700, #698) 2026-05-26 07:12:49 -07:00