A single and its album copy are linked as one song. A like on either covers both, the Liked list shows the song once, and radio and the mixes pick one copy.
On first start, the resolver pass acts on its own (auto_resolve defaults to on). It deletes files Lidarr holds unmapped, changes repeating Lidarr releases (at most 10 per pass, then leaves each album alone for 24h), links songs across releases, and holds rips back.
Milestone 498, plus the CI change from #5426.
**Duplicates (#5435–#5437)**
- The hourly resolver classifies every duplicate group: same release, across releases, mismatch, or review.
- It merges copies Lidarr doesn't use into the copy it does use. A copy Lidarr maps is never removed; the guard is tested.
- It switches a Lidarr album off a release that lists songs twice (the Humanz box set) to one that doesn't.
- Admin → Duplicates has three tabs: Needs review, Across releases, Resolved automatically.
- One setting, on by default, turns automatic resolving off.
**One song across releases (#5438)**
- A single and its album copy are linked as one song. A like on either covers both, the Liked list shows the song once, and radio and the mixes pick one copy.
- "Not the same song" undoes the link.
**Video rips (#5439)**
- Rips are held back from radio and the mixes. Suspect sources offers "This one is fine" to let a track back.
- A stray unmapped copy on another release is merged into the copy Lidarr uses.
**Migrations:** 0075 (duplicate classes, Lidarr state, auto_resolve, notification kind), 0076 (tracks.song_id and song_key), 0077 (tracks.source_verdict).
**On first start,** the resolver pass acts on its own (auto_resolve defaults to on). It deletes files Lidarr holds unmapped, changes repeating Lidarr releases (at most 10 per pass, then leaves each album alone for 24h), links songs across releases, and holds rips back.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
On first boot the postgres image runs initdb under a temporary server that
listens on the unix socket only, then stops it. The socket readiness probe
could catch that server, and the fsync relax then hit 'the database system
is shutting down', leaving the suite ~15x slower on internal/api. Only the
real server listens on TCP, so probe and relax via -h 127.0.0.1, retry the
relax, and print the settings that took effect.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The duplicate sweep proposed 4,197 groups and every one waited for the
operator. Most are safe to settle, and Lidarr defines what safe means: it
maps one file to each track of the release it monitors and downloads any
mapped file that disappears. Deleting a mapped copy opens exactly the hole
the operator saw Lidarr fill.
Classify (#5435)
- Migration 0075: duplicate_groups.class (same_release, cross_release,
mismatch, review), resolve_note, resolved_automatically;
duplicate_group_members.lidarr_state (tracked, unmapped);
fingerprint_settings.auto_resolve; notification kind
duplicates_resolved with both kind CHECKs swapped (rule 36).
- library.ClassifyDuplicateGroup, with MatchTitleKey dropping featuring
credits, remaster notes and video-rip markers, and keeping live, demo,
remix and instrumental. The rip markers move from api to library.
Choose the copy to keep (#5436)
- ProposeSurvivor ranks the copy Lidarr maps first, then tag fit (a
clash-free track number, no rip marker in the name, an MBID), then the
quality rules. File size picked the wrong Humanz copy in 6 of 21 groups.
Act (#5437)
- An hourly resolver pass reads Lidarr's unmapped files, matched by the
last three path components, and records each copy's state.
- Same album, with at most one copy mapped: merged into the mapped copy.
The merge is guarded, so a mapped copy can never be removed
(MergeDuplicateGroupGuarded, ErrCopyTrackedByLidarr).
- Same album, every copy mapped: the monitored release lists the song
twice (Humanz's 14x12" box set). The pass moves Lidarr to the release
that lists each song once and best covers what is on disk. It never
picks one covering less, and is capped at 10 albums per pass.
- Fixed point (lesson #4183): the chosen release no longer repeats.
- The album is left alone for 24h while Lidarr rescans, so "every copy
unmapped" mid-rescan is never read as licence to merge.
- Both actions are audited with no actor and summarised to admins. The
operator can switch them off in the Fingerprinting card (rule 25).
- Manual merges use the same guard: 409 copy_tracked_by_lidarr, or 503
lidarr_unavailable when Lidarr cannot say.
Web
- Duplicates gets tabs: Needs review, Across releases, Resolved
automatically. Each loads as you scroll (rule 172), replacing the
pager.
- Each copy says whether Lidarr uses it.
- The resolver's note shows on each group.
- The merge confirm blocks, before sending, a merge that would remove
the copy Lidarr uses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A single and the album it is on stay two files, since each fulfils its own
release in Lidarr, but they are one song to the listener.
- tracks.song_id links copies; the generated song_key (song_id, else the
track's own id) is what they share (migration 0076).
- The resolver links each cross-release group every pass (idempotent; only
with auto-resolve on) and, when a link is new, shares existing likes across
the song and logs them for sync.
- A like or unlike (web and Subsonic) reaches every copy; each change is
logged and published so clients update every heart.
- The Liked list and its count show the song once; Shuffle and the mix writer
take one copy per song.
- A merge keeps the removed copy's song link; "Not the same song" on the
Across releases tab dismisses the group and undoes the link.
Shared plays ("heard via another copy") are left for a later step.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The resolver also merges cross-release and mismatch groups where Lidarr
maps exactly one copy: the others fulfil nothing, so removing them opens no
hole (D-a rule 1). That covers a rip beside the clean copy on another
release and a wrong-file import Lidarr holds unmapped. With two or more
mapped copies each fulfils its own release and nothing is removed.
- A track whose file name carries a video-rip marker is held back from radio
and the system mixes (tracks.source_verdict, migration 0077). It still plays
when chosen. A renamed file is released; the operator's "fine" sticks.
- Suspect sources shows what was done to each track, with "This one is fine"
and "Hold back again" (PUT /api/admin/library/suspect-sources/{id}).
- The Liked list prefers a copy that is not held back.
Replacing a rip that has no clean copy is left for the operator to decide.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Milestone 498, plus the CI change from #5426.
Duplicates (#5435–#5437)
One song across releases (#5438)
Video rips (#5439)
Migrations: 0075 (duplicate classes, Lidarr state, auto_resolve, notification kind), 0076 (tracks.song_id and song_key), 0077 (tracks.source_verdict).
On first start, the resolver pass acts on its own (auto_resolve defaults to on). It deletes files Lidarr holds unmapped, changes repeating Lidarr releases (at most 10 per pass, then leaves each album alone for 24h), links songs across releases, and holds rips back.
🤖 Generated with Claude Code
A single and the album it is on stay two files, since each fulfils its own release in Lidarr, but they are one song to the listener. - tracks.song_id links copies; the generated song_key (song_id, else the track's own id) is what they share (migration 0076). - The resolver links each cross-release group every pass (idempotent; only with auto-resolve on) and, when a link is new, shares existing likes across the song and logs them for sync. - A like or unlike (web and Subsonic) reaches every copy; each change is logged and published so clients update every heart. - The Liked list and its count show the song once; Shuffle and the mix writer take one copy per song. - A merge keeps the removed copy's song link; "Not the same song" on the Across releases tab dismisses the group and undoes the link. Shared plays ("heard via another copy") are left for a later step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>- The resolver also merges cross-release and mismatch groups where Lidarr maps exactly one copy: the others fulfil nothing, so removing them opens no hole (D-a rule 1). That covers a rip beside the clean copy on another release and a wrong-file import Lidarr holds unmapped. With two or more mapped copies each fulfils its own release and nothing is removed. - A track whose file name carries a video-rip marker is held back from radio and the system mixes (tracks.source_verdict, migration 0077). It still plays when chosen. A renamed file is released; the operator's "fine" sticks. - Suspect sources shows what was done to each track, with "This one is fine" and "Hold back again" (PUT /api/admin/library/suspect-sources/{id}). - The Liked list prefers a copy that is not held back. Replacing a rip that has no clean copy is left for the operator to decide. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>