Skip to content

SoulSync

v2.6.2 Breaking

This release includes breaking changes for platform teams planning a safe upgrade.

Published 7d Media Servers
✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →

✓ No known CVEs patched in this version

ReleasePort's take

Light signal
editorial:auto 7d

The Auto‑Sync modal now opens in ~280 ms (down from ~1.5 s) and a bulk scheduling button is available, while several critical bugs affecting large libraries, UI displays, and download pipelines have been fixed.

Why it matters: Performance improvement of 81% on modal open time; bug fixes prevent hung schedules, display errors, and failed downloads for users with large libraries or timezone differences.

Summary

AI summary

Updates Headline changes, Wishlist + album-bundle improvements, and Code health across a mixed release.

Changes in this release

Feature Low

Bulk scheduling button added for source groups in Auto-Sync sidebar.

Bulk scheduling button added for source groups in Auto-Sync sidebar.

Source: llm_adapter@2026-05-27

Confidence: high

Feature Low

Wishlist albums‑cycle now uses per‑album release‑first searches.

Wishlist albums‑cycle now uses per‑album release‑first searches.

Source: llm_adapter@2026-05-27

Confidence: high

Feature Low

Redownload Album button restored on enhanced artist view (issue #699).

Redownload Album button restored on enhanced artist view (issue #699).

Source: llm_adapter@2026-05-27

Confidence: high

Feature Low

Thread ID support added for Telegram notifications (PR #594).

Thread ID support added for Telegram notifications (PR #594).

Source: llm_adapter@2026-05-27

Confidence: high

Feature Low

Sync page gains four new tabs: ListenBrainz, Last.fm Radio, SoulSync Discovery, iTunes/Apple Music Link.

Sync page gains four new tabs: ListenBrainz, Last.fm Radio, SoulSync Discovery, iTunes/Apple Music Link.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Feature Low

Auto-Sync modal now shows custom interval columns for non‑standard schedules with dashed borders.

Auto-Sync modal now shows custom interval columns for non‑standard schedules with dashed borders.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Feature Low

Sidebar search input and failure indicators (red !, yellow ⚠) added to Auto-Sync manager.

Sidebar search input and failure indicators (red !, yellow ⚠) added to Auto-Sync manager.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Feature Low

Run history tab in Auto-Sync includes filter pills, pagination, and "Run pipeline again" button.

Run history tab in Auto-Sync includes filter pills, pagination, and "Run pipeline again" button.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Feature Low

Cycle toggle in Wishlist now fires once per run instead of per sub‑batch, using a shared run ID.

Cycle toggle in Wishlist now fires once per run instead of per sub‑batch, using a shared run ID.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Feature Low

Wishlist download modal aggregates tasks and analysis results across all album siblings.

Wishlist download modal aggregates tasks and analysis results across all album siblings.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Feature Low

Enhanced view toggle state persists per browser via localStorage scoped per profile.

Enhanced view toggle state persists per browser via localStorage scoped per profile.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Feature Low

Quick Actions UI redesigned as asymmetric bento with animations and softer flow lines.

Quick Actions UI redesigned as asymmetric bento with animations and softer flow lines.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Performance Medium

Auto-Sync modal open time improved from ~1.5s to ~280ms.

Auto-Sync modal open time improved from ~1.5s to ~280ms.

Source: llm_adapter@2026-05-27

Confidence: high

Bugfix Medium

Hung‑forever loading‑schedule bug fixed for large libraries.

Hung‑forever loading‑schedule bug fixed for large libraries.

Source: llm_adapter@2026-05-27

Confidence: high

Bugfix Medium

"in library" always‑showing‑0 bug corrected.

"in library" always‑showing‑0 bug corrected.

Source: llm_adapter@2026-05-27

Confidence: high

Bugfix Medium

Timezone offset on countdowns corrected (~8h Pacific error).

Timezone offset on countdowns corrected (~8h Pacific error).

Source: llm_adapter@2026-05-27

Confidence: high

Bugfix Medium

Whole‑album downloads no longer fail with empty queues (issue #700).

Whole‑album downloads no longer fail with empty queues (issue #700).

Source: llm_adapter@2026-05-27

Confidence: high

Bugfix Medium

Album tracks no longer get requeued as singles (issue #698).

Album tracks no longer get requeued as singles (issue #698).

Source: llm_adapter@2026-05-27

Confidence: high

Bugfix Low

Album‑bundle downloads now correctly assign track numbers, avoiding defaulting to track 1.

Album‑bundle downloads now correctly assign track numbers, avoiding defaulting to track 1.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Bugfix Low

Songs stuck in quarantine loop when selecting a different candidate are now skipped for AcoustID processing.

Songs stuck in quarantine loop when selecting a different candidate are now skipped for AcoustID processing.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Refactor Low

Unified `PlaylistSource` adapter layer replaces large if/elif chain in refresh handler.

Unified `PlaylistSource` adapter layer replaces large if/elif chain in refresh handler.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Refactor Low

Auto-Sync JavaScript extracted into `webui/static/auto-sync.js` with node:test contract.

Auto-Sync JavaScript extracted into `webui/static/auto-sync.js` with node:test contract.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Refactor Low

Mirrored playlist pipeline moved to `core/playlists/pipeline.py` from inline location.

Mirrored playlist pipeline moved to `core/playlists/pipeline.py` from inline location.

Source: granite4.1:30b@2026-05-27-audit

Confidence: high

Full changelog

Release: dev → main, 2.6.1 → 2.6.2

Cycle release bundling 85 commits since the 2.6.1 cut on main. Version string bumped to 2.6.2 (commit 26eeb1e9). Bundles the unreleased 2.6.2 block and the in-flight 2.6.3 entries currently sitting on dev — both ship under the 2.6.2 tag.

Headline changes

New Sync-page tabs (4)

The Sync page absorbs four sources that previously lived only on the Discover page or had no first-class entry point at all. Each tab uses the same discovery → mirror → Auto-Sync flow as Spotify / Tidal / Qobuz / YouTube.

  • ListenBrainz — lists For You / My Playlists / Collaborative LB playlists. Once mirrored, LB playlists participate in Auto-Sync schedules + pipeline automations like any other source.
  • Last.fm Radio — sibling tab to ListenBrainz. Mirrors auto-trim when the Last.fm Radio cache rotates so old radios don't pile up.
  • SoulSync Discovery — personalized SoulSync Discovery playlists (decade mixes, hidden gems, popular picks, daily mixes, discovery shuffle). Clicking a card regenerates + mirrors under a stable synthetic id so the same mirror updates in place every Auto-Sync refresh.
  • iTunes / Apple Music Link — paste an Apple Music album / track / playlist URL. Handles the current SPA token shape; token gets scraped from the JS bundle on first use, cached for 6 hours, refetched on 401 if Apple rotates mid-session.

Backed by a new unified PlaylistSource adapter layer (core/playlists/sources/) — refresh handler shrunk from a ~190-line if/elif chain to ~80 lines that delegate to the source registry. Each source also implements a discover method on the same interface so LB / Last.fm tracks land already matched against Spotify / iTunes via the shared engine.

Auto-Sync manager overhaul

Top-to-bottom revamp of the Playlist Auto-Sync modal:

  • Performance: modal open dropped from ~1.5s to ~280ms (batched get_all_mirrored_playlist_status_counts instead of N per-playlist queries). Playlist sync itself is way faster on partial-match playlists thanks to a lazy per-artist track pool (4+ min → seconds on a 30-track playlist with 9 matches).
  • Bulk scheduling: each source group in the sidebar gets a Bulk button — schedule every playlist at once (1h / 2h / 4h / 8h / 12h / 16h / 24h / 48h / 72h / weekly, or custom interval). "Unschedule all" clears a source's schedules.
  • Custom interval columns: schedules with non-standard intervals (6h, 36h, etc.) now render as their own dashed-border column instead of disappearing because they didn't match a hardcoded bucket.
  • Filters + failure indicators: sidebar gets a playlist search input. Scheduled cards show a red ! badge when the last three pipeline runs failed, yellow ⚠ for at least one. Run history tab gains All / Errors / Completed filter pills, "Load more" pagination, and a "Run pipeline again" button inside the expanded detail panel.
  • Restyle: the whole modal now matches the rest of the app — standard SoulSync gradient + accent-tinted border, KPI summary as inset stat tiles, auto-fill pipeline monitor, underline-style tabs, dense dark-card schedule board sidebar. Picks up the user's chosen accent color instead of hardcoded sky-blue.
  • Fixes: hung-forever-on-loading-schedule bug (300k-track libraries hit a COLLATE NOCASE join that couldn't use indexes — ~3000x speedup by dropping NOCASE), in library always-showing-0 bug (query referenced a removed tracks.artist column), timezone offset on countdowns (~8h on Pacific time), run-history modal hardening.

Wishlist + album-bundle improvements

  • Wishlist albums-cycle now uses per-album release-first searches: instead of dumping every missing track into one big batch and running ~50 per-track Soulseek / Prowlarr searches, the albums cycle splits into per-album sub-batches at submission time. Each engages the existing slskd / torrent / usenet album-bundle release-first flow with the album's context.
  • Cycle toggle fires once per run, not per sub-batch: each wishlist invocation now stamps every sub-batch with a shared run id; cycle flip + completion event waits for the LAST sibling to finish.
  • Wishlist download modal tracks across every album: backend merges every sibling sub-batch's tasks + analysis results into the original batch id (re-indexes track positions globally, aggregates phase across siblings).
  • Album-bundle downloads all landing as track 1 — the staging-file reader was using the auto-import's filename extractor that defaults to 1 when no NN- prefix is present. Now uses a strict extractor that returns 0 when no explicit prefix exists, so the downstream resolver correctly falls through to Spotify metadata.
  • Whole-album downloads ending up "failed" with empty queues (#700) — staging match now pulls the trailing-title segment when a bare track-number is present between " - " delimiters so slskd filename patterns match cleanly.
  • Album tracks getting requeued as singles by the wishlist (#698) — album batches now carry source_type='album', source-context preserves album_context / artist_context, fallbacks default to album instead of single.

Fix popup / mirrored playlist back-sync

  • Manual matches survive Playlist Pipeline runs — three layered fixes: provider stamping no longer hardcodes 'spotify' (uses the actual source the popup matched against), prepare-discovery's drift check honours manual_match, and the discovery worker short-circuits on manual_match before the incomplete-data re-discovery branch. Pre-fix: manual fixes worked once, then flipped back to "Provider Changed" on the next Pipeline cycle.
  • MusicBrainz Fix popup: artist + track fields no longer surface unrelated covers — split-field input goes through a strict recording:"X" AND artist:"Y" query that anchors the artist. Falls back to bare query for diacritic mismatches (Bjork vs Björk). Results stable-prefer entries with known length so the canonical 3:04 sibling sits above the 0:00 duplicate.

Library + UX

  • Enhanced view toggle persists per browser — artist detail no longer reverts to Standard every time. Saved in localStorage scoped per profile so multiple admin profiles keep different defaults.
  • Quick Actions redesigned as asymmetric bento with signature animations and softer flow lines.
  • Redownload Album button on enhanced artist view restored (#699) — silently broken when script.js got split into 17 domain modules.

Quarantine / candidates

  • Songs stuck in quarantine loop when picking a different candidate (#701) — manual picks via the candidates modal now skip AcoustID for that one post-process pass (matching the Approve-on-restored-quarantine path). Integrity + bit-depth gates still run.

Telegram

  • Thread id support on Telegram notifications (community PR #594).

Code health

  • New core/discovery/manual_match.py extracts manual-fix provider derivation + provider-drift checks out of web_server.py route handlers — pinned by 12 unit tests.
  • New core/playlists/sources/ adapter layer (PlaylistSource ABC + registry).
  • Auto-Sync extracted into webui/static/auto-sync.js with node:test contract for its helpers.
  • Mirrored playlist pipeline lifted into core/playlists/pipeline.py (was inline in web_server.py).
  • Pre-existing ruff lint debt cleared (5 errors blocking CI) — duplicate urlparse import removed, four try/except/pass blocks tagged with # noqa: S110 — reason per existing convention, one zip() annotated with strict=False.

Test plan

  • [x] Full pytest: 4067 passed, 0 failed.
  • [x] python -m ruff check . clean.
  • [x] Live API smoke against local dev server for the MB Fix popup case (Coffee Break + Zeds Dead) — canonical 6e2d4a70 recording with length 184000ms ranks first; Björk diacritic case (Bjork + Army of Me) returns 10/10 Björk recordings via strict-empty → bare fallback.

Closes

#594, #697, #698, #699, #700, #701, #708 (community feedback batch)

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track SoulSync

Get notified when new releases ship.

Sign up free

About SoulSync

Automated Music Discovery and Collection Manager

All releases →

Beta — feedback welcome: [email protected]