# Sprint v0.1.10 Coherence Review For Kimi

Ultima revision: 2026-04-01

## Rol de este documento

Este archivo no es un plan aspiracional.

Es un review tecnico de lo que hoy esta realmente cableado en el repo activo y de lo que Kimi tiene que arreglar para mejorar la coherencia total de los sonidos elegidos.

Scope de este review:

- identidad timbrica
- coherencia de pack
- coherencia armonica
- hook family
- cableado real entre referencia, seleccion y materializacion

No es un sprint de wrappers, runtime o mix fino.

## Lo que ya lei antes de escribir esto

Documentacion activa leida:

- `README.md`
- `CLAUDE.md`
- `kimi.md`
- `KIMI_K2_BOOTSTRAP.md`
- `KIMI_K2_START_HERE.md`
- `KIMI_K2_ACTIVE_HANDOFF.md`
- `docs/ROADMAP.md`
- `docs/TODO.md`
- `docs/KNOWN_ISSUES.md`
- `docs/REFERENCE_TRACK_EJEMPLO_ANALYSIS.md`
- `docs/REFERENCE_TRACK_EJEMPLO_MICRO_STEMS.md`
- `docs/MICRO_STEMS_APPROACH.md`
- `docs/CONSOLIDADO_v0.1.8_PARA_CODEX.md`
- `docs/SPRINT_v0.1.9_IMPLEMENTATION_REPORT.md`
- `docs/SPRINT_v0.1.10_NEXT.md`
- `docs/SAME_PACK_SELECTION.md`
- `docs/VALIDATION_REPORT_EJEMPLO_2026-03-30.md`
- `SECTION_AWARE_WIRING_REPORT.md`
- `SMOKE_TEST_ASYNC.md`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/PHRASE_PLAN_README.md`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/SAMPLE_SYSTEM_README.md`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/API.md`

Codigo activo revisado:

- `mcp_wrapper.py`
- `AbletonMCP_AI/__init__.py`
- `AbletonMCP_AI/Remote_Script.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/server.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/song_generator.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/reference_listener.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/sample_selector.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/pack_brain.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/coherence_analyzer.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/tests/test_sample_selector.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/test_phrase_plan.py`
- `temp/smoke_test_async.py`

Validacion local hecha:

- `py_compile` pasa para `server.py`, `song_generator.py`, `reference_listener.py`, `sample_selector.py`
- `tests/test_sample_selector.py` pasa
- `test_phrase_plan.py` pasa

Importante:

- que compile no prueba que el wiring de coherencia este cerrado
- que los tests unitarios pasen no prueba que la generacion real use esos features

## Veredicto corto

La infraestructura de coherencia existe, pero la cadena principal sigue abierta.

Hoy el repo puede:

- analizar referencia
- detectar `locked_properties`
- detectar `micro_stem_summary`
- resolver `harmonic_instrument_hints`
- construir `PhrasePlan`
- medir coherencia despues

Pero hoy no demuestra de forma limpia que:

- la familia armonica dominante de la referencia guie el blueprint musical real
- el mismo mundo sonoro se mantenga entre secciones
- `JOINT_SCORE` afecte la seleccion final end-to-end
- el hook MIDI quede materializado de forma consistente

El problema principal no es "faltan features".

El problema principal es "los features estan en paralelo y no en una sola cadena obligatoria".

## Hallazgos verificados

### 1. Los harmonic hints llegan tarde y no guian el blueprint musical real

Archivos:

- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/song_generator.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/server.py`

Hecho verificado:

- `song_generator.generate_config()` lee `external_harmonic_hints`, pero en la practica solo los loguea y los usa para `generation_context`
- `_build_scene_clips()` no recibe `harmonic_hints`
- `_render_scene_notes()` llama `_render_musical_scene(..., phrase_plan)` sin pasar `harmonic_hints`
- `server.py` recien copia `config["harmonic_instrument_hints"]` despues de `_build_reference_audio_plan(config)`, cuando el blueprint ya fue generado

Consecuencia:

- la referencia puede resolver `pluck/pad/piano/lead`
- pero esos hints no estan mandando la generacion de clips MIDI/audio en el momento donde realmente importa

Impacto musical:

- el track sigue pudiendo caer en capas correctas pero no ancladas a una sola hook family

### 2. El PhrasePlan actual introduce drift timbrico por diseÃ±o

Archivos:

- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/song_generator.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/test_phrase_plan.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/PHRASE_PLAN_README.md`

Hecho verificado:

- `PhrasePlan._determine_family()` elige familia por `random.choice(...)` segun seccion
- `reference_listener.build_arrangement_plan()` crea `PhrasePlan(...)` desde `MusicalTheme`, pero no le inyecta `harmonic_instruments` ni un `family_lock`
- el propio `test_phrase_plan.py` muestra familias saltando entre `piano`, `synth`, `pluck`, `pad` dentro del mismo plan

Consecuencia:

- aunque el motivo melodico sea coherente
- la identidad timbrica puede cambiar por seccion por una regla aleatoria interna

Impacto musical:

- exactamente el problema reportado por el usuario: sonidos lindos pero sin una sola identidad clara

### 3. `JOINT_SCORE` y `SECTION_CONTEXT` existen, pero no controlan el flujo principal de referencia

Archivos:

- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/sample_selector.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/reference_listener.py`
- `SECTION_AWARE_WIRING_REPORT.md`

Hecho verificado:

- `sample_selector.py` tiene `_calculate_joint_score()`, `set_section_context()` y `record_section_selection()`
- eso esta cubierto por tests unitarios
- pero `reference_listener.py` hace la seleccion principal con su propio `_select_candidate()` y `_select_distinct_candidate()`
- ese camino no llama `SampleSelector._calculate_sample_score()` ni `SampleSelector._calculate_joint_score()`
- `record_section_selection()` se llama, pero en el flujo de referencia no se usa como motor de re-scoring real

Consecuencia:

- hay wiring parcial
- pero no evidencia de que el scorer conjunto de `sample_selector.py` este cambiando la seleccion principal

Impacto musical:

- la seleccion por seccion puede variar
- pero no hay garantia real de que `kick + clap + hats`, `bass + synth` o `vocal + fx` se esten corrigiendo mutuamente

### 4. El hook MIDI tiene un estado mezclado entre "planificado" y "materializado"

Archivos:

- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/song_generator.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/server.py`

Hecho verificado:

- `_create_midi_hook_track()` marca `self._midi_hook_created = True` dentro del generador
- `server.generate_track()` solo intenta `materialize_midi_hook()` si `not generator._midi_hook_created`

Consecuencia:

- si el hook queda marcado como creado durante la fase de blueprint
- el server puede saltarse la materializacion explicita en Ableton

Impacto musical:

- puedes tener un hook "existente" en memoria/logs
- pero no una pista MIDI dedicada y verificable en Live

Nota:

- este bug se vuelve mas serio en cuanto cierres de verdad el wiring de harmonic hints

### 5. `server.py` tiene integracion de referencia incompleta en el bloque post-plan

Archivo:

- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/server.py`

Hecho verificado:

- en el bloque posterior a `_build_reference_audio_plan(config)` se usan `ref_musical_theme`, `ref_micro_stem` y `ref_synth_hint`
- en el scope visible de ese bloque no aparecen asignaciones previas para esas variables

Consecuencia:

- la integracion de referencia en ese punto esta incompleta o mal copiada

Impacto:

- la cadena de referencia no es confiable
- incluso si el plan trae buena informacion, el pegado posterior es fragil

### 6. El budget logico no es el budget real del set

Archivos:

- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/song_generator.py`
- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/server.py`
- `docs/VALIDATION_REPORT_EJEMPLO_2026-03-30.md`
- `KIMI_K2_ACTIVE_HANDOFF.md`

Hecho verificado:

- `SongGenerator.track_budget_max = 16` controla solo los blueprints del generador
- `server.py` despues agrega:
  - audio fallback
  - capas derivadas/resample
  - buses/returns
  - hook MIDI materializado
  - capas de referencia por arrangement

Consecuencia:

- el budget que parece correcto en manifest puede no coincidir con el delta real de tracks en Live

Impacto musical:

- el set termina sobrecargado
- y la sobrecarga misma destruye percepcion de identidad

### 7. El selector armonico hoy solo empuja `synth_loop`, no el universo tonal completo

Archivo:

- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/reference_listener.py`

Hecho verificado:

- `_select_layers_with_budget()` usa `_select_harmonic_layer()` solamente para `synth_loop`
- no hay un lock equivalente para `pad`, `lead`, `pluck`, `vocal_loop` o para la eleccion del family dominante del `PhrasePlan`

Consecuencia:

- el proyecto resuelve hints armonicos
- pero el resto del mundo tonal sigue relativamente suelto

Impacto musical:

- la referencia puede pedir `pluck`
- pero el plan, los clips y los apoyos pueden moverse igual a `pad/synth/lead`

### 8. El analyzer de coherencia actual sirve como termometro, no como contrato duro

Archivo:

- `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/coherence_analyzer.py`

Hecho verificado:

- `same_pack_ratio` usa carpeta padre de `audio_layers`, no linea de pack real
- `tonal_consistency` infiere key desde nombres cuando no hay metadata robusta
- todo esto ocurre despues de generar

Consecuencia:

- hoy el analyzer no puede ser la unica prueba de coherencia

Impacto:

- no optimices a la metrica antes de cerrar el wiring real de seleccion

## Lo que Kimi tiene que hacer ahora

Orden obligatorio.

### 1. Cerrar el wiring referencia -> blueprint

Objetivo:

- que la referencia influya antes de que existan los tracks/clips del config

Cambios esperados:

- pasar `harmonic_instrument_hints`, `micro_stem_summary`, `synth_loop_hint` y `locked_properties` dentro de `generate_config()` antes de `_generate_tracks_for_genre()`
- cambiar firmas para propagar `harmonic_hints` por:
  - `_generate_tracks_for_genre()`
  - `_build_scene_clips()`
  - `_render_scene_notes()`
  - `_render_musical_scene()`

Criterio:

- no aceptar un fix que solo copie esos campos al `config` al final

### 2. Reemplazar la familia aleatoria del PhrasePlan por un family lock real

Objetivo:

- una sola familia armonica dominante durante todo el track

Cambios esperados:

- agregar a `PhrasePlan` una forma explicita de recibir `primary_harmonic_family`
- esa familia debe salir de la referencia con prioridad:
  - `pluck`
  - `piano/keys`
  - `pad`
  - `lead`
- intro/build/drop/break/outro pueden mutar densidad, registro y energia
- no pueden cambiar de mundo timbrico porque si

Criterio:

- mismo `base_motif`
- misma `hook family`
- mutacion por seccion
- no random drift de `piano -> synth -> pluck -> pad`

### 3. Separar "hook planificado" de "hook materializado"

Objetivo:

- que el server no confunda estado interno con pista real creada en Live

Cambios esperados:

- dos flags o dos estados distintos:
  - `hook_planned`
  - `hook_materialized`
- o, si prefieres algo mas simple:
  - que `server.py` materialice el hook cuando no exista track real, aunque el generador ya haya armado `hook_data`

Criterio:

- al menos un track MIDI armonico verificable en Live
- no solo notas embebidas en un blueprint ambiguo

### 4. Elegir un solo motor real de section-aware + joint scoring

Objetivo:

- dejar de tener dos sistemas parciales que no se obligan entre si

Opcion recomendada:

- integrar el scoring de `sample_selector.py` dentro del flujo principal de `reference_listener.py`

Alternativa aceptable:

- portar la logica de joint scoring al selector interno de `reference_listener.py`
- y dejar de prometer `JOINT_SCORE` como si viniera del `SampleSelector`

Lo que no acepto:

- dejar `record_section_selection()` como decoracion
- seguir diciendo que `JOINT_SCORE` esta activo end-to-end sin evidencia

### 5. Endurecer la coherencia de pack para roles tonales y de soporte

Objetivo:

- que el mundo sonoro no cambie entre bajo, armonia, vocales y FX

Cambios esperados:

- `bass_loop`, `synth_loop`, `vocal_loop`, `atmos_fx`, `vocal_shot`, `fill_fx`, `snare_roll`
  deben salir del `dominant_pack` o de un sibling directo
- si no hay match coherente:
  - omitir layer
  - registrar omision en manifest/log

Criterio:

- mejor menos capas que una capa fuera de mundo

### 6. Hacer que el budget real viva en `server.py`, no solo en `SongGenerator`

Objetivo:

- que el track final no explote despues del plan lindo

Cambios esperados:

- gate real sobre:
  - audio fallback
  - derived layers
  - resample layers
  - hook extra
  - capas auxiliares
- manifest con:
  - `runtime_track_delta`
  - `omitted_for_budget`
  - `created_post_blueprint`

Criterio:

- no usar budget logico como excusa si Live termina con 30, 50 o 100 tracks nuevos

### 7. Arreglar el bloque roto de variables de referencia en `server.py`

Objetivo:

- eliminar integracion parcial que puede romper reference runs

Cambios esperados:

- definir correctamente `ref_musical_theme`, `ref_micro_stem`, `ref_synth_hint`
- o eliminar el bloque y usar una unica fuente de datos ya validada

### 8. Ajustar el analyzer de coherencia solo despues del wiring

Objetivo:

- usar metrica que mida lo mismo que intentas forzar

Cambios esperados despues del wiring principal:

- `same_pack_ratio` debe usar pack lineage real, no solo carpeta exacta
- `tonal_consistency` debe preferir metadata persistida del sample/plan cuando exista
- objetivo de coherencia para este sprint:
  - pack ratio de roles musicales > 0.75
  - conflictos tonales reales = 0 en `bass/music/hook`

## Lo que NO hay que tocar en este sprint

- `mcp_wrapper.py`
- `AbletonMCP_AI/__init__.py`
- `AbletonMCP_AI/Remote_Script.py`
- automatizacion fina de volumen/filtro/reverb
- master chain
- swarm/dashboard de Ralph

Si algo de eso se toca, que sea solo por bloqueo directo.

Hoy el problema esta en la cadena de seleccion, no en la capa de transporte.

## Criterio de aceptacion para este sprint

No cierres esta pasada hasta poder demostrar estas 8 cosas:

1. `reference_path` fuerza `key` y `bpm` finales o deja override explicado.
2. existe un `primary_harmonic_family` unico y trazable.
3. `PhrasePlan` respeta esa familia en todas las secciones principales.
4. el blueprint de tracks/clips ya nace con ese lock, no se parchea tarde.
5. existe un hook MIDI real en Live o en la evidencia runtime.
6. los roles de soporte no rompen `dominant_pack`.
7. el delta real de tracks queda dentro del budget acordado.
8. el manifest/smoke report muestran datos suficientes para revisar coherencia sin adivinar.

## Tests y evidencia que Kimi tiene que dejar

### Tests minimos

- mantener verde:
  - `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/tests/test_sample_selector.py`
  - `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/test_phrase_plan.py`

- agregar:
  - test que pruebe que `harmonic_instrument_hints` llega al blueprint antes de `_generate_tracks_for_genre()`
  - test que pruebe que `PhrasePlan` mantiene `primary_harmonic_family`
  - test que pruebe que el hook se materializa aunque haya sido "planificado"
  - test que pruebe que `reference_listener` usa el motor de joint scoring elegido

### Smoke obligatorio

Usar:

```powershell
python temp\smoke_test_async.py `
  --use-track `
  --genre reggaeton `
  --structure minimal `
  --reference "C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\libreria\reggaeton\ejemplo.mp3" `
  --save-report "temp\smoke_report_v010_coherence_review.json"
```

El reporte debe guardar ademas:

- `reference_path`
- `key_used`
- `bpm_used`
- `runtime_track_delta`
- `dominant_pack`
- `primary_harmonic_family`
- `midi_hook_created`
- `midi_hook_family`

## Review gate para cuando Kimi termine

Voy a revisar contra estas preguntas, no contra promesas:

1. ¿La referencia ahora influye el blueprint antes de la materializacion?
2. ¿La familia armonica dominante se mantiene o sigue habiendo drift por seccion?
3. ¿El hook existe en Live o solo en memoria?
4. ¿El section-aware scoring realmente cambia picks o sigue siendo decorativo?
5. ¿El budget real bajo o solo el budget logico?
6. ¿La evidencia runtime confirma lo mismo que dice el diff?

## Resumen final para Kimi

No intentes mejorar la coherencia agregando mas roles.

Haz esto:

1. fija una sola familia armonica dominante
2. haz que esa familia mande el `PhrasePlan`
3. haz que esos hints entren antes del blueprint
4. materializa un hook real
5. omite capas fuera de pack o fuera de family
6. mide el delta real de tracks

Si no logras eso, el track puede seguir "correcto", pero no va a sonar como una sola cancion.
