feat: SDD workflow — test sync, song generation + validation, ReaScript hybrid pipeline

- compose-test-sync: fix 3 failing tests (NOTE_TO_MIDI, DrumLoopAnalyzer mock, section name)
- generate-song: CLI wrapper + RPP validator (6 structural checks) + 4 e2e tests
- reascript-hybrid: ReaScriptGenerator + command protocol + CLI + 16 unit tests
- 110/110 tests passing
- Full SDD cycle (propose→spec→design→tasks→apply→verify) for all 3 changes
This commit is contained in:
renato97
2026-05-03 22:00:26 -03:00
parent 7729d5f12f
commit 48bc271afc
25 changed files with 2842 additions and 343 deletions

View File

@@ -0,0 +1,31 @@
# Tasks: generate-song CLI
## Phase 1: Foundation — RPP Validator
- [x] 1.1 Create `src/validator/rpp_validator.py` with `validate_rpp_output(rpp_path: str) -> list[str]`
- [x] 1.2 Implement track count check — count `<TRACK` blocks, assert == 9
- [x] 1.3 Implement audio path check — regex `<SOURCE WAVE "([^"]+)"`, verify files exist
- [x] 1.4 Implement MIDI note presence check — find `<ITEM>` blocks with `<SOURCE MIDI>`, count `NOTE \d+ \d+ \d+` entries
- [x] 1.5 Implement arrangement duration check — find last item position + length, assert >= 52 bars × 4 beats
- [x] 1.6 Implement send routing check — each non-return track must have `AUXRECV`
- [x] 1.7 Implement plugin chain check — each non-return track must have `<FXCHAIN>` with `VST` entry
## Phase 2: Core Implementation — CLI Wrapper
- [x] 2.1 Create `scripts/generate.py` with argparse: `--bpm` (float, default 95), `--key` (default "Am"), `--output` (default "output/song.rpp"), `--seed` (int, default 42), `--validate` (flag)
- [x] 2.2 Add BPM validation — raise `ValueError` if `bpm <= 0`
- [x] 2.3 Add output directory creation — `output_path.parent.mkdir(parents=True, exist_ok=True)`
- [x] 2.4 Wire `compose.main()` — set `sys.argv` and call `compose.main()` directly (not subprocess)
- [x] 2.5 Wire `--validate` flag — call `validate_rpp_output()` and `sys.exit(1)` on errors
## Phase 3: Testing
- [x] 3.1 Write `tests/test_generate_song.py::test_generate_cli_smoke` — subprocess call, assert returncode 0, file exists, size > 0
- [x] 3.2 Write `tests/test_generate_song.py::test_validate_passes_for_valid_output` — CLI with `--validate`, assert `errors == []`
- [x] 3.3 Write `tests/test_generate_song.py::test_validate_detects_track_count_violation` — synthesize 5-track .rpp, assert "Expected 9" in errors
- [x] 3.4 Write `tests/test_generate_song.py::test_reproducibility_same_seed` — run CLI twice with `--seed 42`, assert byte-identical output
## Phase 4: Verification
- [x] 4.1 Run full test suite — `pytest tests/` — verify all 90+ tests pass (existing + new)
- [x] 4.2 Run new tests in isolation — `pytest tests/test_generate_song.py -v` — confirm 4 tests pass