Match: update state for displaced Apple tracks #39

Closed
opened 2026-09-05 21:50:36 +00:00 by hermes · 1 comment
Owner

Context

Independent review of the SPEC reconciliation found that moving a beets item from Apple track A to Apple track B updates B to matched but can leave A persisted as matched after its last association is removed. That violates the state invariant in SPEC.md §7 and causes incorrect list-tracks output.

Task

When explicit or interactive matching reassigns an item already associated with another retained Apple track, reconcile the displaced track from its remaining beets associations and mark the selected track matched. Preserve a displaced permanent skip, and do not fail when the displaced Apple ID has no plugin-state row.

Acceptance criteria

  • Focused regression tests reproduce the stale state for explicit and interactive matching.
  • A displaced retained track with no association becomes unmatched.
  • One remaining association produces matched; multiple remaining associations produce ambiguous.
  • A displaced permanent skip remains skipped.
  • The selected track becomes matched and owns the beets association.
  • Dry-run remains non-mutating.
## Context Independent review of the SPEC reconciliation found that moving a beets item from Apple track A to Apple track B updates B to `matched` but can leave A persisted as `matched` after its last association is removed. That violates the state invariant in `SPEC.md` §7 and causes incorrect `list-tracks` output. ## Task When explicit or interactive matching reassigns an item already associated with another retained Apple track, reconcile the displaced track from its remaining beets associations and mark the selected track `matched`. Preserve a displaced permanent skip, and do not fail when the displaced Apple ID has no plugin-state row. ## Acceptance criteria - [ ] Focused regression tests reproduce the stale state for explicit and interactive matching. - [ ] A displaced retained track with no association becomes `unmatched`. - [ ] One remaining association produces `matched`; multiple remaining associations produce `ambiguous`. - [ ] A displaced permanent skip remains `skipped`. - [ ] The selected track becomes `matched` and owns the beets association. - [ ] Dry-run remains non-mutating.
Author
Owner

Completed in coop/beets-appleplaylists by implementation commit cc124c9, merged through PR #41 as e4fbbffd4a0bf744d4967c6bfb03e4ffe369869a.

Explicit and interactive matching now reconcile the displaced track from its remaining association count, preserve displaced permanent skips, tolerate absent historical state rows, and set the selected track to matched.

Validation: 104 tests passed with warnings promoted to errors, plus Ruff lint, compileall, isolated CLI help, package build, and git diff --check.

Completed in `coop/beets-appleplaylists` by implementation commit `cc124c9`, merged through PR #41 as `e4fbbffd4a0bf744d4967c6bfb03e4ffe369869a`. Explicit and interactive matching now reconcile the displaced track from its remaining association count, preserve displaced permanent skips, tolerate absent historical state rows, and set the selected track to `matched`. Validation: 104 tests passed with warnings promoted to errors, plus Ruff lint, compileall, isolated CLI help, package build, and `git diff --check`.
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#39
No description provided.