# AGENT BRIEF — `spotify-library-taxonomy-fixer` (`Library Atlas` & `Music Brain` v1.2)

**Handoff Type**: `implementation` (authoritative cold-start handoff & bundle index for downstream Perplexity Computer, Claude Code, Cursor, or Flyway agents).  
**First Deliverable Owned by Next Agent**: Execute incremental Spotify delta extraction, apply pending subgenre/smart-crate write-backs when authorized, or wire `chirp_crates.json` / `algo_playlists.json` (`chirp.av_core.set.v1`) into `venkatron/Chirp` (`CHIRP` decks, `SHRIKE` beat-slicer, `CLUTCH` pattern bench, `ROOKERY` Suno intake) without reconstructing session history.

```text
OPEN: venkatron/spotify-library-taxonomy-fixer (branch: main) or Perplexity Project "Spotify Library Taxonomy & Faceted Atlas" (8047f8d5-908c-4c97-a488-2de89b243a0b)
READ: AGENT-BRIEF.md -> ONE_PAGER.md -> MUSIC_BRAIN.md -> taxonomy.yaml
DO:
  1. Run `python3 verify_fixture.py` (offline 41-track smoke test; must pass all 5-axis, BPM/Camelot, and Smart Crate assertions).
  2. Inspect `verified_playlists.json` and `music_brain.json` (schema v1.2) to see the 86 live Spotify playlists and 5-axis state before touching `library.db`.
  3. Follow Playbook A (Incremental Spotify Delta), Playbook B (Spotify Write-Back), Playbook C (Chirp / DJ Interop), or Playbook D (Web Deployment) below based on the user's request.
PROTECT:
  - NEVER run `08_unlike.py --apply` or unlike any Spotify tracks (bulk unliking is explicitly deferred).
  - NEVER overwrite `classification.override` or rows where `classification.facets_locked = 1`.
  - NEVER commit `config.json` or `.tokens.json` to git or deploy them to `public/`.
VALIDATE:
  - `python3 verify_fixture.py` -> exits 0 (`ALL OFFLINE VERIFICATION CHECKS PASSED`).
  - `python3 11_algo_playlists.py` -> generates 7 sets (`168` tracks) in `algo_playlists.json` & `public/algo_playlists.json`.
  - `git status -s` -> confirms `config.json` and `.tokens.json` are absent before any commit or deploy.
STOP AFTER: Completing the bounded playbook requested by the user and syncing `public/` + `ONE_PAGER.md` + `MUSIC_BRAIN.md`.
```

---

## 1. Reconciled Current State (`2026-10-22 · v3`)

| Layer / Surface | Current Verified State | Source of Truth |
|---|---|---|
| **SQLite Library (`library.db`)** | **17,686 unique tracks** (`14,504` Liked Songs + `3,182` owned-playlist tracks across `24,601` `track_sources` links); **7,577** Last.fm-enriched artists with `tag_weights` (`0–100`). | `library.db` (tracked in repo; local Windows checkout at `C:\Users\aravi\spotify-library-taxonomy-fixer\library.db` needs `git pull`) |
| **5-Axis Classification (`03_classify.py`)** | **99.6% classified** (`17,620` classified into `13` L1 genres / `69` leaf subgenres; `66` unsorted). Includes **26 orthogonal facets** across Mood (`6`), Region/Scene (`8`), Style Signatures (`7`), and Producer Sample Role (`5`). **454** co-artist Last.fm homonyms (e.g. `Savon` on Sango tracks) rescued via `--populate-facets`. | `taxonomy.yaml`, `03_classify.py`, `viewer_data.json` |
| **Stage 10 Audio DSP Sidecar (`10_audio_features.py`)** | **100% populated** (`17,686` tracks) with `bpm`, `half_time_bpm` (`85↔170` / `70↔140`), `key_camelot` (`1A–12B`), and `audio_source` (`preview_dsp`, `acousticbrainz`, `tag_parsed`, `taxonomy_corridor`). Dominant minor hubs: `5A` (`3,142`), `8A` (`3,116`), `6A` (`2,059`), `7A` (`1,942`). | `10_audio_features.py`, `library.db` (`tracks` table columns) |
| **Stage 09 Music Brain & Chirp Manifest (`09_music_brain.py`)** | Emits `music_brain.json` (`schema_version: "1.2"`) and `chirp_crates.json` (`chirp.crate.manifest.v1`) with `chirp_deck_config`, `shrike_slice_config`, `suno_bridge` (`STYLE:`/`EXCLUDE:` recipes), and top 25 sample donors for each of the **8 Smart Crates**. | `09_music_brain.py`, `music_brain.json`, `chirp_crates.json`, `MUSIC_BRAIN.md` |
| **Stage 11 Algorithmic Set Studio (`11_algo_playlists.py`)** | Sequences non-subtree playlists across **5 modes** (`seed_walk`, `wormhole`, `energy_arc`, `sample_pack`, `deep_cuts`) using Camelot wheel compatibility (`0–4.0 pts`), BPM/half-time bridges (`0–3.5 pts`), and cross-genre facet affinity (`0–5.0 pts`). Exports to Spotify (`LA_Algo_*`), Serato DJ Pro (`.m3u8`), Algoriddim `djay Pro` (`.rekordbox.xml`), and `Chirp` AV Core (`chirp.av_core.set.v1`). | `11_algo_playlists.py`, `algo_playlists.json`, `viewer.html` (`#algoPanel`) |
| **86 Verified Live Spotify Playlists (`05_write_back.py`)** | **100% verified (`HTTP 200 OK`)** against `GET /v1/playlists/{id}` on `2026-10-22`:<br>• **7 `LA_Algo_*` Sets**: **`168` tracks live on Spotify** = `168` in `algo_playlists.json` (100% 1:1 synced).<br>• **79 `LA_*` Subgenre Playlists**: **`16,227` tracks live on Spotify** (Sept 1, 2026 run) vs. **`16,513` deduplicated tracks** in the reclassified `library.db` plan (`+286` net delta not yet re-applied to the 79 subgenre playlists). | `05_write_back.py`, `verified_playlists.json`, `ONE_PAGER.md` |
| **Live Web Deployments (`public/`)** | • **Interactive Explorer**: https://library-atlas.pplx.app · https://spotify-library-taxonomy-fixer.pages.dev<br>• **Published One-Pager**: https://library-atlas.pplx.app/one-pager.html · https://spotify-library-taxonomy-fixer.pages.dev/one-pager | `viewer.html` (`public/index.html`), `one-pager.html` (`public/one-pager.html`) |

---

## 2. Decision Boundaries (`Settled` vs. `Pending on Request` vs. `Forbidden`)

### Settled State (Do Not Regress)
1. **Playlist Naming Convention (`LA_` prefix)**: `config.json` uses `"playlist_prefix": "LA_"` (`LA_Elec_*`, `LA_HipHop_*`, `LA_Algo_*`, `LA_Crate_*`). `common.py` defaults to `"[GS] "` only if `playlist_prefix` is omitted from `config.json`. Always preserve `"playlist_prefix": "LA_"` when creating a temporary `config.json`.
2. **Weighted Last.fm + Co-Artist Homonym Rescue**: `03_classify.py` uses weighted tag sums (`2x` track-tag weight, `1.35x` leaf specificity over `_other` buckets) and rescues first-listed collaborator homonyms (such as `Savon` on Sango tracks) using library-frequency-weighted co-artist tags (`--populate-facets`).
3. **5 Orthogonal Axes**:
   - Axis 1 (`subgenre`, 1:1): `13` L1 genres → `69` leaf subgenres.
   - Axis 2 (`moods`, multi-label): `hype_club`, `hypnotic_grooves`, `late_night`, `euphoric_uplifting`, `chill`, `cinematic_epic`.
   - Axis 3 (`scenes`, multi-label): `uk_continuum`, `japanese_ost_citypop`, `global_lounge_dub`, `anatolian_levantine`, `desi_diaspora`, `soulection_future_beats`, `baile_favela`, `african_diaspora`.
   - Axis 4 (`styles`, multi-label): `four_on_the_floor_hypnotic`, `hybrid_orchestral_brass`, `sliding_808_drill_trap`, `dub_delay_sitar_lounge`, `chopped_vocal_flip`, `amen_break_roller`, `baile_tamborzao_percussion`.
   - Axis 5 (`sample_roles`, multi-label SHRIKE utility): `chord_bed_donor`, `horn_sting_donor`, `tempo_bridge_pivot`, `vocal_chop_donor`, `drum_break_donor`.

### Pending / Authorized Only on Explicit User Request
1. **Syncing the `+286` Reclassified Subgenre Deltas to the 79 `LA_*` Spotify Playlists**:
   - The 7 `LA_Algo_*` playlists were applied (`05_write_back.py --only-algo --apply`), while the 79 `LA_*` subgenre playlists on Spotify still hold their Sept 1, 2026 track lists (`16,227` tracks vs. `16,513` in the reclassified plan, plus 9 new leaf keys totaling 58 tracks). Run `python3 05_write_back.py --apply` **only** when the user asks to sync subgenre playlists.
2. **Syncing the 8 Cross-Facet Smart Crates (`LA_Crate_*`) to Spotify**:
   - Currently dry-run (`6,177` total memberships across 8 crates). Run `python3 05_write_back.py --smart-playlists --apply` **only** when the user asks to materialize Smart Crates as Spotify playlists.
3. **Pulling New Spotify Likes since Sept 1, 2026**:
   - Requires Spotify OAuth (`config.json` + `.tokens.json`). Run `python3 01_extract.py` → `02_enrich.py` → `03_classify.py` → `10_audio_features.py` → `04_review.py` → `09_music_brain.py` → `11_algo_playlists.py`.

### Deferred / Forbidden
- **Bulk Unliking (`08_unlike.py`)**: Explicitly deferred by user instruction (`"i dont want to tdo the bulk unlike just yet"`). Never run `08_unlike.py --apply`.
- **Committing Credentials**: Never leave `config.json` or `.tokens.json` in the working tree when committing or deploying.

---

## 3. Ordered Playbooks for Next Agents

### Playbook A — Incremental Scan on Newly Liked Spotify Songs
```bash
# 1. Extract newest liked songs (stops automatically on first known track in library.db)
python3 01_extract.py
# 2. Enrich new artists & multi-genre tracks via Last.fm + MusicBrainz
python3 02_enrich.py --refresh-weights
# 3. Classify new tracks & populate 5-axis facets (preserves manual overrides & facets_locked=1)
python3 03_classify.py
python3 03_classify.py --populate-facets
# 4. Populate BPM, Half-Time BPM & Camelot Key sidecar
python3 10_audio_features.py
# 5. Rebuild viewer_data.json, music_brain.json, chirp_crates.json & algo_playlists.json
python3 04_review.py
python3 09_music_brain.py
python3 11_algo_playlists.py
```

### Playbook B — Non-Destructive Spotify Write-Back (`05_write_back.py`)
```bash
# Dry-run preview (always run first and show user the diff):
python3 05_write_back.py --only-algo          # preview 7 LA_Algo_* sets (168 tracks)
python3 05_write_back.py                      # preview 79+ LA_* subgenre playlists
python3 05_write_back.py --smart-playlists    # include 8 LA_Crate_* smart crates

# Apply to Spotify (ONLY after user confirmation):
python3 05_write_back.py --only-algo --apply
```

### Playbook C — Downstream `venkatron/Chirp` (`CHIRP` / `SHRIKE` / `CLUTCH` / `ROOKERY`) Integration
- **Smart Crates Handoff (`chirp_crates.json`, schema `chirp.crate.manifest.v1`)**:
  - Load `crates[crate_key].chirp_deck_config` (`target_bpm`, `half_time_bridge_bpm`, `camelot_hubs`, `eq_crossfader_mode`, `register_occupancy`) into `CHIRP` 2-deck mixer.
  - Load `crates[crate_key].shrike_slice_config` (`recommended_sample_roles`, `high_pass_hz`, `slice_grid`) and `top_donor_tracks` into `SHRIKE` 8-slice beat chopper.
  - Load `crates[crate_key].suno_bridge` (`style`, `exclude`, `lyrics`) into `ROOKERY` Suno prompt generator.
- **Sequenced Algorithmic Set Handoff (`algo_playlists.json` or browser export `.chirp-set.json`, schema `chirp.av_core.set.v1`)**:
  - Contains `deck_routing` (`Deck A` / `Deck B` alternation), `transition_type` (`half_time_pivot`, `harmonic_lock`, `tempo_glide`), `shrike_slice_grid`, and `molt_reactive_preset` (`baile_brass_strobe`, `reese_sub_nebula`, `mecha_hud_oscilloscope`, `dub_echo_horizon`, `camelot_prism_pulse`).

### Playbook D — Deploying Updates to `pplx.app` and Cloudflare Pages
1. Copy updated `viewer.html` to `public/index.html` and `public/viewer.html`, and ensure `public/one-pager.html`, `public/viewer_data.json`, `public/music_brain.json`, `public/chirp_crates.json`, `public/algo_playlists.json`, and `public/verified_playlists.json` are up to date.
2. Push to `origin/main` (`venkatron/spotify-library-taxonomy-fixer`).
3. If Cloudflare Pages automatic GitHub build hits a transient error, trigger a deployment via API:
   `POST https://api.cloudflare.com/client/v4/accounts/69bdf46c63b4748598a83348b13553cd/pages/projects/spotify-library-taxonomy-fixer/deployments` with `{"branch":"main"}`.
4. Sync `/home/user/workspace/library-atlas-preview/` and publish to `https://library-atlas.pplx.app` (`site_id: cc4bcbf1-1dbf-4981-85fb-456207958b41`, `asset_id: e4f6e489-0670-47fc-afc7-8986811e5018`).

---

## Bundle Contents

| Path | State | Recipient Use |
|---|---|---|
| `AGENT-BRIEF.md` | Authoritative | Primary cold-start handoff, invariants, playbooks, and bundle index. |
| `ONE_PAGER.md` & `one-pager.html` (`public/one-pager.html`) | Authoritative | Visual & Markdown system one-pager containing all **86 verified live Spotify playlist links** and counts. |
| `MUSIC_BRAIN.md` & `music_brain.json` (`public/music_brain.json`) | Authoritative | Music Brain Taste Graph (`v1.2`), Suno prompt recipes, 5-axis summary, and verified playlist manifest. |
| `chirp_crates.json` (`public/chirp_crates.json`) | Authoritative | `chirp.crate.manifest.v1` handoff for `CHIRP`, `SHRIKE`, `CLUTCH`, and `ROOKERY`. |
| `algo_playlists.json` (`public/algo_playlists.json`) | Authoritative | 7 sequenced non-subtree algorithmic sets (`168` tracks) generated by `11_algo_playlists.py`. |
| `verified_playlists.json` (`public/verified_playlists.json`) | Authoritative | Machine-readable audit of all 86 live Spotify playlists (`sp_total` vs. `plan_total`, `spotify_id`, `url`). |
| `taxonomy.yaml` | Authoritative | 13 L1 genres, 69 leaf subgenres, 26 facets across 4 orthogonal axes (`moods`, `scenes`, `styles`, `sample_roles`), and 8 `_playlists` Smart Crates. |
| `01_extract.py` – `11_algo_playlists.py`, `common.py` | Authoritative | 11-stage Python pipeline scripts operating on `library.db`. |
| `viewer.html` (`public/index.html`, `public/viewer.html`) | Authoritative | 5-Axis Library Atlas + Smart Crates Studio + Algorithmic Set & Playlist Studio (`#algoPanel`) + One-Pager (`#guidePanel`). |
| `verify_fixture.py` & `fixture.db` | Authoritative | Zero-network 41-track regression test suite. |
| `08_unlike.py` | Parked / Deferred | Dry-run unlike script — **do not execute with `--apply`**. |

## Exclusions
- `config.json` and `.tokens.json` are excluded from the repository and deployment bundles (`gitignore`d). Obtain credentials from the user's local machine (`C:\Users\aravi\spotify-library-taxonomy-fixer\`) or secure session input only when live Spotify/Last.fm API calls are required, and delete temporary copies immediately after use.
- Bulk unliking (`08_unlike.py --apply`) and destructive edits to user-owned non-`LA_` playlists are strictly excluded.

## Validation
- `python3 verify_fixture.py` -> prints `ALL OFFLINE VERIFICATION CHECKS PASSED (41 tracks, 5 axes, BPM/Camelot, 8 smart crates)` and exits `0`.
- `python3 -c "import json; d=json.load(open('verified_playlists.json')); assert d['total_playlists_verified']==86 and d['all_http_200_ok']==True"` -> exits `0`.
- `test ! -f config.json && test ! -f .tokens.json` -> exits `0` before any `git commit` or `deploy_website`.

---

## Changelog

- **2026-10-22 · v3** — Full 17,686-track library reclassification (`99.6%` classified, `454` co-artist homonyms rescued); added Stage 09 (`09_music_brain.py` → `music_brain.json` v1.2 + `chirp_crates.json` v1 + `MUSIC_BRAIN.md`), Stage 10 (`10_audio_features.py` BPM/half-time/Camelot sidecar + Axis 5 `sample_roles`), and Stage 11 (`11_algo_playlists.py` 5-mode Algorithmic Set Studio + Serato `.m3u8` / Algoriddim `djay` XML / `Chirp` AV Core `chirp.av_core.set.v1` exports); synced 7 `LA_Algo_*` playlists (`168` tracks) to Spotify; verified all **86 live Spotify playlists** (`7` `LA_Algo_*` + `79` `LA_*` subgenre playlists) in `verified_playlists.json`; published standalone `one-pager.html` to `library-atlas.pplx.app/one-pager.html` and `spotify-library-taxonomy-fixer.pages.dev/one-pager`.
- **2026-10-21 · v2** — Added Phase 3 Insights (`Taste drift`, `Artist concentration`, `Bucket suggester`), 8 curated `_playlists` Smart Crates (`--smart-playlists` in `05_write_back.py`), Signal Inspector & Facet Editor drawer with `facets_locked=1` round-trip in `04_review.py`, local JSON/CSV file loader, and 41-track `verify_fixture.py`.
- **2026-10-20 · v1** — Upgraded to weighted tag scoring, automatic track-level enrichment for multi-genre artists, 4-axis faceted taxonomy (`genre`, `moods`, `scenes`, `styles`), interactive faceted `viewer.html`, and `verify_fixture.py`.
- **2026-09-01 · v0 DRAFT** — Initial fleet harvest brief.
