# Proposal: Hook-Based Reggaeton Melody

## Intent

`build_lead_track()` generates random pentatonic notes — no hook, no identity, no rhythmic motif. Professional reggaeton leads have memorable hooks (repeating motif), rhythmic alignment with the dembow grid, call-and-response structure, and chord-tone emphasis on strong beats. This change replaces random generation with a structured hook engine producing identifiable, repeating motifs with controlled variation.

## Scope

### In Scope
- **Hook engine module** (`src/composer/melody_engine.py`) — generates motifs, variations, call-response
- **3 reggaeton styles**: "stabs" (syncopated hits on 1, 2.5, 3, 3.5), "smooth" (stepwise eighth notes), "hook" (arch contour, chord tones on strong beats)
- **Motif + variation loop**: 2–4 bar motif repeated 2–4x with transpose/rhythmic-shift variations
- **Call-and-response**: first half = call (ends on V/VII), second half = response (resolves to i)
- **Chord-aware note selection**: strong beats (1, 3) favor chord tones; weak beats use scale passing tones
- **Replace `build_lead_track()`** in `compose.py` to delegate to the new engine
- **Tests** for deterministic output, motif identity preserved across variations, call-response resolution

### Out of Scope
- MIDI velocity humanization / groove quantization
- User-selectable style at CLI (hardcoded to "hook" style initially)
- Chord progression generation (uses existing `CHORD_PROGRESSION` from compose.py)
- Pad/chords/bass refactoring — lead only

## Capabilities

### New Capabilities
- `melody-engine`: Deterministic hook generation with motif, variation, call-response, and 3 reggaeton styles. Chord-aware via `CHORD_PROGRESSION` input.

### Modified Capabilities
- None at spec level. `build_lead_track()` API unchanged (same signature). Behavior changes from random to deterministic, but callers see same interface.

## Approach

New module `src/composer/melody_engine.py` with:

1. **`build_motif(key_root, key_minor, style, bars=4)`** → `list[MidiNote]`
   - Style "hook": arch contour, chord tones on 0, 2, 4... beats, 4–8 notes
   - Style "stabs": short 16th hits on [1.0, 2.5, 3.0, 3.5] per bar
   - Style "smooth": stepwise scalar motion at eighth-note density
   - Chords resolved from `CHORD_PROGRESSION` for chord-tone selection

2. **`apply_variation(motif, shift=0, transpose=0)`** → variation
   - Rhythmic shift: offset within the grid
   - Transpose: ±octave or ±third within scale

3. **`build_call_response(motif, sections, key_root, key_minor)`** → `list[ClipDef]`
   - First half = call (motif + slight variation, ends on tension note)
   - Second half = response (motif, resolves to tonic)
   - Repeats for section length

`compose.py` `build_lead_track()` becomes thin wrapper calling `melody_engine`. All existing tests pass with updated expected values.

## Affected Areas

| Area | Impact | Description |
|------|--------|-------------|
| `src/composer/melody_engine.py` | New | Hook engine — motifs, variations, call-response |
| `scripts/compose.py` | Modified | `build_lead_track()` delegates to melody_engine; `get_pentatonic()` stays as helper |
| `tests/test_compose_integration.py` | Modified | Update `test_melody_uses_pentatonic` to assert motif structure |
| `tests/test_section_builder.py` | None | `get_pentatonic` tests unaffected |

## Risks

| Risk | Likelihood | Mitigation |
|------|------------|------------|
| Deterministic melody sounds repetitive | Med | 3 style options + variation params provide diversity; section energy scales velocity |
| Chord-awareness breaks if CHORD_PROGRESSION changes format | Low | Hardcoded in compose.py — same module owns both; integration test catches mismatch |
| Motif too short for long sections (8+ bars) | Low | Call-response repeats motif to fill bars; edge case validated in tests |

## Rollback Plan

Revert `build_lead_track()` to original random-pentatonic implementation (git revert). No schema or API changes — pure function replacement.

## Dependencies

- `CHORD_PROGRESSION` constant from `compose.py` (existing)
- `get_pentatonic()` helper from `compose.py` (kept, reused)

## Success Criteria

- [ ] `build_lead_track()` produces identical output for same seed+key input (deterministic)
- [ ] Generated melody contains a repeating 2–4 bar motif with ≤2 variations
- [ ] Call section ends on V or VII degree; response resolves to i
- [ ] Strong beats (quarter positions) use chord tones ≥70% of the time
- [ ] All 110+ existing tests pass
- [ ] 5+ new tests for melody_engine: motif identity, variation bounds, call-response resolution
