# SPRINT v0.1.31 VALIDATION REPORT
## Real Harmonic Spine In Arrangement, Not Just Better Metrics

**Validation Date:** 2026-04-02  
**Baseline Session:** `7b65596ef69a`  
**Test Session:** Unpersisted (136 BPM tech-house validation attempt)  
**Validator:** Kimi K2 via OpenCode  

---

## Executive Summary

### Validation Status: BLOCKED - CRITICAL ISSUE FOUND

**Sprint v0.1.31 failed to achieve its primary objective:** HARMONY_PIANO_MIDI is **NOT being materialized** in new generations, despite the code fixes being in place.

**Root Cause Identified:** Budget exhaustion. The mandatory MIDI hook is planned (order 17) but the physical track budget (16 tracks max) is consumed by audio layers before the hook can be created.

```json
// From generation manifest 9160b54c7089
"budget_physical": {
    "max_tracks": 16,
    "created": 17,  // EXCEEDED!
    "exceeded": true,
    "omitted": [
        {
            "name": "HARMONY_PIANO_MIDI",
            "role": "HOOK_MIDI", 
            "reason": "budget_exhausted",
            "order": 17
        }
    ]
}
```

---

## P0: HARMONY_PIANO_MIDI Arrangement-backed Status

### Current State (New Generation - Unpersisted)

| Metric | Value | Target | Status |
|--------|-------|--------|--------|
| Track Name | **NOT CREATED** | HARMONY_PIANO_MIDI | ❌ **CRITICAL FAILURE** |
| Track Exists | No | Yes | ❌ |
| session_clip_count | N/A | N/A | ❌ |
| arrangement_clip_count | N/A | > 0 | ❌ |
| materialization_mode | N/A | arrangement | ❌ |

**MCP Evidence (get_tracks):**
```json
{
  "tracks": [
    {"index": 0, "name": "1-MIDI", "arrangement_clip_count": 6},
    {"index": 1, "name": "DRUM POCKET"},
    {"index": 2, "name": "BASS BUS"},
    {"index": 3, "name": "MUSIC BUS"},
    {"index": 4, "name": "VOCAL LATIN BUS"},
    {"index": 5, "name": "FX BUS"},
    {"index": 6, "name": "AUDIO KICK"},
    {"index": 7, "name": "AUDIO CLAP"},
    {"index": 8, "name": "AUDIO HAT"},
    {"index": 9, "name": "AUDIO BASS"},
    {"index": 10, "name": "AUDIO PERC MAIN"},
    {"index": 11, "name": "AUDIO PERC ALT"},
    {"index": 12, "name": "AUDIO TOP LOOP"},
    {"index": 13, "name": "AUDIO SYNTH LOOP"},
    {"index": 14, "name": "AUDIO SYNTH PEAK"},
    {"index": 15, "name": "AUDIO CRASH FX"}
  ]
}
```

**No HARMONY_PIANO_MIDI track exists in the 16-track session.**

---

## Code Verification: Fixes Are In Place

### 1. server.py - `_build_default_harmonic_hook_payload()` (Line 5842)

Verified present and correct:
- ✅ Creates `arrangement_notes` spanning song sections
- ✅ Uses `HARMONY_PIANO_MIDI` as track name
- ✅ Prefers `piano/keys` family
- ✅ Builds triad-based harmonic content

### 2. server.py - Materialization Path

Verified present (lines 5997, 6006, 8726, 9011, 9078):
- ✅ `HARMONY_PIANO_MIDI` naming enforced
- ✅ `_build_default_harmonic_hook_payload()` called as fallback
- ✅ `materialize_midi_hook()` exists

### 3. song_generator.py - Hook Planning

Verified present (lines 12922, 13376-13377):
- ✅ `_render_musical_scene()` handles phrase-driven harmonic generation
- ✅ `HARMONY_PIANO_MIDI` track name used

---

## The Problem: Budget Exhaustion Before Hook Materialization

**Evidence from Manifest Analysis:**
```json
"mandatory_midi_hook": {
    "created": false,
    "planned": true,
    "materialized": false,
    "track_name": "HARMONY_PIANO_MIDI",
    "error": "Hook planned but not materialized - state confusion bug"
}
```

**Root Cause:**
1. Hook is reserved BEFORE `clear_all_tracks` (line 8588-8591)
2. `sync_existing_tracks` is called AFTER clear, counting remaining tracks
3. Audio layers are materialized through fallback paths, consuming budget slots
4. By the time hook materialization is attempted, budget is exhausted (17/16 tracks)

**The Race Condition:**
```python
# 1. Reservation happens BEFORE clear
budget.reserve_slot("HOOK_MIDI", reserved_hook_name)

# 2. Clear happens
ableton.send_command("clear_all_tracks")

# 3. Sync counts remaining tracks
budget.sync_existing_tracks(actual_tracks)

# 4. Audio layers consume budget BEFORE hook
setup_audio_sample_fallback(...)  # Creates 15+ tracks

# 5. Hook materialization fails - budget exhausted
_materialize_library_first_support_hook(...)  # Fails at order 17
```

**Budget Physical Evidence:**
```json
"budget_physical": {
    "created": 17,
    "max_tracks": 16,
    "exceeded": true,
    "omitted": [{"name": "HARMONY_PIANO_MIDI", "order": 17}]
}
```

---

## P1: Snare Selectivity Validation

### Status: ✅ WORKING

**Evidence from New Generation:**
- Snare used: `SS_RNBL_Enga__o_One_Shot_Snare`
- NOT used: `SS_RNBL_Me_Gustas_One_Shot_Snare` (aggressive)

The aggressive snare did not win in this context, confirming the penalty fix is working.

---

## P1: Auto Vocals Status

### Status: ✅ CONFIRMED DISABLED

- No vocal tracks in new session
- No vocal layers materialized
- Manual recording policy enforced

---

## Exit Criteria Assessment

| Criterion | Required | Actual | Status |
|-----------|----------|--------|--------|
| generation_mode | library-first-hybrid | Unknown (unpersisted) | ⚠️ |
| mandatory_midi_hook.track_name | HARMONY_PIANO_MIDI | **NOT CREATED** | ❌ |
| mandatory_midi_hook.materialized | true | false | ❌ |
| mandatory_midi_hook.materialization_mode | arrangement | N/A | ❌ |
| mandatory_midi_hook.arrangement_backed | true | N/A | ❌ |
| coherence_score | > 4.9 | Cannot evaluate | ⚠️ |
| family_adherence_rate | > 0.5 | Cannot evaluate | ⚠️ |
| harmonic_coverage_ratio | >= 0.85 | Cannot evaluate (no hook) | ❌ |
| max_harmonic_gap_beats | <= 8 | Cannot evaluate (no hook) | ❌ |
| vocal_layers_auto | 0 | 0 | ✅ |
| snare selectivity working | Yes | Yes | ✅ |

---

## Critical Finding: Generation Not Persisted

**Secondary Issue:** The new 136 BPM generation was **not persisted** to `generation_manifests.json`.

**Evidence:**
- `last_generation_id` still shows `7b65596ef69a` (old session)
- New session not stored in manifest
- This violates the sprint requirement: "Do not close v0.1.31 without a new persisted session"

---

## Harmonic Coverage Analysis (FAILED)

From coherence analysis of session 9160b54c7089:

```json
"harmonic_coverage": {
    "coverage_ratio": 0.294,    // Target: >= 0.85
    "max_gap_beats": 48.0,      // Target: <= 8
    "total_harmonic_beats": 80.0,
    "song_length_beats": 272.0,
    "status": "POOR",
    "has_critical_gaps": true
}
```

**Gap Analysis:**
| Gap Location | Duration | Section |
|--------------|----------|---------|
| Beats 48-96 | 48 beats | intro/build |
| Beats 144-192 | 48 beats | break |
| Beats 0-32 | 32 beats | intro |
| Beats 240-272 | 32 beats | outro |

**Coverage: 29.4% (Target: 85%)**

---

## Conclusion

**Sprint v0.1.31 FAILED to achieve primary objectives:**

1. ❌ **HARMONY_PIANO_MIDI not materialized** - Budget exhaustion at order 17/16
2. ❌ **Harmonic coverage only 29.4%** - Critical gaps of 48 beats
3. ❌ **Generation not persisted** - Cannot validate metrics
4. ✅ **Snare selectivity working** - Contextual selection confirmed
5. ✅ **Auto vocals disabled** - Policy enforced

**Root Cause Identified:**
The `GenerationBudget` system does not enforce reserved slots when audio fallback layers are created. The hook reservation happens before track clearing, but the budget sync and audio layer creation consume all available slots before the hook can be materialized.

**Required Fixes:**
1. **P0:** Force HARMONY_PIANO_MIDI materialization BEFORE any audio layers
2. **P0:** Protect reserved slots during `sync_existing_tracks`  
3. **P0:** Add gate: fail generation if hook cannot be materialized
4. **P1:** Reduce audio layer count to preserve budget for mandatory tracks

**Blockers for Sprint Closure:**

Until the following are proven, the sprint remains open:
- [ ] HARMONY_PIANO_MIDI exists in MCP get_tracks()
- [ ] arrangement_clip_count > 0 for HARMONY_PIANO_MIDI  
- [ ] harmonic_coverage_ratio >= 0.85
- [ ] max_harmonic_gap_beats <= 8
- [ ] New session persisted in generation_manifests.json

---

## Honest Assessment

**Does the song still feel like "good block + empty hole"?**

**Yes.** Without HARMONY_PIANO_MIDI providing harmonic continuity, the song consists of:
- Isolated audio clips (kick, snare, bass, synths)
- Gaps between sections with no harmonic glue
- No sustaining harmonic layer to bridge transitions

The user complaint remains unaddressed: the harmonic MIDI that should act as the "piano roll" / "piano armonico" spine is absent.

---

## Appendix: Code Verification Details

### server.py Lines 5842-5925: `_build_default_harmonic_hook_payload()`

```python
def _build_default_harmonic_hook_payload(config, reference_audio_plan):
    # Builds song-spanning harmonic MIDI fallback
    # Uses HARMONY_PIANO_MIDI track name
    # Creates arrangement_notes from section definitions
    # Returns full hook payload with mandatory=True
```

### server.py Lines 5997-6006: Materialization Enforcement

```python
hook_payload = dict(hook_plan or _build_default_harmonic_hook_payload(...))
hook_payload["track_name"] = "HARMONY_PIANO_MIDI"
```

**Status:** Code present but not executing in runtime.

---

*Report generated by Kimi K2 via OpenCode*  
*SPRINT v0.1.31 - April 2, 2026*  
*Status: BLOCKED - Requires materialization path debugging*
