# PhrasePlan Implementation Summary

## Overview

Created a **PhrasePlan** class system that transforms the generation from thinking in long loops to thinking in short hook phrases that mutate across sections while maintaining coherence.

## Files Modified

### 1. `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/song_generator.py`

Added **355 lines** containing:

- **`Phrase` dataclass**: Represents a single melodic phrase/hook
- **`PhrasePlan` class**: Plans melodic phrases across song sections
- **Mutation algorithms**: sparse, tension, full, response, fade
- **Integration method**: `from_musical_theme()` for easy creation from existing themes

### 2. `AbletonMCP_AI/AbletonMCP_AI/MCP_Server/server.py`

Modified to:

- Import `PhrasePlan` from song_generator
- Create phrase plan after musical theme initialization (line ~5962)
- Add phrase plan to generation manifest (line ~6252)
- Log phrase plan creation and mutation distribution

## Key Features

### Phrase Data Structure
```python
@dataclass
class Phrase:
    start: float              # Bar position
    end: float
    kind: str                 # 'hook', 'response', 'variation', 'fill'
    role: str                 # 'synth', 'bass', 'pad', 'pluck', 'lead'
    family: str               # 'pluck', 'pad', 'piano', 'keys', 'synth'
    instrument_hint: Dict     # ADSR recommendations
    mutation_type: str         # 'sparse', 'tension', 'full', 'response', 'fade'
    notes: List[Dict]         # MIDI note data
    section_kind: str         # 'intro', 'build', 'drop', 'break', 'outro'
```

### Section Mutation Rules

| Section | Mutation | Result |
|---------|----------|--------|
| **Intro** | `sparse` | Every other note, reduced complexity |
| **Build** | `tension` | Adds anticipation pickups, passing notes |
| **Drop** | `full` | Complete hook, doubled for emphasis |
| **Break** | `response` | Minimal, just first and last notes |
| **Outro** | `fade` | Reduced velocity, longer sustains |

### Instrument Family Assignment

- **Drop**: pluck, synth, lead (bright, punchy)
- **Break**: pad, pluck (atmospheric, minimal)
- **Build**: synth, pluck, keys (tension-building)
- **Intro**: pluck, pad, piano (sparse, setting mood)
- **Outro**: pad, pluck (fading, resolving)

## Test Results

### Example Output

```
PHRASE PLAN TEST
============================================================

1. Creating Musical Theme...
   Key: Am, Scale: minor, Seed: 42
   Base motif: 6 notes
   Pitches: [69, 74, 69, 69, 74, 69]

3. Creating Phrase Plan...
   Phrase plan created with 11 phrases

5. Mutation Verification:
------------------------------------------------------------
   [OK] intro: sparse (expected: sparse)
   [OK] build: tension (expected: tension)
   [OK] drop: full (expected: full)
   [OK] break: response (expected: response)
   [OK] outro: fade (expected: fade)

6. Manifest Structure:
------------------------------------------------------------
   Key: Am
   Scale: minor
   Base motif length: 6
   Phrase count: 11
   Sections covered: 7
   Mutation summary: {'sparse': 1, 'tension': 4, 'full': 4, 'response': 1, 'fade': 1}
```

## Usage

### Creating a Phrase Plan

```python
from song_generator import MusicalTheme, PhrasePlan

# Create theme
theme = MusicalTheme(key='Am', scale='minor', seed=42)

# Define sections
sections = [
    {'kind': 'intro', 'start_bar': 0, 'end_bar': 8},
    {'kind': 'build', 'start_bar': 8, 'end_bar': 16},
    {'kind': 'drop', 'start_bar': 16, 'end_bar': 32},
    {'kind': 'break', 'start_bar': 32, 'end_bar': 40},
    {'kind': 'outro', 'start_bar': 40, 'end_bar': 48},
]

# Create phrase plan
phrase_plan = PhrasePlan.from_musical_theme(theme, sections)

# Access phrases
for phrase in phrase_plan.phrases:
    print(f"{phrase.section_kind}: {phrase.mutation_type} ({len(phrase.notes)} notes)")

# Get manifest data
manifest_entry = phrase_plan.to_dict()
```

### Accessing from Manifest

```python
# After generation, the phrase plan is stored in manifest
manifest = _get_stored_manifest()
phrase_plan_data = manifest.get('phrase_plan')

# Structure:
{
    'key': 'Am',
    'scale': 'minor',
    'base_motif_notes': [69, 74, 69, 69, 74, 69],
    'base_motif_length': 6,
    'phrase_count': 11,
    'sections_covered': 7,
    'phrases': [...],
    'mutation_summary': {'sparse': 1, 'tension': 4, 'full': 4, 'response': 1, 'fade': 1}
}
```

## Benefits

1. **Coherence**: Base motif ensures all phrases are related
2. **Variety**: Mutations provide section-appropriate variations
3. **Clarity**: Each phrase has explicit metadata (kind, role, mutation)
4. **Manifest Storage**: Full phrase plan stored for debugging/analysis
5. **Materialization Ready**: Notes are pre-generated and ready for MIDI creation

## Next Steps

To materialize phrases into Ableton:

1. Use `phrase.notes` to create MIDI clips
2. Apply `phrase.instrument_hint` for synth configuration
3. Place clips at `phrase.start` for `phrase.end - phrase.start` duration
4. Use `phrase.family` to select appropriate instrument/sound
5. Apply section-specific processing based on `phrase.mutation_type`

## Integration Points

The phrase plan is automatically:
- Created during `generate_song()` after musical theme initialization
- Stored in the generation manifest under `phrase_plan` key
- Available via `_get_stored_manifest()` after generation
- Logged with mutation distribution summary

This enables post-generation analysis and phrase-based materialization workflows.
