Changelog
How Doppel came together, newest first. The two halves of the engine, the crowd and the sound, braid into one result, and everything below built toward it. Every entry links to the real pull request behind it.
- sitelatest version
This changelog
A page tracing how Doppel came together, release by release. Each entry links to the real pull request behind it, so you can read the code that shipped it.
- site#35 (opens the pull request on GitHub in a new tab)
Plainer words and polish
Rewrote every word on the site to be plain, added hover definitions for the few terms worth keeping, and did an accessibility, mobile, and speed pass.
plain-language rewrite · WCAG accessibility pass · responsive to 320px · perf: memoization + reduced-motion
- site · v1.3#34 (opens the pull request on GitHub in a new tab)
A new look: signal convergence
A ground-up redesign around one idea: the crowd and the sound braid into a single result. New type, a warm-charcoal palette, and the seam motif where the two streams meet.
authored design system · type + palette + token register · data-derived fingerprints · Framer Motion
- infra#33 (opens the pull request on GitHub in a new tab)
Server hardening for a co-tenant
Prepped the server to safely host a second app alongside Doppel, without changing how Doppel stays private and locked down.
multi-tenant VPS prep · OOM protection (oom_score_adj) · fail-closed backup retention
The engine replay console
The landing page became an engine console: pick a song and watch a saved run of the real pipeline play back stage by stage, next to a live panel of the production system.
recorded-run replay (RAF clock) · live ops telemetry to Cloudflare R2 · healthchecks.io status · host vitals · fail-soft
Mood steering
Added a mood lane: type a mood and the engine searches the whole library for songs that fit it, reaching good picks the crowd around your song would never surface. One idea that did not pan out, rewriting a mood into acoustic terms first, was measured and shelved.
HNSW vector search (pgvector) · 2×2 A/B test · MBID-native lane redesign · vibe-translation A/B (disproven, shelved)
The showcase site
The first version of this site. Doppel's engine stays private, so the site serves frozen results from real runs of curated songs, with a gallery, an honest score breakdown, and a how-it-works layer.
Next.js static export · real frozen pipeline output · Tailwind · responsive + a11y · Vercel
Live, and measured
Doppel went live on a small server, then got put to the test. A run across a benchmark of songs from many genres confirmed it held up, tuned the dials, and caught a bug where a song could recommend a different recording of itself. Daily backups, an off-site copy, and failure alerts rounded it out.
Docker on a Hetzner VPS · loopback + SSH-only · image 10.6 GB → 2.2 GB · encrypted off-site backups · 19-seed eval benchmark · cold 701s → warm 12s
The core engine
The heart of it, built over a few days: gather candidate songs from what listeners connect to your pick, match and de-duplicate them, listen to each preview and turn the sound into numbers, score those against your song, and ask an LLM to write the short note for each pick (it explains, it never ranks). All behind one API.
Python · async (httpx/asyncio) · CLAP embeddings (PyAV decode) · Postgres + pgvector · ARQ + Redis worker · two-gate async pipeline · FastAPI + Claude (prompt-cached)
- engine · day 0#1 (opens the pull request on GitHub in a new tab)
Proving it could work
Before writing the engine, every outside piece it would lean on got a feasibility check: the music data sources, Deezer's song previews, and the CLAP model that does the listening. They held up, so the build got a green light.
feasibility probe · Last.fm / ListenBrainz / MusicBrainz / Deezer · CLAP load + embed · GO verdict
- the idea
Why Doppel exists
Spotify shut off the recommendations API that a generation of music apps were built on. Doppel started from a simple question: could you match the feeling of a song, its mood and texture, by blending what listeners connect it to with how it actually sounds? That question is the whole engine.