528 lines
16 KiB
Markdown
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.
|