The MV SELECTed COALESCE(user_id, zero-uuid) but GROUPed BY raw user_id,
so a global enrichment claim (user_id NULL) and a default-user behavior
claim (user_id = zero-uuid) for the same edge produced two rows that
collide on idx_claim_fusion_pk, breaking REFRESH ... CONCURRENTLY.
Exposed by the #219 listener_behavior same_scene_as/alias_of writes.
New migration rebuilds the MV grouping by the COALESCE'd user_id so the
two fuse into one row.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per-user SET NX PX lock with Lua CAS release around the
getActivePlan->mutate->setActivePlan span so concurrent prefetch +
feedback requests serialize instead of losing one side's write.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
both generators ran N sequential queries per artist/album.
rewritten with ROW_NUMBER() OVER (PARTITION BY ...) to get per-group
limits in a single round-trip, preserving existing semantics:
- comfortGenerator: up to 2 tracks per artist (was 20 queries → 1)
- deepDiveGenerator: up to 5 tracks per album (was 20 queries → 1)