soulsync/core/discovery
BoulderBadgeDad f0a6d5e696 discovery: add apply_adventurousness — pure popularity-penalty re-rank (aurral-style)
Both Discover rec rows already exclude what you own/watch, so novelty is baked in; the missing lever
is a popularity penalty. apply_adventurousness(items, level) re-ranks dicts (score + optional 0-100
popularity) so globally-popular candidates sink as the dial rises. Pure + reusable across both rec
rows. level<=0 returns the input order unchanged (a copy) — fully additive, no regression; 1.0 applies
the full penalty (a popularity-100 pick loses 70% of its score). Missing popularity is never penalised.

5 seam tests (no-op+copy, demotion, proportional penalty, missing-pop, clamping). 37 pass. Wiring
(scan stores popularity -> routes re-rank live -> Settings slider) is the next increment.
2026-06-29 16:03:16 -07:00
..
__init__.py
beatport.py
deezer.py
endpoints.py #702: make mirrored-playlist cancel/reset/delete idempotent (un-wedge LB weekly sync) 2026-06-11 12:55:55 -07:00
hero.py
listenbrainz.py
listening_recommendations.py discovery: add apply_adventurousness — pure popularity-penalty re-rank (aurral-style) 2026-06-29 16:03:16 -07:00
manual_match.py #799: stop mirrored discovery from reverting a manual fix to Wing It 2026-06-05 11:07:32 -07:00
matching.py
playlist.py #799: stop mirrored discovery from reverting a manual fix to Wing It 2026-06-05 11:07:32 -07:00
qobuz.py
quality_scanner.py merge: pull upstream/main (2.7.4) into feature/best-quality-search-mode 2026-06-19 16:54:51 +02:00
scoring.py
spotify_public.py
sync.py Sync wishlist re-add: build the IDENTICAL payload the auto-add uses 2026-06-24 16:41:40 -07:00
tidal.py
youtube.py #909: backfill the YT-artist column from a confident match instead of 'Unknown Artist' 2026-06-23 11:54:55 -07:00