Independent prototypes, dashboards and analysis writeups. Each project lives in its own folder. Two kinds live here: static writeups and small Flask tools, and a Next.js app for the ones that need real app UI — the card’s footer says which.
How few times does a DJ have to do anything for us to import their collection and keep it in sync? Once.
One rekordbox.xml export names the exact folders their music lives in — so nobody is ever asked
"where is your library?" — and hands over the crates and ratings no folder on disk can show. After that the
music folder alone does the work: the rig walks it in the browser, keeps the handle, and fingerprints every
file, so Rescan reports precisely what a sync run would touch. It reads ID3, Vorbis and M4A tags to show what
the catalogue match gets for free, and decodes each file to the 16 kHz mono the analyser eats, encoding
Opus at ~29× smaller than the source — a 50 GB upload turned into under 2 GB. No agent, no second
export, and no network calls at all.
Die Produktion vergleicht Tracks über einen gemittelten Vektor aus 60 Sekunden. Hier steht daneben, was passiert, wenn der zeitliche Verlauf mitzählt: jeder Track über seine ganze Länge in 8 Abschnitte, abschnittsweise gegen den Seed. Vier echte Digs, beide Spalten aus demselben Kandidatenpool von je 500 Nachbarn, jeder Titel zum Anhören verlinkt. Das Ergebnis sortiert um (im Schnitt 5 Plätze je Track, 14 Tracks neu in den gezeigten Top-25), stellt die Spitze aber nicht auf den Kopf — plausibel, denn das 60-Sekunden-Fenster repräsentiert den ganzen Track schon mit cos 0,988. Gegen Saves gemessen (134 gelabelte Listen) war kein signifikanter Gewinn nachweisbar; ob die rechte Liste besser ist, muss das Ohr entscheiden.
The aggregate behind the drop-off tool, and mostly a negative result: on genre agreement, artist spread, tempo distance, playability and embedding closeness, the people who left got results indistinguishable from the people who stayed — and on playability they got better ones. What separates them is how far they listened (1.3 tracks vs 5.3, rank 2 vs rank 7), and playing one or two tracks predicts a return no better than playing none. The one quality effect that survives is the outlier tail: a top result under 0.85 cosine — 3.8% of first searches, mostly non-electronic YouTube links — drops the return rate to 23.7% from 38.3%. The sharpest split is not about music at all: the drop-offs are two-thirds phone users against a desktop majority among the returners, a phone session runs five minutes to desktop's fifteen, and the player itself works fine on both.
A blind A/B on the ranking itself. Submit a seed track and the page shows two orderings of the same candidates side by side — one pure cosine similarity, one re-ranked by the measured external signals (collection ownership, Bandcamp buyers, MixesDB DJ plays, era proximity) with shrinkage and artist de-clumping. Which column is which is decided per run and only revealed after you rate, so the tester cannot score their own hypothesis. Weights come from a conditional logistic fit on 14 829 measured pairs with a user holdout: 54.1% test accuracy on discordant pairs — real, but close enough to a coin flip that the blind test is the point. Ratings are stored with both ranks, so the count of keepers in each column's top 5/10/20 is the verdict. Moved here from the main app (2026-09-23), where it briefly sat open on beta.
The accounts that submitted a track, played one or two of the recommendations and never came back — one at a time, with the evidence. Every search stores the full ranking it returned, and every 3.5-second play is logged, so the page can show exactly which rows they heard, at which rank, how long after the search, next to everything else we hold: where they came from, what they saved, what they told us. All of it playable, because whether a set of recommendations deserved a second session is a thing you hear, not a number. Of the current cut, 91% were gone within five minutes and 3% saved anything.
The embedding's 1280 dimensions are not a list of concepts: a network packs more properties into a space than it has axes, so each property lies along a slanted direction and each axis carries several at once. A sparse autoencoder re-expressed them as 10 240 units of which every track lights up 32 — and those units are readable. One fires on 1 254 tracks spanning 57 BPM whose tags are darkpsytrance at 179x lift: not a tempo, not a genre, a production style. Each unit shows its strongest tracks (playable), what it lines up with across every track that fires it, and a steering panel: push a different track along the unit's direction and watch which ten neighbours the catalogue answers with.
300 000 playable tracks clustered on the embedding, then grouped into a hierarchy you can walk: continents, regions, neighbourhoods. Each region carries its measured signature — tempo, tonality, era, vocals, genre mix — and its tracks are ranked closest-to-centre first, so the top of a list is that sound's prototype and reading down walks out to its edges. Two views (grid and a real point cloud), a catalogue search that drops you into the matching region, and a switch between seven embedding spaces for comparison.
Paste a set, get its timeline: segments, matched tracks where we can identify them, and the similar sounds around each moment.
Mark a 60-second window anywhere in a set and search the catalogue from exactly that sound, rather than from a track name.
The matcher decides which YouTube upload to play and which Discogs release to attach for every track we ingest, on a confidence score with a hand-tuned threshold — and until now nobody could say how often either is wrong, because there was no labelled data. That is what makes matcher work whack-a-mole: each fix is validated against the one anecdote that prompted it, and its regressions surface weeks later. One match per screen, our track beside the pick, verdict on a keystroke; a wrong verdict asks why, and that histogram is the work plan — “37% of false positives are mix mismatches” points at one gate in the scorer. Filterable by the source a track was discovered on (bandcamp, traxsource, deejay, decks …), since each scraper's metadata is shaped differently. Exports straight into the offline scorer, which replays every label in milliseconds. Precision only — a match the pipeline rejected leaves no row behind.
Essentia's mood heads run on the EffNet embeddings we already store — no audio, no
re-analysis. First view measures whether they spread at all inside our catalogue:
party, aggressive and relaxed do (std ~0.13–0.19,
Techno 0.62 vs Ambient 0.34 on party), while danceability saturates
(median 0.87 — in a techno catalogue everything is danceable) and the 56-tag Jamendo head is
mostly flat. Second view plays a track and records what it actually is, in
DJ vocabulary (hypnotic, driving, dubby, raw) — words no pretrained model has, since
there is no public mood dataset for electronic music. The CSV is the deliverable.
Paste a YouTube DJ set and it plays right there, over a timeline you can mark regions on. Auto-scan maps the set's shape — including a drift line showing where it turns — and every region is embedded on its own and queried against the live catalogue, in three views: crate (fits here, not already in the set), nearest, and a probable ID for partial tracklisting. Auth-gated: a dynamic app that spends analyzer time per set.
Same model, two scorings: what digdeeper.fm returns today vs the same neighbours with the
corpus mean subtracted. The live space is anisotropic (||mu||/mean||x|| = 0.69) — two random
tracks already score 0.48, which squeezes rank 1 to rank 50 into a 0.069-wide band. Centering doubles that
margin, and swaps ~1 in 4 of every top-10. Every row playable, so you can judge whether the swap is an improvement.
Auth-gated (basic auth): a dynamic app against the shared DB + Qdrant, not a static writeup.
(Was: six embedding spaces — the five contrastive variants lost.)
Tracks whose full-track embedding is near-identical (cosine ≥ 0.995) — the same recording regardless of how the metadata reads. Catches what id/slug/title signals miss: cross-artist collab reuploads, "various artists" compilation copies, differing credit strings, re-masters. ~8% of tracks have such a twin. Each group is playable inline (Bandcamp/YouTube) with a title+artist match badge — listen, mark same/different, export verdicts. No merges happen here.
The follow-up to the classifier: given a track's stored title + artist + Bandcamp label.name,
decide the real artist(s) and label(s) — no re-fetch, exactly what a backfill sees. 10/11 artists
and 8/11 full credits on the check-set; 180 random tracks shown input→output, grouped by confidence so you can
judge the low-confidence boundary yourself.
A Bandcamp URL can't tell you if a page is a solo artist or a label, but Dig Artist / Dig Label
need to. Tested a simple rule (“many distinct artists ⇒ label” + the Various-Artists flag) over all
127,840 pages in prod — 7/10 on a labelled check set. Directionally right, but the stored
artist field is the bottleneck: it collapses to the label name on some catalogs and inflates on
“feat.”-heavy artists.
Can we ingest Traxsource, and can we play it back? Three catalog endpoints are open (no Cloudflare) — an estimated ~9.4M tracks reachable by ID sweep. The official embed player is live here, but has no JS control API (unlike SoundCloud/YouTube). Plus the licensing split: analyze freely, but don't reskin their preview.
decks.de has no embeddable player, so each track needs a matched YouTube or SoundCloud source to be playable. The matcher run over a random sample of the archived backlog — 74% get a playable match — every match playable inline so you can judge it yourself.
Picking the YouTube upload for a track used to be one tuned number against one threshold, and nobody could
say how often it was wrong. 101 matches judged by hand now say: the old scorer was right on 70, the
field model on 95. A separate playlist of twelve independently flagged bad matches replays clean —
eight now find nothing, four pick a different video, none survive. The labels also say where the damage
is: below score 0.9 every single labelled row was wrong (15/15, 268k tracks), while the "perfect" 1.0
band is only 18% wrong but holds 94% of the volume — about a million bad matches. Plus three things we stopped
guessing about: adding (Original Mix) to the query halves the hit rate, the exit country
changes nothing, and the fallback query ladder costs 1.23 searches per track.
The full logic behind decks/Traxsource → Discogs + YouTube/SoundCloud, step by step: the search ladder (barcode → catno → tracklist → fuzzy → stop-words), the four scoring signals, and the accept/reject rules (corroboration, not title resemblance — incl. the tracklist check that fixed Jeff Mills and killed catno collisions). Read it to sanity-check the pipeline.
The actual stored matches from the production drain (decks → YouTube + Discogs), not a re-run.
Each row links the matched YouTube (▶ to verify the pick) and Discogs release, with confidence + the
no_youtube_match visibility flag. Eyeball it to find where the matcher still goes wrong.
100 real source tracks (50 decks, 50 Traxsource), each run through the two matchers that matter: YouTube (playback — the ingest gate) and Discogs (metadata/buy). SoundCloud was dropped (mostly noise). Playable: decks ~73%, Traxsource ~92%. Discogs matches by free-text + catalog-number search, confirmed by the tracklist / release title / catno+artist — recovering placeholder-titled vinyl ("track two" → the catno finds the record), mis-credited artists (Decibel Ft Leveetra → Decibel Feat. La Veetra) and catnos decks mis-files into the label field: decks ~92%, Traxsource ~36%, and 0 false positives. Each match surfaces the release's curated YouTube link (▶ YT). Source rows link back to decks/Traxsource.
A second, non-overlapping random sample (50 decks, 50 Traxsource) through the same two matchers — a cross-check that coverage holds beyond the first 100. decks ~94% on Discogs (47/50), ~72% playable; Traxsource ~90% playable, ~34% on Discogs; 0 false positives. Confirms the catalog-number / placeholder- vinyl recovery generalizes to fresh tracks.
Discogs isn't playback — it's metadata and a buy link. Matching by catalog number / barcode (which decks gives us), 92% of tracks resolve to a Discogs release — 38 by exact catalog number — bringing label, year, genre/style, marketplace stats and a buy link, and often fixing decks' own bad metadata.
The same matcher over a second, non-overlapping 100-track sample from the archived backlog — 83% get a playable match. A cross-check that coverage holds beyond the first sample, after the metadata + matcher fixes.
The 100 nearest neighbours of a seed track, playable inline, with six embedding strategies scored side by side. They agree on what's similar but disagree a lot on order.
A tiny no-build prototype with shared DigDeeper styling, inline CSS animation, and simple JavaScript controls.
site/<slug>/, build an
index.html that links /style.css, add a card here, commit & push. See
.claude/skills/publish-experiment and the repo CLAUDE.md.