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