← Dashboard

Spotify Phase 1 — build complete, real pull blocked on one creds step

Built overnight 2026-05-20 → 21 against the May 20 spec. Code shipped, schema applied, fail-loud verified. One unblock between now and real listening data.
Lede. Phase 1 of the Spotify hybrid pipe is built and waiting. The Python client, the JSON->Postgres loader, the schema (1 table, 4 indexes, 4 views) — all sitting in tp3_scripts/ on Apex tonight. The only thing standing between now and a real listening dump is a Spotify Developer app's client_id + client_secret, which I can't create without you signed in. When you wake and confirm /mcp on chrome-devtools, the unblock is a five-minute, one-click handshake — I drive developer.spotify.com in your real Chrome, you click Approve once. Then this report regenerates with real artists, real shows, real time-of-day patterns instead of the projected shape below.

What landed tonight

PieceStatePath / notes
tp3_spotify_pull.pySHIPPED/mnt/c/Users/Breezy/tp3_neural_stack/tp3_scripts/tp3_spotify_pull.py — OAuth bootstrap (PKCE + state guard), recently-played walker with before= cursor pagination, refresh-token persistence in ~/spotify_history/refresh_token.txt (chmod 600), ntfy summary on completion (ASCII title per the May-19 gotcha rule).
tp3_spotify_load_to_pg.pySHIPPED/mnt/c/Users/Breezy/tp3_neural_stack/tp3_scripts/tp3_spotify_load_to_pg.py — reads listening_history.json and idempotently upserts into spotify_recently_played. Has --ensure-schema flag that applies the DDL inline so the load can self-bootstrap.
tp3_spotify_ddl.sqlAPPLIEDLives at /mnt/c/Users/Breezy/tp3_neural_stack/tp3_scripts/tp3_spotify_ddl.sql. Live on tp3_neural_stack_brain_db: 1 table (spotify_recently_played, unique on (spotify_uri, played_at)), 4 indexes (played_at DESC, item_type, show_id-where-episode, artist-where-track), 4 views (spotify_episodes_recent, spotify_tracks_recent, spotify_top_shows_90d, spotify_top_artists_90d).
credential templateSHIPPED/home/breezy/spotify_history/.env, chmod 600, three blank slots, SPOTIFY_REDIRECT_URI pre-filled to http://127.0.0.1:8765/callback.
real pull executedBLOCKEDNo Spotify Developer credentials exist anywhere on Apex or in the TP3 .env. Verified with a full grep across ~/, ~/.config/, and the TP3 stack root.

The blocker, in one sentence

I need a Spotify Developer app's client_id + client_secret — a 3-minute creation in your signed-in Chrome at developer.spotify.com. After that, the first run is one --bootstrap-oauth click (you tap Approve on Spotify's consent screen, my helper captures the callback) and every subsequent nightly pull runs unattended for years on the refresh token.

Your one action to unblock: when you give me /mcp confirm on chrome-devtools, I open developer.spotify.com directly in your real Chrome, create the app called “TP3 Spotify Pull”, set redirect to http://127.0.0.1:8765/callback, copy the two secrets into Apex's ~/spotify_history/.env, and fire tp3_spotify_pull.py --bootstrap-oauth. You click Approve once. Total elapsed: under five minutes from your “go.” Per the no-directions rule, that's the handoff — not a checklist for you to walk.

Why this matters before the discovery has real numbers

The spec called Phase 1 “the listening signal” — what landed in your ears, when, for how long. It's the cheap, ToS-clean, no-LLM-tokens dump that lets us see before we spend cycles on transcripts. Even with zero transcripts, the table answers immediately:

None of these need Phase 2. They drop out of Phase 1 the moment the JSON lands.

Discovery framing — what we'll be looking at (questions, not yet answers)

Music side

Podcast side (the actual long-arc payoff)

Cross-cutting

What's NOT in this report yet (and why)

Discipline notes (FAIL LOUD verification)

When you wake — the unblock recipe (one decision, one click)

  1. Confirm chrome-devtools MCP is alive (/mcp if needed). I drive the rest.
  2. I open developer.spotify.com in your real Chrome, create the app, paste secrets into Apex .env, fire --bootstrap-oauth. You click Approve once. Done.
  3. First pull runs immediately. Report regenerates with real numbers in the next morning brief.
  4. If you'd rather hold this until after the 5/23 hardware install: nothing breaks. Code sits ready, table sits empty, no nightly cron until you say go.