Category
Technical Notes
Reading paths
Read end to end.
Building an AI Podcast Index
An eight-part build-along: a locally-running tool that ingests a YouTube podcast channel, extracts guests and topics, lets you clip-search by intent, and generates questions for future episodes — using uv, FastAPI, Vite + React, and a provider-switchable LLM client.
Start →Python Monorepos in 2026
A five-part series on building Python monorepos with uv workspaces — package boundaries, Pydantic-to-TypeScript shared schemas, a Vite + React frontend co-living with FastAPI, and CI that scales.
Start →uv: the 2026 Python toolchain
A six-part series on uv — why it replaces pip, venv, pyenv, pipx, and pip-tools; how to start a new Python project in 2026; and a pragmatic migration path that keeps requirements.txt where it earns its keep.
Start →Browse all series →
See every reading path on the site.
- ·3 min read
From YouTube to a Scrobble: The Case for Track-Aware Listening
YouTube is a major source of music listening, but ordinary scrobblers treat an album upload or DJ mix as one video. This article maps the ecosystem, explains the splitting problem, and outlines what an ideal open-source solution could look like.

- ·3 min read
The Homelab Music Recommendation Field Guide: Every Signal, Trade-off, and Winner
A comprehensive reference for building Spotify-like music discovery at home: identity, metadata, sonic analysis, loudness, behaviour, collaboration, playlists, smart fades, household discovery, and how to choose between competing approaches.

- ·3 min read
The first real Alembic revision: a column, a backfill, and the parts autogenerate can't do
Last post set up Alembic in clipdex. This one cashes the bet: add a duration_ms column to processed_videos, backfill from the existing aggregation, and switch the /episodes endpoint to read it. Three commits. The parts autogenerate gets right, the parts it doesn't, and why the backfill is the line where raw SQL would have started to hurt.

- ·3 min read
Adopting Alembic in clipdex without rewriting the query layer
The previous post named four cracks in clipdex's raw-SQL migration story. This one closes them. Declarative models that mirror the live schema, a no-op baseline revision, `alembic stamp head`, and a frozen `migrations/legacy/` directory. No query code changes. Ninety minutes.

- ·3 min read
Lefthook for a Static Site: Four Hooks That Earn Their Keep
A static Astro site doesn't need Husky-grade ceremony. But it does have four failure modes worth catching before they reach `main`: a broken type, a leaked key, a post without a `directory:` field, and a build that silently breaks production. Here's the lefthook.yml I landed on, and why each hook is there.

- ·3 min read
Raw SQL migrations: when they're enough, and the four cracks that force Alembic
Clipdex ships migrations as numbered `.sql` files applied by a Taskfile loop. That's been the right call for a teaching artifact. Here are the four specific cracks that will eventually force a move to Alembic — and the test for when 'eventually' becomes 'now'.

- ·3 min read
SMS Is a Lossy Channel: An Architect's Guide to OTPs, Alerts, and Graceful Degradation
SMS looks like a reliable transport because it usually works. Architecturally, it's a best-effort store-and-forward network with no end-to-end SLA. Here's what every engineer should design for before wiring OTPs, alerts, or 2FA to a text message.

- ·3 min read
The question generator, the cron job, and shipping it locally
Grounded question generation is one prompt away. Wrap the project with a local cron, a one-line backup, and a popular-guests landing query — and the podcast index runs on its own.

- ·3 min read
The React side: guest pages, search UI, and codegen'd types
A Vite + React SPA with three real pages — popular guests, guest detail, search — wired to FastAPI through codegen'd TypeScript types from a shared Pydantic schema. No UI framework, three pages, type-safe end to end.

- ·3 min read
Search without embeddings: Postgres tsvector, LLM rerank, and 30-second clips
For a few hundred podcast episodes, Postgres full-text search plus an LLM rerank beats embedding-based RAG on both quality and operational simplicity. No vector DB, no embedding pipeline.
