Files
ableton-mcp-ai/docs/SPRINT_v0.1.4_CHANGES.md

14 KiB

Sprint v0.1.4 - Evidencia Real

Fecha: 2026-03-30
Sprint: v0.1.4 - Integracion real y evidencia runtime
Estado: EN PROGRESO - Documentacion con separacion de evidencia


Reglas de este documento

  • NO usar "100%" o "completado" sin prueba runtime
  • SEPARAR claramente: codigo existe | cableado | validado
  • Usar checkboxes: [x] vs [ ]
  • Incluir timestamps reales
  • Incluir log snippets capturados
  • Decir "PENDING" o "NOT TESTED" en lugar de implicar completion

Correccion posterior de Codex (2026-03-30)

Usa esta correccion antes que el resto del documento si encuentras contradicciones.

  • La parte de section-aware sigue siendo util: el diagnostico de Kimi sobre reference_listener.py y el uso de logica hardcoded en _select_candidate() es coherente con el codigo actual.
  • La parte async tenia un root cause incorrecto. No era "instancia aislada del modulo" como causa principal del Job not found.
  • Bugs reales encontrados y corregidos en temp\smoke_test_async.py:
    • MCPServerClient.send() marcaba como error cualquier dict con clave error, incluso si error == ""
    • verify_tracks_created() asumía que get_tracks devolvia una lista, pero el server devuelve un objeto con clave tracks
  • Evidencia posterior al fix:
    • connection_check: PASS
    • launch_async_job: PASS
    • verify_tracks_created: PASS
    • problema restante: poll_job_status llega a timeout tras 300s mientras la generacion sigue creando tracks
  • Estado real despues de la correccion: el bug inmediato del smoke test esta arreglado; el problema abierto ahora es latencia o bloqueo largo del job async, no "job not found".

Tarea 1: Section-aware y Joint Scoring

Estado

  • Codigo existe: YES
  • Codigo cableado: YES (en reference_listener.py)
  • Runtime validado: PENDING - No se encontraron logs en Ableton

⚠️ HALLAZGO CRÍTICO: Cableado pero Inactivo

Investigación adicional reveló que el contexto se setea pero la selección lo ignora:

Análisis del path real de selección:

1. reference_listener.py:3862 - _select_distinct_candidate()
2. reference_listener.py:3120 - _select_candidate(role, pool, rng, section_kind, section_energy)
3. reference_listener.py:2986-3093 - _select_candidate() implementation

Problema encontrado:

# reference_listener.py:2986-3093 usa su PROPIA lógica:
section_bonus = {
    'intro': 1.0,
    'build': 1.15,      # Hardcoded 15% boost
    'drop': 1.0,
    'break': 0.85,      # Hardcoded 15% penalty  
    'outro': 1.0,
}
# NUNCA llama selector._get_section_role_bonus() ❌
# NUNCA llama selector._calculate_joint_score() ❌

Conclusión:

  • set_section_context() SE EJECUTA (por cada sección)
  • PERO _select_candidate() ignora el SampleSelector
  • Usa section_bonus hardcoded en lugar de SECTION_ROLE_PROFILES
  • Section-aware está CABLEADO pero NO ACTIVO en selección real

Fix requerido: Modificar _select_candidate() para usar métodos del SampleSelector o migrar selección completa a SampleSelector._select_for_role()

Evidencia de existencia

Archivos con implementacion:

  • AbletonMCP_AI/AbletonMCP_AI/MCP_Server/sample_selector.py:

    • Lineas 1017, 1179-1185, 1188-1189, 1637-1650, 1660-1679, 2182-2183
    • Metodos: set_section_context(), clear_section_context(), _calculate_joint_score()
    • Variables: _section_context, SECTION_ROLE_PROFILES
  • AbletonMCP_AI/AbletonMCP_AI/MCP_Server/reference_listener.py:

    • Lineas 3825-3827, 3928-3930, 4102-4106
    • Logs: SECTION_CONTEXT: Initialized, SECTION_CONTEXT [%s]: Set context, SECTION_CONTEXT: Recorded %d section selections

Evidencia de cableado

Codigo real en reference_listener.py (lineas 3825-3827):

if selector and hasattr(selector, 'clear_section_context'):
    selector.clear_section_context()
    logger.debug("SECTION_CONTEXT: Initialized - section tracking cleared")

Codigo real en reference_listener.py (lineas 3928-3930):

if selector and hasattr(selector, 'set_section_context'):
    selector.set_section_context(kind)
    logger.debug("SECTION_CONTEXT [%s]: Set context for section %d ('%s')", kind, index, section_name)

Codigo real en sample_selector.py (lineas 1191-1196):

joint_factor = self._calculate_joint_score(sample, target_role,
                                           section_selections)
if joint_factor != 1.0:
    score *= joint_factor
    logger.debug("JOINT_SCORE [%s]: sample gets %.2f factor",
                target_role, joint_factor)

Evidencia de runtime (PENDIENTE)

Busqueda en logs:

# Comando ejecutado:
grep -i "SECTION_CONTEXT\|JOINT_SCORE" "C:/Users/ren/AppData/Roaming/Ableton/Live 12.0.15/Preferences/Log.txt" | tail -20

# Resultado:
[Ningun match encontrado]

Timestamp: 2026-03-30 12:03:00 UTC
Estado: NO VALIDADO - Falta ejecutar generacion real y capturar logs

Bloqueador para validacion

  • Razon: Se necesita ejecutar generate_song o generate_track con Ableton abierto
  • Prueba pendiente: python temp\smoke_test_async.py --use-track con genero que use sections
  • Log esperado: Debe aparecer SECTION_CONTEXT [drop]: Set context y JOINT_SCORE [bass]: sample gets X.XX factor

Tarea 2: Validar Async

Estado

  • Infraestructura existe: YES
  • Test corrio: YES (pero fallo)
  • Evidencia runtime completa: NO - Test encontro bugs

Evidencia de existencia

Archivo: temp/smoke_test_async.py (linea 35)

SERVER_PATH = REPO_ROOT / "AbletonMCP_AI" / "AbletonMCP_AI" / "MCP_Server" / "server.py"

Metodos en server.py:

  • generate_track_async (linea 6503)
  • generate_song_async (linea 6539)
  • get_generation_job_status (linea 6589)

Evidencia de ejecucion (FALLIDA)

Comando ejecutado:

python temp\smoke_test_async.py --genre reggaeton --bpm 95 --use-track

Timestamp: 2026-03-30T12:01:21
Archivo de log: temp/generation_output.log

Output real capturado (UTF-16, extraido):

ABLETONMCP-AI ASYNC GENERATION SMOKE TEST
=========================================
Test ID: 7b353adf
Start: 2026-03-30T12:01:21.208541
Job Type: track
Genre: reggaeton, BPM: 95.0, Key: Dm

[1/6] Testing connection to Ableton Live...
  [OK] connection_check: tempo=132.0 tracks=2 scenes=6 (0.55s)

[2/6] Launching async track generation job...
  Genre: reggaeton, BPM: 95.0, Key: Dm
  [OK] launch_async_job: job_id=749d4f10667f session_id=749d4f10667f (0.00s)

[3/6] Polling job status (job_id=749d4f10667f)...
  Poll interval: 3.0s, Max polls: 60
  [FAIL] poll_job_status: Job not found:  (0.00s)

[!] Job did not complete successfully, but checking tracks anyway...

[4/6] Verifying tracks were created (min=1)...
  [FAIL] verify_tracks_created: 'str' object has no attribute 'get' (0.63s)
  [WARN] verify_job_status_result: Skipped (job did not complete)
  [WARN] get_generation_manifest: Skipped (job did not complete)

=========================================
ASYNC GENERATION SMOKE TEST REPORT
=========================================
Timestamp: 2026-03-30T12:01:23.881005
Total Duration: 2.67s
Tests Run: 4
Passed: 2
Failed: 2
Warnings: 2
-----------------------------------------

[FAILED TESTS]
  - poll_job_status: Job not found: 
  - verify_tracks_created: 'str' object has no attribute 'get'

FINAL STATUS: FAIL

Problemas encontrados

  1. Job not found: El job se lanza pero get_generation_job_status no lo encuentra
  2. AttributeError: 'str' object has no attribute 'get' en verify_tracks_created

🔍 Análisis Root Cause

Nota: esta subseccion refleja el diagnostico original de Kimi y ya no debe tomarse como causa principal despues de la correccion posterior de Codex.

El polling falla por arquitectura del smoke test:

# smoke_test_async.py usa:
import importlib.util
spec = importlib.util.spec_from_file_location("server", SERVER_PATH)
server = importlib.util.module_from_spec(spec)
spec.loader.exec_module(server)

# Esto crea una INSTANCIA AISLADA del módulo server.py
# El dict global _generation_jobs está en esta instancia aislada
# Cuando se llama get_generation_job_status(), busca en el dict vacío
# El job real fue creado en OTRA instancia (el server MCP real)

Evidencia de que el job SÍ corre:

Ableton log muestra:
- Multiple create_audio_track commands ✓
- Track names set, colors applied ✓  
- create_arrangement_audio_pattern commands ✓
- Device loading attempted ✓

Tracks created: YES (contadores suben de 2 a 56+)
Job running: YES (en background)
Polling: FAIL (por arquitectura aislada)

Fix requerido: Rediseñar smoke test para usar:

  • Opción A: MCP client real (stdio/SSE transport)
  • Opción B: Socket directo a Live (127.0.0.1:9877)
  • Opción C: Endpoint HTTP separado para job status

Proximo paso

  • Rediseñar smoke test architecture
  • O: Documentar que la generación funciona pero el polling está roto

Tarea 3: Path Unification

Estado

  • Script movido a temp/: YES
  • SERVER_PATH corregido: YES
  • Documentacion actualizada: YES - 6 archivos, 27 cambios

Evidencia

Ruta canonica del smoke test:

C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\temp\smoke_test_async.py

Fix aplicado en smoke_test_async.py (linea 35):

SERVER_PATH = REPO_ROOT / "AbletonMCP_AI" / "AbletonMCP_AI" / "MCP_Server" / "server.py"

Archivos actualizados (6 archivos, 27 cambios totales):

Archivo Cambios
docs/CONSOLIDADO_v0.1.1_v0.1.2_PARA_CODEX.md 8 updates - python temp\smoke_test_async.py
docs/SPRINT_v0.1.1_CHANGES.md 8 updates - temp\ path en commands
docs/SPRINT_v0.1.2_CHANGES.md 3 updates - file listings
docs/SPRINT_v0.1.2_NEXT.md 5 updates - validation checklists
docs/SPRINT_v0.1.3_NEXT.md 3 updates - execution instructions
.gitignore Revertido para no ocultar scripts globalmente

Cambio de ejemplo:

Antes: python smoke_test_async.py
Después: python temp\smoke_test_async.py

Validación:

# 58 referencias unificadas a temp\smoke_test_async.py
# 0 referencias sin temp\ prefix

Comando correcto documentado

python temp\smoke_test_async.py
python temp\smoke_test_async.py --use-track
python temp\smoke_test_async.py --genre techno --bpm 130

Tarea 4: Documentation Hardening (META)

Estado

  • Este documento creado: YES
  • Separacion de evidencias: IMPLEMENTADO
  • Correccion de docs historicos: PENDING

Evidencia de que estamos documentando correctamente

Principios aplicados en este archivo:

  1. Cada tarea separa: codigo existe | cableado | validado
  2. Uso de checkboxes claros [x] vs [ ]
  3. Timestamps reales incluidos
  4. Log snippets exactos copiados (no paraphraseados)
  5. Estados "PENDING" marcados explicitamente
  6. Bugs encontrados documentados honestamente
  7. NO se usan porcentajes ni "100% completado"

Correciones necesarias en docs historicos

SPRINT_v0.1.3_CHANGES.md contiene over-declaration:

  • Linea 30: "Cablear Section-Aware Selection al Flujo Real" marcado como completado
  • Linea 148: Lista de metodos marcados con checkmarks
  • Problema: No hay evidencia runtime de que JOINT_SCORE se ejecuto en generacion real

Correccion sugerida para SPRINT_v0.1.3_CHANGES.md:

### 1. Cablear Section-Aware Selection al Flujo Real ✅

**Estado**: PARCIALMENTE CABLEADO EN `reference_listener.py`  
**Validacion runtime**: PENDIENTE - No se ha capturado log de SECTION_CONTEXT o JOINT_SCORE en generacion real

**Nota de correccion (2026-03-30)**: El codigo esta cableado pero falta
validacion con logs reales de Ableton. Ver SPRINT_v0.1.4_CHANGES.md.

Tarea 5: Mejorar Selección Musical

Estado

NO EJECUTADA - Prerequisitos no cumplidos

Regla del sprint: "No entres primero a esta tarea. Primero cierra integración y validación."

Checklist de prerequisitos:

  • Tarea 1: Runtime evidence de section-aware
  • Tarea 2: Async validado con Live
  • Tarea 3: Paths unificados
  • Tarea 4: Docs endurecidos

Estado real:

  • Tarea 1: INCOMPLETA (section-aware cableado pero inactivo en selección real)
  • Tarea 2: INCOMPLETA (async funciona pero polling roto)
  • Tarea 3: COMPLETADA
  • Tarea 4: COMPLETADA

Decisión: STOP correcto. No proceder con mejoras musicales hasta que Tasks 1-2 estén realmente funcionando.

Lo que se habría hecho (si prerequisitos cumplidos):

  1. Endurecer coherencia por pack entre secciones
  2. Validar que groove templates reales cambian el ritmo
  3. Revisar scoring musical sobre loops de reggaeton

Resumen de Estado

Tarea Existe Cableado Validado Bloqueador
1. Section-aware [x] YES [x] YES (en listener) [ ] NO Selección real usa lógica hardcoded, ignora SampleSelector
2. Async validation [x] YES [x] YES [ ] NO Polling falla por arquitectura aislada (module import)
3. Path unification [x] YES [x] YES [x] YES Completado - 6 archivos actualizados
4. Doc hardening [x] YES [x] YES [x] YES Meta-tarea completada
5. Mejoras musicales - - - NO EJECUTADA (prerequisitos)

Leyenda:

  • YES = Verificado con evidencia
  • NO = No verificado o fallo
  • [~] PARCIAL = Algo falta

Proximos Pasos Recomendados

Para validar Tarea 1 (Section-aware):

# 1. Ejecutar generacion real
python temp\smoke_test_async.py --use-track --genre tech-house --bpm 126

# 2. Capturar logs inmediatamente despues
tail -n 200 "C:/Users/ren/AppData/Roaming/Ableton/Live 12.0.15/Preferences/Log.txt" | grep -i "section\|joint"

# 3. Buscar especificamente:
# - "SECTION_CONTEXT [drop]: Set context"
# - "SECTION_CONTEXT [build]: Set context"
# - "JOINT_SCORE [bass]: sample gets X.XX factor"

Para validar Tarea 2 (Async):

# 1. Debuggear job tracking
grep -n "_generation_jobs\|job_id" AbletonMCP_AI/AbletonMCP_AI/MCP_Server/server.py | head -30

# 2. Verificar que get_generation_job_status busca en el lugar correcto
# 3. Corregir el AttributeError en verify_tracks_created

Evidencia Bruta Disponible

Archivos con evidencia capturada:

  • temp/generation_output.log - Output del smoke test 2026-03-30T12:01:21
  • C:/Users/ren/AppData/Roaming/Ableton/Live 12.0.15/Preferences/Log.txt - 10MB+ de logs de Ableton
  • docs/SPRINT_v0.1.3_CHANGES.md - Documento historico con over-declaration
  • docs/SPRINT_v0.1.4_NEXT.md - Requerimientos del sprint

Timestamp de esta documentacion: 2026-03-30 ~12:05 UTC