bvandeusen 86cb8e5cbf docs(spec): add M4b ListenBrainz inbound similarity ingest design
Second M4 sub-plan (Fable #346). Periodic worker pulls track-track and
artist-artist similarity edges from LB's public /explore/* endpoints,
filters to the local library, stores top-20 per source track in two new
tables (track_similarity, artist_similarity). Hourly tick, batch=5,
weekly re-fetch cap per row, passive retry via timer. No auth (public
endpoints). Discovery within library handled by LB's collaborative-
filtering response naturally surfacing unplayed library tracks; spec
notes M4c will add a serendipity floor + lazy fetch + sparse-fallback.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 19:46:23 -04:00
2026-04-19 15:14:56 +00:00
2026-04-18 17:33:35 +00:00

Minstrel

Self-hosted music server with OpenSubsonic compatibility plus an extended API for server-side smart shuffle, a dual-like model (general + contextual), session-aware radio, ListenBrainz scrobble/similarity, and Lidarr integration. Go + Postgres, packaged as a Docker container.

State and intelligence belong on the server, not the client.

Specs

Authoritative v1 scope lives under docs/:

  • Server spec — current implementation focus.
  • Client spec — Flutter companion app; work starts once the server reaches its Subsonic-compatible baseline.

Development workflow

  • Day-to-day work happens on the dev branch (or feature branches merged into dev).
  • main is protected — changes land only via pull request from dev.
  • Production builds are cut by tagging a release (v*) off main.

CI / container image

Forgejo Actions handles:

  • Tests on push to dev and on PRs into main.
  • Container image build + push to the Forgejo registry on merge to main (:main) and on v* tags (:<version>).

Task and milestone tracking: Fable (Minstrel project, id 12).

Development

Minstrel has two concurrent dev processes:

  1. Backend: docker compose up — starts Postgres and Minstrel on :4533.
  2. Frontend: cd web && npm install && npm run dev — Vite dev server on :5173 with HMR.

The Vite dev server proxies /api/* and /rest/* to the backend on :4533, so session cookies work correctly when the SPA is loaded from the Vite origin.

Production build

docker build -t minstrel . runs the SvelteKit build inside a node stage, copies the output into the golang stage, and //go:embeds it into the final binary. The resulting container serves the SPA from / alongside the API surfaces. No separate static-file server is required.

S
Description
Self-hosted music server with OpenSubsonic compatibility, server-side smart shuffle, dual-like model, session-aware radio, and Lidarr integration. Go + Postgres.
Readme MIT 63 MiB
Languages
Go 39.2%
Kotlin 25%
Dart 14.2%
TypeScript 12%
Svelte 9.3%
Other 0.1%