Rewrites the internal/api comment blocks to rule 32: task, milestone and
rule ids gone, the stories behind them restated as the constraint they
left, stale references corrected (the stream secret is wired from config,
the timezone handler already refreshes the scheduler, the Android app is
the native client, the design docs cited are not in the repo). Also
rewraps comment lines over 80 columns left by the earlier batches.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mode (off, auto, track, album), target (-18, -16, -14 LUFS) and boost
(within headroom, or fully with a limiter), stored per user on the server
so the web player, the Android app and casts apply the same one.
- Server: user_normalization_prefs (migration 0067), GET/PUT
/api/me/normalization; a whole-body PUT, validated, last write wins.
- Web: Settings > Playback > Volume leveling. Saves at once, restores the
old choice if the save fails, and caches the value for the player.
- Android: Settings card. The device keeps a copy for offline playback
(Room v9 with an explicit migration, so the upgrade wipes nothing).
Writes are offline-first: shown at once, PUT best effort, queued on
failure (NORMALIZATION_SET, collapsed to the newest). A refresh never
overwrites a change still queued.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>