gabriel / muse public
muse-variation-spec.md markdown
215 lines 5.3 KB
Raw
sha256:84df9126d09aeec0b8f1b908f0b06c10913feec28f3514b382efb1ba6d619385 refactor: rename StructuredMergePlugin to AddressedMergePlu… Sonnet 4.6 minor ⚠ breaking 24 days ago

Muse Variation Spec — Music Domain Reference

Scope: This spec describes the Variation UX pattern as implemented for the MIDI domain. It is not part of the core Muse VCS engine.

For the domain-agnostic VCS protocol, see muse-protocol.md. For a discussion of how "Variation" might generalize across domains, see muse-domain-concepts.md.


What a Variation Is

A Variation is a proposed musical change set awaiting human review before being committed to the Muse DAG. It is the MIDI plugin's implementation of the propose → review → commit pattern.

VCS equivalent mapping:
  Variation  = A staged diff
  Phrase     = A hunk (contiguous group of changes within a region)
  Accept     = muse commit
  Discard    = Discard working-tree changes (no commit)
  Undo       = muse revert

The defining characteristic: a Variation is heard before committed — the musician auditions the proposed change in the DAW's playback engine and then decides whether to accept or discard. This is layered on top of the VCS DAG, not part of it.


Lifecycle

1. Variation Proposed   — AI or user creates a proposed change set
2. Stream               — phrases stream to the DAW in SSE events
3. Review Mode Active   — DAW shows proposed state alongside canonical state
4. Accept (or partial)  — accepted phrases are committed; discarded phrases are dropped
5. Canonical state updates — only after commit

Canonical state MUST NOT change during review. The proposed state is always ephemeral.


Terminology

Term Definition
Variation A proposed set of musical changes, organized as phrases
Phrase A bounded group of note/controller changes within one region
NoteChange An atomic note delta: added, removed, or modified
Canonical State The actual committed project state in the Muse DAG
Proposed State The ephemeral preview state during variation review
Accept Committing accepted phrases to the Muse DAG
Discard Dropping the variation; canonical state unchanged

Execution Mode Policy

User Intent Mode Result
Composing / generating variation Produces a Variation for human review
Editing (add track, set tempo) apply Applied immediately, no review
Reasoning / chat only reasoning No state mutation

The backend enforces execution mode. Frontends MUST NOT override it.


Data Shapes

Variation (meta event)

{
  "variationId": "...",
  "intent": "add countermelody to verse",
  "aiExplanation": "I added a countermelody in the upper register...",
  "noteCounts": { "added": 12, "removed": 0, "modified": 3 }
}

Phrase

{
  "phraseId": "...",
  "trackId": "...",
  "regionId": "...",
  "startBeat": 1.0,
  "endBeat": 5.0,
  "label": "Verse countermelody",
  "noteChanges": [...],
  "controllerChanges": [...]
}

NoteChange

{
  "noteId": "...",
  "changeType": "added",
  "before": null,
  "after": {
    "startBeat": 1.5,
    "durationBeats": 0.5,
    "pitch": 72,
    "velocity": 80
  }
}

Rules:

  • addedbefore MUST be null
  • removedafter MUST be null
  • modified → both before and after MUST be present

SSE Streaming Contract

Events stream in this order (strictly):

meta → phrase* → done
Event type When sent
meta First event; carries variation summary
phrase One per phrase; may be many
done Last event; signals review mode is active

Event envelope:

{
  "type": "phrase",
  "sequence": 3,
  "variationId": "...",
  "projectId": "...",
  "baseStateId": "...",
  "timestampMs": 1234567890,
  "payload": { ...phrase... }
}

sequence is strictly increasing. baseStateId is the Muse snapshot ID the variation was computed against.


API Endpoints

Method Path Purpose
POST /variation/propose Propose a new variation
GET /variation/stream SSE stream of meta + phrase events
POST /variation/commit Accept (all or partial phrases)
POST /variation/discard Discard without committing
GET /variation/{id} Poll status / reconnect

Commit request

{
  "variationId": "...",
  "acceptedPhraseIds": ["phrase-1", "phrase-3"]
}

Partial acceptance is supported: only listed phrases are committed.


Audition Modes

Mode What plays
Original Canonical state only
Variation Proposed state (with changes applied)
Delta Solo Only the added/modified notes

Safety Rules

  1. Review mode is isolated — destructive edits are blocked during review.
  2. Canonical state MUST NOT mutate during proposal.
  3. Commit is a single undo boundary: muse revert can undo the entire commit.
  4. If the stream fails mid-phrase, keep received phrases and allow the user to discard or commit what arrived.

Relationship to Muse VCS

A committed Variation becomes a standard muse commit in the DAG:

muse log --oneline
a1b2c3d4 (HEAD -> main) Add countermelody to verse

From Muse's perspective, a committed Variation is indistinguishable from any other commit. The Variation UX is a midi-domain layer on top of the standard VCS commit cycle.

File History 1 commit
sha256:84df9126d09aeec0b8f1b908f0b06c10913feec28f3514b382efb1ba6d619385 refactor: rename StructuredMergePlugin to AddressedMergePlu… Sonnet 4.6 minor 24 days ago