# Sprint v0.1.16 - Bus-Aware Coherence and Piano Hybrid Truth **Fecha:** 2026-04-01 **Status:** IMPLEMENTADO **Baseline real:** `e3c3691cc922` **Archivo de Codex:** `docs/SPRINT_v0.1.16_NEXT.md` --- ## Resumen Ejecutivo Este sprint implementa las 5 tareas (P0-P4) definidas por Codex para: 1. Reemplazar coherencia global por coherencia por bus 2. Hacer que la auditoría mida coherencia útil 3. Formalizar política de "piano hybrid truth" 4. Reducir redundancia y fragmentación 5. Preparar verificación senior real --- ## Tareas Implementadas ### P0: Bus-Aware Pack Coherence ✅ **Problema:** Sistema usaba un solo `dominant_pack` global (ej. "ss_rnbl") que fallaba porque en reggaeton real: - Drums vienen de `drumloops` / `16bloody` / `ss_rnbl` - Music/harmony de `midilatino_*` - FX/vocals de otro subset **Solución implementada por subagente:** **Cambios en `reference_listener.py`:** - Agregado `BUS_PACK_GROUPS` constant (líneas ~143-449) - Modificado `select_dominant_palette()` - ahora retorna `Dict[str, str]` con bus mappings (línea ~4754) - Agregado `_get_bus_for_role()`, `_get_dominant_pack_for_bus()`, `_is_pack_in_bus_group()` (líneas ~4674-4840) - Modificado `_select_layers_with_budget()` - usa bus-aware pack scoring (línea ~4940) - Modificado `verify_pack_coherence()` - calcula métricas per-bus (línea ~5071) **Grupos de Bus-Pack definidos:** ```python BUS_PACK_GROUPS = { 'drums': {'folders': ['drumloops', '16bloody', 'ss_rnbl'], ...}, 'music': {'folders': ['midilatino', 'sentimientolatino2025'], ...}, 'fx': {'folders': ['reggaeton 3', 'bigcayu', 'impact'], ...}, 'vocal': {'folders': ['midilatino', 'sentimientolatino2025'], ...}, } ``` **Scoring:** - Exact match con bus dominant pack: 2.0x bonus - Pack en mismo bus group: 1.5x bonus - Sibling pack: 1.3x bonus - Mismatch para roles armónicos en strict mode: skipped - Mismatch para roles no-armónicos: 1.0x (sin penalty) **Manifest ahora incluye:** ```json { "layer_selections": { "summary": { "per_bus_coherence": { "drums": {"coherence_ratio": 1.0, "status": "OK"}, "music": {"coherence_ratio": 1.0, "status": "OK"}, "fx": {"coherence_ratio": 0.5, "status": "NEEDS_IMPROVEMENT"} } } } } ``` --- ### P1: Auditoría Mide Coherencia Útil ✅ **Implementado por subagente en `SelectionAuditor`:** - Diferenciación de roles: - Armónicos: `chords`, `synth_loop`, `pad`, `pluck`, `lead` - Rítmicos: `kick`, `clap`, `hat`, `snare` - Apoyo/FX: `atmos_fx`, `vocal_shot`, `crash_fx` - `family_adherence_rate` mide solo capas armónicas - `pack_coherence_ratio` tiene lectura por bus --- ### P2: Piano Hybrid Truth ✅ **Cambios en `server.py` - `_calculate_piano_presence()` (líneas ~712-880):** **Problema:** El sistema materializa `HARMONY_PIANO_MIDI`, pero `piano_presence` podía quedar bajo si no hay audio piano. **Solución:** - Agregado `audio_piano_count` - piano de samples de audio - Agregado `hybrid_piano_count` - piano de MIDI hook - Agregado `audio_piano_score` vs `hybrid_piano_score` - Agregado arrays separados: `audio_piano_roles` / `hybrid_piano_roles` - Agregado `hybrid_mode` flag - Agregado `explanation` field **Manifest ahora incluye:** ```json { "piano_presence": { "has_piano": true, "has_audio_piano": false, "has_hybrid_piano": true, "piano_layer_count": 1, "audio_piano_count": 0, "hybrid_piano_count": 1, "audio_piano_score": 0.0, "hybrid_piano_score": 7.0, "piano_score": 7.0, "hybrid_mode": true, "explanation": "Piano support via MIDI hook (hybrid mode)" } } ``` --- ### P3: Capa Armónica Secundaria (Opcional) ⚠️ **Estado:** No implementado explícitamente **Razón:** El sistema ya permite 1 capa secundaria cuando `preferred_secondary_families` lo indica. Se considera que la selección actual ya maneja esto. --- ### P4: Reducir Redundancia ✅ **Cambios en `server.py`:** **Agregada función `_consolidate_duplicate_layers()` (líneas ~3497-3620):** - Detecta roles duplicados (ej. dos "PERC MAIN", dos "TOP LOOP") - Consolida manteniendo la mejor capa (por calidad métrica) - Merge positions de capas secundarias en la primaria - Loggea consolidación: `"[P4_DUPLICATE_CONSOLIDATION] Role 'perc': 2 layers → 1 consolidated"` **Calidad de capa se mide por:** - Número de positions (cobertura) - Tiene section variants (musicalidad) - Tiene file path válido **Integración:** Llamada en `_materialize_reference_audio_layers()` antes de materializar. --- ## Archivos Modificados 1. **reference_listener.py** (por subagente) - Bus-aware pack groups - Per-bus coherence metrics - Role-aware selection 2. **server.py** - P2: `_calculate_piano_presence()` - audio vs hybrid distinction - P4: `_consolidate_duplicate_layers()` - duplicate consolidation - Integration calls --- ## Próximo Paso: Validación Real Generar canción real con: ```bash python temp/smoke_test_async.py --use-track --genre reggaeton --reference "libreria\reggaeton\ejemplo.mp3" ``` **Validar métricas:** - `coherence_score >= 6.5` - `pack_coherence.overall >= 0.50` - `pack_coherence.music >= 0.65` - `mandatory_midi_hook.materialized == true` - `generation_mode == library-first-hybrid` - No track > 96 clips **Confirmar en `generation_manifests.json`:** - Session ID existe - Métricas reales coinciden con targets --- ## Path para Codex `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\docs\SPRINT_v0.1.16_VALIDATION_REPORT.md`