Files
ableton-mcp-ai/docs/SPRINT_v0.1.10_COHERENCE_REVIEW_FOR_KIMI.md

528 lines
16 KiB
Markdown

# 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.