-- 0057_songs_like_tuning.up.sql — a THIRD weight profile, for Songs-like -- (Scribe #3881, milestone #398). -- -- Songs-like shared the `daily_mix` profile with For-You, and that is the bug. -- The two surfaces want opposite things: For-You is a broad "what will they -- enjoy today", Songs-like answers "what sounds like THIS", and under one set -- of weights the broad answer wins. Operator, 2026-09-10: "I'm expecting to -- get a consistent sound and style from the experience... I was getting a -- seeming wide variety of music from each one when I was hoping to stay in a -- certain neighborhood." -- -- Under the shared daily_mix weights, an UNRELATED track the user had liked -- and not played recently scored 1.0 + 2.0 + 1.0 = 4.0 before taste, while a -- PERFECT similarity match they had not liked scored 1.0 + 1.5 = 2.5. Liking -- something outranked sounding like the seed. Splitting the profile is what -- lets similarity dominate here without making For-You narrow. -- -- Rows are seeded by the recsettings boot reconcile, not here, so shipped -- defaults live in exactly one place (Go) — same as 0040. -- Rule #36: a new value for a CHECK-gated column needs the constraint -- rewritten in the SAME change, or the first row written under the new -- profile fails at runtime rather than at migrate time. ALTER TABLE recommendation_weight_profiles DROP CONSTRAINT recommendation_weight_profiles_profile_check; ALTER TABLE recommendation_weight_profiles ADD CONSTRAINT recommendation_weight_profiles_profile_check CHECK (profile IN ('radio', 'daily_mix', 'songs_like')); -- The audit table gates the same name on a separate constraint. Missing this -- one would let the profile be seeded and then fail on the first knob turn — -- green at boot, 500 on first use. ALTER TABLE recommendation_tuning_audit DROP CONSTRAINT recommendation_tuning_audit_scope_check; ALTER TABLE recommendation_tuning_audit ADD CONSTRAINT recommendation_tuning_audit_scope_check CHECK (scope IN ('radio', 'daily_mix', 'taste', 'discover', 'songs_like'));