cgcardona / muse public
muse-variation-spec.md markdown
215 lines 5.3 KB
9ee9c39c refactor: rename music→midi domain, strip all 5-dim backward compat Gabriel Cardona <gabriel@tellurstori.com> 1d ago
1 # Muse Variation Spec — Music Domain Reference
2
3 > **Scope:** This spec describes the *Variation* UX pattern as implemented
4 > for the MIDI domain. It is not part of the core Muse VCS engine.
5 >
6 > For the domain-agnostic VCS protocol, see [muse-protocol.md](muse-protocol.md).
7 > For a discussion of how "Variation" might generalize across domains, see
8 > [muse-domain-concepts.md](muse-domain-concepts.md).
9
10 ---
11
12 ## What a Variation Is
13
14 A Variation is a **proposed musical change set awaiting human review** before
15 being committed to the Muse DAG. It is the music plugin's implementation of the
16 propose → review → commit pattern.
17
18 ```
19 VCS equivalent mapping:
20 Variation = A staged diff
21 Phrase = A hunk (contiguous group of changes within a region)
22 Accept = muse commit
23 Discard = Discard working-tree changes (no commit)
24 Undo = muse revert
25 ```
26
27 The defining characteristic: a Variation is *heard before committed* — the
28 musician auditions the proposed change in the DAW's playback engine and then
29 decides whether to accept or discard. This is layered on top of the VCS DAG,
30 not part of it.
31
32 ---
33
34 ## Lifecycle
35
36 ```
37 1. Variation Proposed — AI or user creates a proposed change set
38 2. Stream — phrases stream to the DAW in SSE events
39 3. Review Mode Active — DAW shows proposed state alongside canonical state
40 4. Accept (or partial) — accepted phrases are committed; discarded phrases are dropped
41 5. Canonical state updates — only after commit
42 ```
43
44 Canonical state MUST NOT change during review. The proposed state is always
45 ephemeral.
46
47 ---
48
49 ## Terminology
50
51 | Term | Definition |
52 |---|---|
53 | **Variation** | A proposed set of musical changes, organized as phrases |
54 | **Phrase** | A bounded group of note/controller changes within one region |
55 | **NoteChange** | An atomic note delta: added, removed, or modified |
56 | **Canonical State** | The actual committed project state in the Muse DAG |
57 | **Proposed State** | The ephemeral preview state during variation review |
58 | **Accept** | Committing accepted phrases to the Muse DAG |
59 | **Discard** | Dropping the variation; canonical state unchanged |
60
61 ---
62
63 ## Execution Mode Policy
64
65 | User Intent | Mode | Result |
66 |---|---|---|
67 | Composing / generating | `variation` | Produces a Variation for human review |
68 | Editing (add track, set tempo) | `apply` | Applied immediately, no review |
69 | Reasoning / chat only | `reasoning` | No state mutation |
70
71 The backend enforces execution mode. Frontends MUST NOT override it.
72
73 ---
74
75 ## Data Shapes
76
77 ### Variation (meta event)
78
79 ```json
80 {
81 "variationId": "...",
82 "intent": "add countermelody to verse",
83 "aiExplanation": "I added a countermelody in the upper register...",
84 "noteCounts": { "added": 12, "removed": 0, "modified": 3 }
85 }
86 ```
87
88 ### Phrase
89
90 ```json
91 {
92 "phraseId": "...",
93 "trackId": "...",
94 "regionId": "...",
95 "startBeat": 1.0,
96 "endBeat": 5.0,
97 "label": "Verse countermelody",
98 "noteChanges": [...],
99 "controllerChanges": [...]
100 }
101 ```
102
103 ### NoteChange
104
105 ```json
106 {
107 "noteId": "...",
108 "changeType": "added",
109 "before": null,
110 "after": {
111 "startBeat": 1.5,
112 "durationBeats": 0.5,
113 "pitch": 72,
114 "velocity": 80
115 }
116 }
117 ```
118
119 Rules:
120 - `added` → `before` MUST be `null`
121 - `removed` → `after` MUST be `null`
122 - `modified` → both `before` and `after` MUST be present
123
124 ---
125
126 ## SSE Streaming Contract
127
128 Events stream in this order (strictly):
129
130 ```
131 meta → phrase* → done
132 ```
133
134 | Event type | When sent |
135 |---|---|
136 | `meta` | First event; carries variation summary |
137 | `phrase` | One per phrase; may be many |
138 | `done` | Last event; signals review mode is active |
139
140 Event envelope:
141 ```json
142 {
143 "type": "phrase",
144 "sequence": 3,
145 "variationId": "...",
146 "projectId": "...",
147 "baseStateId": "...",
148 "timestampMs": 1234567890,
149 "payload": { ...phrase... }
150 }
151 ```
152
153 `sequence` is strictly increasing. `baseStateId` is the Muse snapshot ID the
154 variation was computed against.
155
156 ---
157
158 ## API Endpoints
159
160 | Method | Path | Purpose |
161 |---|---|---|
162 | `POST` | `/variation/propose` | Propose a new variation |
163 | `GET` | `/variation/stream` | SSE stream of meta + phrase events |
164 | `POST` | `/variation/commit` | Accept (all or partial phrases) |
165 | `POST` | `/variation/discard` | Discard without committing |
166 | `GET` | `/variation/{id}` | Poll status / reconnect |
167
168 ### Commit request
169
170 ```json
171 {
172 "variationId": "...",
173 "acceptedPhraseIds": ["phrase-1", "phrase-3"]
174 }
175 ```
176
177 Partial acceptance is supported: only listed phrases are committed.
178
179 ---
180
181 ## Audition Modes
182
183 | Mode | What plays |
184 |---|---|
185 | Original | Canonical state only |
186 | Variation | Proposed state (with changes applied) |
187 | Delta Solo | Only the added/modified notes |
188
189 ---
190
191 ## Safety Rules
192
193 1. Review mode is isolated — destructive edits are blocked during review.
194 2. Canonical state MUST NOT mutate during proposal.
195 3. Commit is a single undo boundary: `muse revert` can undo the entire commit.
196 4. If the stream fails mid-phrase, keep received phrases and allow the user to
197 discard or commit what arrived.
198
199 ---
200
201 ## Relationship to Muse VCS
202
203 A committed Variation becomes a standard `muse commit` in the DAG:
204
205 ```bash
206 muse log --oneline
207 ```
208
209 ```
210 a1b2c3d4 (HEAD -> main) Add countermelody to verse
211 ```
212
213 From Muse's perspective, a committed Variation is indistinguishable from any
214 other commit. The Variation UX is a midi-domain layer on top of the standard
215 VCS commit cycle.