Architecture decision records
This directory records stable architectural decisions for the Bitrate monorepo.
ADRs explain why the repository uses a pattern; CLAUDE.md and .claude/rules/ explain
how to apply it day to day.
| ADR | Decision |
|---|---|
| 0001 | Turborepo + pnpm multi-runtime monorepo |
| 0002 | Feature-Sliced Design for web-player |
| 0003 | Next.js App Router |
| 0004 | OpenAPI-first client and TanStack Query |
| 0005 | Zustand target for client state |
| 0006 | Shared UI package, tokens, Base UI, shadcn methodology |
| 0007 | React Hook Form + Zod |
| 0008 | Repository-owned AI agent layer |
| 0009 | shadcn produces package-owned compositions |
| 0010 | App Router files stay thin; views own screens |
| 0011 | Retire apps/web in favor of apps/web-player |
| 0012 | Ticket-driven agent commands, GitHub Projects, and Obsidian sync |
| 0013 | apps/docs vs .claude — ownership boundary and drift detection |
| 0014 | What in obsidian/ is committed vs local-only |
| 0015 | graphify and the obsidian/ vault are decoupled |
| 0016 | Retire the obsidian/ ticket/board mirror for live GitHub queries |
| 0017 | Remove the obsidian/ working-notes vault |
| 0018 | Consolidate .agents//AGENTS.md into .claude/ only |
| 0019 | Remove the graphify:obsidian convenience wrapper |
| 0020 | Single-file CMAF + Range index + MSE for audio playback |
| 0021 | Mandatory dispatch (superseded by ADR-0040) |
| 0022 | App-scoped developer agents, unattended /br-auto pipeline, retire br-ticket |
| 0023 | Hand-write the design tokens as CSS; retire the token generator |
| 0024 | Rebrand the project from spotify-clone to Bitrate |
| 0025 | Remove the Kottster admin panel |
| 0026 | pnpm 11; pnpm-workspace.yaml is the only home for pnpm settings |
| 0027 | Deploy by pulling CI-built images; production configuration lives in GitHub |
| 0028 | Split the brand foundation into one page per decision |
| 0029 | Release by a pull request a human merges; the tag is the derived product version |
| 0030 | Remove the performance testing suite |
| 0031 | Expand /br-sync-docs to root onboarding docs and .claude/ self-consistency |
| 0032 | Bitrate is artist-first; the listening surface supports it |
| 0033 | Backups leave the host and are restore-rehearsed; audio moves to object storage |
| 0034 | The artists portal runs on TanStack Start, not Next.js |
| 0035 | The operator panel returns, on Angular, with its own data layer |
| 0036 | The operator panel is layered as clean architecture |
| 0037 | br-manager owns tracker state beside br-worker |
| 0038 | Operators hold permissions; roles are templates |
| 0039 | The player becomes a Svelte custom-element package |
| 0040 | Scoped instructions, task-based delegation and routine Sonnet defaults |
| 0041 | Required grill-me interview and confirmed plan before large tasks |
| 0042 | One-operation hook approvals, scoped formatting and on-demand verification/review/TDD |
| 0045 | Scoped rules, canonical specs and serialized verification |
| 0048 | pnpm 12.7.0, settings in pnpm-workspace.yaml, explicit allowBuilds policy |
| 0049 | Transcode worker process boundary, provider list and ConvertAudioJob contract |
| 0050 | SeaweedFS single-node internal object storage for audio; spike results; accepted no-backup risk |
| 0051 | Operator panel resource coverage: ranked pages, take-down and restore convention, session revocation, MODERATOR template rule |
| 0052 | Artist release workspace, credits and splits; single-owner MVP boundary |
| 0053 | Private artist recordings, owner-constrained release links and database-backed Music catalogue |
| 0054 | Draft title/type editing with atomic ownership/lifecycle/version checks |
| 0055 | Addressable owned workspace with bounded active recordings, schedule and credited participants |
| 0056 | Planned UTC timing edits with the existing atomic draft owner/version guard |
| 0057 | Adding participant credits with unique roles and transactional draft version checks |
| 0058 | Correcting participant names/roles while preserving identity, account links and splits |
| 0059 | Rights confirmation, splits, optional UPC/ISRC, readiness and review submission/withdrawal |
| 0060 | API Prisma write ownership per module, enforced by an oxlint JS plugin with a shrinking baseline |
| 0061 | Shared login, lockout, session, recovery-token, 2FA and guard core for listeners and artists; no account merge |
| 0062 | Release publishing state machine, all-or-nothing go-live and publishedAt visibility for tracks and albums |
| 0063 | Player chrome variants and public part elements composed through the Context Protocol |
| 0064 | The player element owns streaming, prefetch and mirrors; hosts keep the queue and supply a legacy HLS adapter |
| 0065 | One stored audio format: CMAF AAC with 10-second fragments over HTTP Range; legacy Opus/HLS removed |
| 0066 | Bitrate is music-only; podcasts and audiobooks are separate products and the podcast vertical is removed |
| 0067 | Playback sessions: a signed token per play on every rendition request, a ~10-second exact cap, real-time pacing |
| 0068 | The operator API runs as its own process with its own contract, served from the admin panel's host with host-only staff cookies |
| 0069 | GSAP is the only JavaScript animation library on web surfaces; CSS keeps hover, press and Base UI enter or exit |
Create new records from template.md. Accepted decisions are changed by
a superseding ADR rather than silently rewriting history.
The release diagrams and demo guide describe the implemented workspace, database relationships and the boundary with future publication/delivery work.