Taxonomy is compiled. The alias map in genre.rs cannot be changed at runtime. If the user disagrees with a mapping, the agent works around it by using the user’s preferred genre directly.
No auto-tagging. Every genre change requires explicit human approval.
Cache-first. Classification runs from cached data. If cache is empty for a track, it is flagged as insufficient evidence — do not trigger enrichment mid-classification.
XML export only. No direct DB writes. All changes flow through update_tracks → preview_changes → write_xml.
Per-track reasoning is mandatory for low/insufficient confidence. Do not skip or batch-approve these tracks. Delegate to subagents if the volume is large.
Prerequisites
cache_coverage(has_genre=false)
All providers must be at 100% before proceeding. If not, hydrate first:
Repeat until all providers reach 100%. Report progress between batches.
All classify_tracks calls support max_tracks (default 50, max 200) and offset for pagination. Continue until all tracks are covered.
Steps
1. Normalize aliases
suggest_normalizations(stage_aliases=true)
This auto-stages all non-debatable alias mappings (e.g. Hip-Hop → Hip Hop, DnB → Drum & Bass) and returns grouped results showing each mapping and its track count.
Review the staged aliases. If any are debatable, unstage them with clear_changes(track_ids=[...]) and ask the user. Store overrides for Step 2.
Unknown genres (non-canonical, no alias mapping) will be classified in Step 2 using the has_unknown_genre filter.
2. Classify and get approval policy
Get the confidence distribution first using format="summary":
What the decision tree already considered:
BPM range plausibility, Beatport/Discogs genre tags, label-genre mapping, audio energy profile, same-family depth resolution.
What you add:
Artist reputation beyond this library, label/scene context, remix conventions (e.g. remixer known for a specific genre), title interpretation.
Workflow:
Call get_genre_taxonomy() to load the canonical genre list — only recommend genres from this list
Review the evidence and flags included with each track
Check if the artist has other genred tracks in the library via search_tracks where useful
Consider artist reputation, label identity, and track title
Recommend a canonical genre with one-sentence reasoning
After classifying all tracks, stage your recommendations via update_tracks
Output format:
#N Artist — Title
Evidence: [key signals from the evidence array]
Library: [artist's other genres, or "no other tracks"]
Recommend: GENRE — [why]
Tracks to classify:
[track list here]
4.3 Verify staged results
Once all subagents have completed, verify the aggregate results:
preview_changes(format="summary")
Compare the staged track count against dispatch_stats.total_tracks from Step 4.1 (plus any tracks staged in Step 3). If the staged count is lower than expected, identify which artist batches may have failed and report them to the user.
Present the summary to the user. Report: "Review complete: N tracks staged across M genres."
Ask: “Any genres or artists you want to review before export?“
5. Export
preview_changes(format="summary")
Ask user: “Export these changes to XML?”
write_xml()
Report output path, then walk the user through the Rekordbox import:
Add XML to Rekordbox — Open Preferences → Advanced → rekordbox xml → Imported Library → Browse → select the exported XML file.
Open the XML view — In the sidebar, click the “Display rekordbox xml” icon. The imported tracks appear under “All Tracks”.
Import into collection — Select all tracks (Cmd+A), right-click → Import To Collection. When prompted “Do you want to load information in the tag of the library being imported?”, click Yes (tick “Don’t ask me again” for bulk imports).