Plugin: matching policy rework (precedence, ambiguity, normalization, apple_music_id) #29

Closed
opened 2026-08-19 18:32:55 +00:00 by hermes · 0 comments
Owner

Context

SPEC.md §9 (matching policy) and §8 (beets item metadata). Current matching.py violates it in several ways: setdefault silently picks the first of multiple candidates (no ambiguity state), normalization strips all punctuation (SPEC forbids), no duration tolerance, no existing-association precedence, no apple_music_id usage.

Task

  • Automatic precedence, in order:
    1. existing apple_music_id association on a beets item;
    2. exactly one local item matching the Apple ISRC;
    3. exactly one strong metadata candidate;
    4. otherwise unresolved → match workflow.
  • Strong metadata matching:
    • normalization = NFKC + case-fold + trim/collapse whitespace + typographic apostrophe/dash normalization; arbitrary punctuation is not stripped;
    • exact normalized artist match AND exact normalized title match;
    • if both durations present: absolute difference ≤ 2 seconds; missing duration on either side is ignored;
    • album is not used — neither qualifies nor rejects.
  • Exactly one qualifying candidate auto-matches; multiple remain ambiguous (persisted state). No fuzzy matching without explicit user approval; never re-prompt after an explicit association.
  • Beets metadata rules:
    • write apple_music_id on association; explicit match may replace it; normal sync trusts existing associations;
    • write Apple ISRC to the item's isrc only when local is empty; never overwrite non-empty local ISRC;
    • Apple/local ISRC conflicts are reported (feeds ISRC_CONFLICT in list-tracks), never auto-resolved;
    • never write audio-file tags; never auto-remove metadata.
  • Local metadata always wins over conflicting Apple metadata.

Acceptance criteria

  • All four precedence levels implemented and tested.
  • Ambiguity persisted as a resolution state, not silently resolved.
  • Normalization matches SPEC exactly (incl. punctuation preserved, apostrophe/dash folding).
  • Duration tolerance and missing-duration handling tested.
  • apple_music_id/ISRC write rules tested incl. never-overwrite and conflict reporting.

Ref: SPEC.md §8, §9.

## Context SPEC.md §9 (matching policy) and §8 (beets item metadata). Current `matching.py` violates it in several ways: `setdefault` silently picks the first of multiple candidates (no ambiguity state), normalization strips all punctuation (SPEC forbids), no duration tolerance, no existing-association precedence, no `apple_music_id` usage. ## Task - Automatic precedence, in order: 1. existing `apple_music_id` association on a beets item; 2. exactly one local item matching the Apple ISRC; 3. exactly one strong metadata candidate; 4. otherwise unresolved → `match` workflow. - Strong metadata matching: - normalization = NFKC + case-fold + trim/collapse whitespace + typographic apostrophe/dash normalization; **arbitrary punctuation is not stripped**; - exact normalized artist match AND exact normalized title match; - if both durations present: absolute difference ≤ 2 seconds; missing duration on either side is ignored; - album is not used — neither qualifies nor rejects. - Exactly one qualifying candidate auto-matches; multiple remain `ambiguous` (persisted state). No fuzzy matching without explicit user approval; never re-prompt after an explicit association. - Beets metadata rules: - write `apple_music_id` on association; explicit `match` may replace it; normal sync trusts existing associations; - write Apple ISRC to the item's `isrc` **only when local is empty**; never overwrite non-empty local ISRC; - Apple/local ISRC conflicts are reported (feeds `ISRC_CONFLICT` in `list-tracks`), never auto-resolved; - never write audio-file tags; never auto-remove metadata. - Local metadata always wins over conflicting Apple metadata. ## Acceptance criteria - [ ] All four precedence levels implemented and tested. - [ ] Ambiguity persisted as a resolution state, not silently resolved. - [ ] Normalization matches SPEC exactly (incl. punctuation preserved, apostrophe/dash folding). - [ ] Duration tolerance and missing-duration handling tested. - [ ] `apple_music_id`/ISRC write rules tested incl. never-overwrite and conflict reporting. Ref: SPEC.md §8, §9.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coop/beets-appleplaylists#29
No description provided.