Sprint v0.1.13 - Piano-Forward Coherence

Fecha: 2026-04-01  
Estado: pendiente  
Objetivo: mejorar la coherencia total de los sonidos elegidos con un sesgo mas claro hacia `piano/keys`, sin perder el family lock principal ni degradar el reference flow

## Contexto

El validation report de v0.1.12 dejó una pista usable y una dirección musical válida: la generación ya puede sonar bien, pero todavía necesita un criterio más fino para decidir qué timbres armónicos sostienen cada sección.

Después de revisar ese report contra el código real, el baseline quedó así:

- `JOINT_SCORE` y el auditor de selección sí existen y están cableados
- `layer_selections` sí puede ir al manifest, pero había un bug de scope en `server.py`
- el wrapper de Ableton tenía el hard budget desincronizado con las tracks reales de la sesión
- `server.py` no contaba correctamente las tracks ya creadas por el runtime antes de agregar capas extra
- los derived layers podían duplicarse en el camino `reference_audio_plan -> materialization -> extra derived pass`

Esos errores de infraestructura fueron corregidos en esta revisión.  
El siguiente sprint no debe volver a abrir ese frente salvo que una corrida real demuestre otra fuga.

## Dirección musical

El objetivo no es “poner pianos por poner”.

La dirección correcta es:

- mantener `pluck` o la familia primaria cuando sea el ancla del hook/drop
- usar `piano/keys/rhodes` como soporte armónico más presente en intro, break y build
- aumentar la presencia de piano cuando sea compatible con la referencia, la key y el pack dominante
- evitar que el sistema derive a `lead/pad` genéricos cuando hay opciones de piano más coherentes

## Tareas

### 1. Introducir preferencia secundaria explícita para `piano/keys`

Agregar en el flujo de referencia una noción de familia secundaria preferida.

Mínimo esperado:

- derivar `preferred_secondary_families` desde `harmonic_instrument_hints`
- priorizar `piano`, `keys` y `rhodes` cuando la referencia sea compatible
- no reemplazar ciegamente la familia primaria; usarlo como refuerzo, no como override global

### 2. Hacer la preferencia dependiente del rol y de la sección

La selección no debe tratar todas las capas armónicas igual.

Aplicar una política por rol/sección:

- `hook` y `lead` de drop: conservar prioridad de familia primaria
- `chords`, `synth_loop`, `music bed`, `atmos`: subir peso de `piano/keys`
- intro/break/build: permitir más presencia de piano que en el peak

Si no se puede expresar por sección todavía, dejar al menos el adapter listo y el scoring por rol funcionando.

### 3. Mejorar el scoring para que el piano gane cuando corresponde

Extender `reference_listener.py` y/o `sample_selector.py` para que el ranking final premie piano coherente.

No alcanza con keywords.

El score final debe considerar:

- compatibilidad con `primary_harmonic_family`
- bonus por `piano/keys` como familia secundaria preferida
- `dominant_pack`
- key compatibility
- sección/rol musical

### 4. Exponer en manifest cuánto piano realmente quedó

Agregar evidencia directa en el manifest para no depender de escuchar a ciegas.

Mínimo esperado:

- `piano_presence` o métrica equivalente
- conteo de capas `piano/keys/rhodes`
- qué roles terminaron usando piano
- razones de selección por esas capas

### 5. Endurecer tests para este nuevo criterio

Agregar tests que fallen si el sistema vuelve a caer en capas genéricas pese a tener piano compatible.

Casos mínimos:

- referencia `pluck` + candidatos `piano/keys` coherentes + `pad/lead` genéricos:
  el sistema debe elegir al menos una capa `piano/keys` en roles de soporte
- referencia con hint de piano:
  el ranking debe reflejar ese bonus de forma explícita
- el manifest debe exponer la presencia real de piano cuando se seleccionó

### 6. Validación real en Ableton

Correr al menos una generación con referencia y verificar:

- que el hook principal siga coherente
- que haya más presencia de `piano/keys` que en v0.1.12 cuando la referencia lo permita
- que no reaparezcan duplicados de derived layers
- que `layer_selections` y el manifest permitan auditar ese resultado

## Archivos foco

- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\reference_listener.py`
- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\sample_selector.py`
- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\song_generator.py`
- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\server.py`
- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\AbletonMCP_AI\MCP_Server\tests`
- `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\docs`

## Criterio de salida

El sprint cierra solo si:

1. el sistema selecciona más `piano/keys` cuando la referencia lo justifica
2. esa subida de pianos no rompe el family lock principal ni la coherencia de key/pack
3. el manifest deja evidencia explícita de la presencia de piano y de las razones de selección
4. hay tests que fallen si el piano compatible vuelve a perder contra capas genéricas
5. una validación real en Ableton confirma mejora audible y ausencia de regresiones obvias
