docs: library comments say what the scanner and resolver do, not how they came to be (#6277)
release / govulncheck (push) Successful in 20s
release / web (push) Successful in 1m20s
release / go (push) Successful in 1m37s
release / integration (push) Successful in 5m15s
release / android (push) Successful in 5m26s
release / Build signed APK (releases and dev) (push) Successful in 5m45s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 16s
release / Verify release artifacts (tag releases only) (push) Skipped
release / govulncheck (push) Successful in 20s
release / web (push) Successful in 1m20s
release / go (push) Successful in 1m37s
release / integration (push) Successful in 5m15s
release / android (push) Successful in 5m26s
release / Build signed APK (releases and dev) (push) Successful in 5m45s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 16s
release / Verify release artifacts (tag releases only) (push) Skipped
Rewrites the internal/library comment blocks to rule 32. Task, milestone, decision and rule ids are gone; the incidents behind them are restated as the constraint they left (why a file is deleted before its row, why the missing mark is a mark, why duplicates block on duration). Counts and album names from one library are dropped from production comments; test comments keep the names their fixtures use. The tagReadVersion log keeps each version's before and after, without the measurements. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,7 @@ import (
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Duplicate classification (M498 #5435; settled further 2026-10-19).
|
||||
// Duplicate classification.
|
||||
//
|
||||
// A duplicate group is one recording found more than once. What should happen
|
||||
// to it depends on where the copies sit:
|
||||
@@ -19,15 +19,15 @@ import (
|
||||
// album it came from, a deluxe edition and the standard one, or one
|
||||
// recording a later release retitled ("The Ragtime Cat", "F.O.D. (live)",
|
||||
// a romanized title): each copy belongs to its own release, so none is
|
||||
// deleted (unless it is a video rip; the resolver decides). The measured
|
||||
// library (2026-10-19) had 451 such groups waiting on the operator under
|
||||
// different titles, and they were retitles, not different songs.
|
||||
// deleted (unless it is a video rip; the resolver decides). Copies under
|
||||
// different titles on different releases are retitles, not different
|
||||
// songs.
|
||||
// - distinct: one album, two versions of a song that sound alike, named as
|
||||
// such ("Lovesick", "Lovesick (Instrumental)"). Not duplicates.
|
||||
// - mismatch: one album holds the same audio under different song titles:
|
||||
// one file filling several track slots, a broken download. Which slot is
|
||||
// right is the resolver's to decide from MusicBrainz's track lengths.
|
||||
// - review: what none of these fits. The operator decides.
|
||||
// - review: what none of these fits. An admin decides.
|
||||
|
||||
// DuplicateClass is a group's shape. The values are duplicate_groups.class.
|
||||
type DuplicateClass string
|
||||
@@ -54,8 +54,8 @@ type ClassifyMember struct {
|
||||
// adds to a title (featuring credits, remaster notes, video markers) and keeps
|
||||
// what names a different recording (live, demo, remix, instrumental). On one
|
||||
// album, titles that differ only by such a word are two versions (distinct)
|
||||
// unless the bytes are identical, which is one file twice: the #3885 case of
|
||||
// "WWW" and "WWW (instrumental)" holding the same file is a wrong slot.
|
||||
// unless the bytes are identical, which is one file twice: "WWW" and "WWW
|
||||
// (instrumental)" holding the same file is a wrong slot.
|
||||
func ClassifyDuplicateGroup(tier string, members []ClassifyMember) DuplicateClass {
|
||||
if len(members) < 2 {
|
||||
return ClassReview
|
||||
@@ -136,7 +136,8 @@ func songKey(title, artist string) string {
|
||||
var (
|
||||
// A bracketed credit: "(feat. Panda Bear)", "[ft. X]", "(featuring Y)".
|
||||
featBracket = regexp.MustCompile(`(?i)[(\[][^)\]]*\b(feat\.?|ft\.?|featuring)\s[^)\]]*[)\]]`)
|
||||
// A credit trailing the title without brackets: "Doin' It Right ft. Panda Bear".
|
||||
// A credit trailing the title without brackets: "Doin' It Right ft. Panda
|
||||
// Bear".
|
||||
featTrailing = regexp.MustCompile(`(?i)\s(feat\.?|ft\.?|featuring)\s.*$`)
|
||||
// "(2011 Remaster)", "[Remastered]", "- Remastered 2009".
|
||||
remasterBracket = regexp.MustCompile(`(?i)[(\[][^)\]]*remaster[^)\]]*[)\]]`)
|
||||
@@ -149,10 +150,11 @@ var (
|
||||
// whether two copies carry the same one.
|
||||
//
|
||||
// Dropped: a leading "Artist - " (a video upload's title), bracketed featuring
|
||||
// credits and remaster notes, and bracketed segments carrying a video-rip marker
|
||||
// ("(Official Video)", "[HD]"). Kept: every other bracketed word, so "(live)",
|
||||
// "(demo)", "(acoustic)", "(remix)" and "(instrumental)" still tell recordings
|
||||
// apart. Then case, "&" against "and", and punctuation and spacing are ignored.
|
||||
// credits and remaster notes, and bracketed segments carrying a video-rip
|
||||
// marker ("(Official Video)", "[HD]"). Kept: every other bracketed word, so
|
||||
// "(live)", "(demo)", "(acoustic)", "(remix)" and "(instrumental)" still tell
|
||||
// recordings apart. Then case, "&" against "and", and punctuation and spacing
|
||||
// are ignored.
|
||||
func MatchTitleKey(title, artist string) string {
|
||||
t := strings.TrimSpace(title)
|
||||
if a := strings.TrimSpace(artist); a != "" {
|
||||
|
||||
Reference in New Issue
Block a user