gabriel / muse public
WHITE_PAPER.md markdown
1065 lines 68.8 KB
fe21d86c docs: add WHITE_PAPER.md — flat-projection impossibility theorem Gabriel Cardona <gabriel@tellurstori.com> 2d ago
1 # The Flat-Projection Impossibility Theorem for Multidimensional State Version Control
2
3 **A Technical White Paper**
4
5 *Gabriel · Muse Project · March 2026*
6
7 ---
8
9 > *"The question is not whether you can serialize multidimensional state to bytes —
10 > you can always do that. The question is whether the bytes remember the
11 > dimensions. They don't."*
12
13 ---
14
15 ## Abstract
16
17 Modern version control systems (VCS) treat all versioned artifacts as opaque byte sequences, detecting changes through line-level longest-common-subsequence (LCS) diffs and resolving conflicts through text-merge heuristics. This works acceptably for source code, whose primary structure is a linear token sequence with line-bounded locality. It fails, and fails categorically, for every other class of multidimensional state: musical scores, genomic sequences, scientific simulations, 3D scene graphs, and animation keyframes — none of which are text and none of which can be losslessly projected to a flat byte sequence that preserves the semantic independence structure of their native dimensions.
18
19 This paper makes five formal arguments that flat-byte projection is insufficient for multidimensional state version control, then grounds each argument in the Muse implementation — a domain-agnostic VCS built to manage exactly this class of artifact. We demonstrate that:
20
21 1. **Byte-level equality is not domain equality** — two semantically equivalent states may have different byte representations, and two semantically different states may differ by only a handful of bytes with no structural signal of which bytes matter.
22 2. **No flat projection preserves dimensional independence** — the 21-dimensional independence structure of a MIDI file cannot survive any encoding into a byte sequence, because independence is a property of the parsing interpretation, not the bits.
23 3. **Merge correctness requires causal awareness** — a tempo change in bar 4 shifts the musical meaning of every subsequent tick, creating a causal dependency that no byte-level diff can detect or honor.
24 4. **Entity identity requires domain knowledge** — the fact that the note C4 at beat 3 with velocity 100 is the *same entity* as the note C4 at beat 3 with velocity 80 (after an expression edit) is invisible at the byte level and requires domain parsing to establish.
25 5. **Semantic versioning is a property of structure, not bytes** — whether a change is a breaking API change, a backward-compatible addition, or a pure refactor is derivable only from the domain's symbol structure, not from counting added and removed bytes.
26
27 The Muse implementation, across 419 commits and 691 passing tests, provides a working existence proof of the alternative: a plugin-based VCS in which each domain contributes its own diff, merge, and schema functions, and the core engine remains domain-agnostic. The result is a system where two collaborators can simultaneously edit different dimensions of the same MIDI file — sustain pedal on one branch, note velocities on the other — and merge without any conflict, because the 21 dimensions of MIDI state are declared and their independence is machine-verifiable.
28
29 ---
30
31 ## Table of Contents
32
33 1. [Introduction: The Version Control Abstraction](#1-introduction)
34 2. [The Flat-Projection Thesis and Its Appeal](#2-the-flat-projection-thesis)
35 3. [Argument I: Byte-Level Equality Loses Semantic Identity](#3-argument-i)
36 4. [Argument II: No Flat Projection Preserves Dimensional Independence](#4-argument-ii)
37 5. [Argument III: Merge Requires Causal Awareness](#5-argument-iii)
38 6. [Argument IV: Entity Identity Cannot Be Recovered from Bytes](#6-argument-iv)
39 7. [Argument V: Semantic Versioning Is a Structural Property](#7-argument-v)
40 8. [The Muse Architecture: A Constructive Counter-Proof](#8-the-muse-architecture)
41 9. [The MuseDomainPlugin Protocol: Six Methods That Cannot Be Bytes](#9-the-musedomain-plugin-protocol)
42 10. [The Typed Operation Algebra: The Language Bytes Don't Speak](#10-the-typed-operation-algebra)
43 11. [The Merge Hierarchy: From File to Dimension to Operation](#11-the-merge-hierarchy)
44 12. [CRDT Convergence: When Three-Way Merge Is the Wrong Model](#12-crdt-convergence)
45 13. [Cross-Domain Generalization: Evidence Beyond Music](#13-cross-domain-generalization)
46 14. [Related Work](#14-related-work)
47 15. [Discussion and Implications](#15-discussion-and-implications)
48 16. [Conclusion](#16-conclusion)
49 17. [Appendix A: The 21 Dimensions of MIDI State](#appendix-a)
50 18. [Appendix B: The Operation Commutativity Table](#appendix-b)
51 19. [Appendix C: Formal Definitions](#appendix-c)
52
53 ---
54
55 ## 1. Introduction
56
57 Version control is one of the oldest and most consequential abstractions in software engineering. Since `diff` and `patch` were introduced in the early UNIX era, the working model has been consistent: a versioned artifact is a file; a file is a sequence of bytes; a change is the transformation from one byte sequence to another; and a conflict occurs when two independent changes touch overlapping byte ranges.
58
59 This model has been extraordinarily successful for its primary intended domain: source code. Source code is text. Text is a sequence of lines. Lines have locality — a change to line 47 rarely affects the semantics of line 3. The LCS-based diff algorithm finds minimum edit scripts with good human interpretability, and three-way merge handles the common case of non-overlapping concurrent edits correctly.
60
61 But version control is needed in many domains beyond source code. A molecular biology team maintaining a reference genome needs to track edits to nucleotide sequences, gene annotations, and structural variants — three fundamentally different data types in a single artifact. A game studio needs to version 3D scene graphs, animation rigs, material libraries, and physics parameters — each with its own identity model and merge semantics. A music production team needs to track note events, control change automation, tempo maps, and time signatures — dimensions that are sometimes independent and sometimes causally linked in ways that the file format does not expose.
62
63 The reflex response to all of these is: *"Just commit the file. Git can handle it."* After all, any artifact can be serialized to bytes, and bytes can be stored in a Git object. A MIDI file is bytes. A genome FASTA file is bytes. A Blender `.blend` file is bytes. What is the problem?
64
65 The problem is not storage. The problem is the *operations* that version control must support:
66
67 - **Diff**: what changed between two versions?
68 - **Blame**: which commit introduced this element?
69 - **Merge**: how do two independent edit streams combine?
70 - **Cherry-pick**: can this specific change from branch A be applied to branch B?
71 - **Revert**: can this specific change be undone without disturbing others?
72
73 Each of these operations, for multidimensional state, requires semantic understanding that is irretrievably absent from a byte sequence. This paper proves why.
74
75 ---
76
77 ## 2. The Flat-Projection Thesis
78
79 The flat-projection thesis is the claim that any multidimensional artifact can be adequately version-controlled by:
80
81 1. Serializing the artifact to a canonical byte sequence.
82 2. Applying standard byte-level or line-level diff algorithms.
83 3. Applying standard three-way merge on the resulting diffs.
84
85 The thesis has an obvious technical truth at its core: *any* finite data structure can be serialized to bytes. This is guaranteed by computability theory. A MIDI file, a genome, a scene graph — all are computable structures and therefore byte-serializable. The question is not whether the serialization exists. The question is whether the serialization *preserves the properties needed for version control operations to be meaningful*.
86
87 We will show that it does not, systematically and for principled reasons.
88
89 ### 2.1 The Canonical Form Requirement
90
91 The first crack in the thesis appears immediately: for byte-level equality to mean semantic equality, the serialization must be **canonical** — a unique, deterministic byte representation of each logical state.
92
93 For text files, this is approximately true (given a fixed encoding). For binary formats, it is typically false. The MIDI specification, for example, permits:
94
95 - Events at the same tick position in any order (they are simultaneous from the sequencer's perspective).
96 - Running status compression (omitting status bytes when the channel and type are unchanged), which may be applied or omitted by any writer.
97 - Variable-length encoding of delta-times, with multiple valid bit patterns for the same value (leading zero bytes).
98 - Track chunk metadata (track names, copyright strings) that are optional and format-specific.
99
100 Two MIDI files that are semantically identical — they would produce the same audio output through any MIDI-compliant synthesizer — may have entirely different byte representations. Two MIDI files that differ semantically by a single note insertion may share 99.98% of their bytes, with no structural signal about where the musically meaningful change occurred.
101
102 ```
103 $ diff --stat before.mid after.mid
104 Binary files before.mid and after.mid differ
105 ```
106
107 Git's response to a binary diff. There is no actionable information here.
108
109 ### 2.2 The Subset Representation Problem
110
111 Suppose we solve the canonicalization problem — we define a canonical serialization that produces a unique byte sequence for each logical state. Does this fix the flat-projection model?
112
113 No. The problem is the **subset representation** problem: a byte diff computes which bytes changed, but not which *semantic elements* those bytes represent.
114
115 Consider a 50 KB MIDI file representing a full orchestral arrangement. A one-note velocity change modifies approximately 1 byte (the velocity field of a single MIDI note-on event). A tempo change modifies 3 bytes (the BPM value in a `set_tempo` meta-event). A new 16th-note added at bar 7, beat 3 modifies approximately 8 bytes.
116
117 The byte counts are similar. The semantic significance is radically different. The tempo change shifts the musical meaning of every subsequent event. The note insertion changes the harmonic and rhythmic texture of a specific measure. The velocity change adjusts expression on a single note. A byte diff represents all three as "some bytes changed somewhere in the file" and treats them identically.
118
119 ### 2.3 The Independence Destruction Problem
120
121 The deepest failure of the flat-projection thesis is what we call the **independence destruction problem**. A multidimensional artifact has a natural structure of partially-independent sub-dimensions. In a MIDI file, the note events on the melody track are independent of the sustain pedal automation — an edit to one does not, in general, affect the other. In a genome, an edit to chromosome 3 is independent of an edit to chromosome 7.
122
123 This independence is a *semantic property*, not a syntactic one. When the artifact is serialized to bytes, the independence structure is lost. The bytes for melody notes and sustain pedal automation are interleaved in the file, with no representation of which byte regions are independent. A byte-level conflict detection system sees "both branches modified bytes in this file" and declares a conflict — even when the actual changes were to completely independent dimensions.
124
125 Muse's implementation puts a precise number on this loss: in the MIDI domain, 18 of 21 semantic dimensions are fully independent (`independent_merge: True`). A naive byte-diff system treats all 21 as one dimension — the file — and produces a conflict whenever any two of those 21 are touched concurrently on different branches.
126
127 ---
128
129 ## 3. Argument I: Byte-Level Equality Loses Semantic Identity
130
131 **Claim**: The equality relation induced by byte-level comparison does not correspond to the domain equality relation for any non-trivial multidimensional artifact.
132
133 ### 3.1 The Formal Setup
134
135 Let $\mathcal{S}$ be the set of valid semantic states of a domain (e.g., all valid MIDI compositions). Let $\text{ser}: \mathcal{S} \to \{0,1\}^*$ be a serialization function. Let $\text{des}: \{0,1\}^* \to \mathcal{S} \cup \{\perp\}$ be a deserialization function.
136
137 For flat-projection to be sound, we require:
138
139 $$\forall s_1, s_2 \in \mathcal{S}: s_1 =_{\mathcal{S}} s_2 \iff \text{ser}(s_1) =_{\text{bytes}} \text{ser}(s_2)$$
140
141 This holds only if $\text{ser}$ is **injective** and **canonical** — one state maps to one byte sequence.
142
143 ### 3.2 MIDI: Non-Canonicality in Practice
144
145 The MIDI 1.0 specification (MIDI Manufacturers Association, 1983) does not mandate a canonical event ordering within a tick. The following two byte sequences both represent a valid C major chord (C4, E4, G4) at tick 0 on channel 1:
146
147 ```
148 Sequence A: 00 90 3C 64 00 90 40 64 00 90 43 64 (C, E, G)
149 Sequence B: 00 90 43 64 00 90 3C 64 00 90 40 64 (G, C, E)
150 ```
151
152 `00 90 3C 64` = delta_time=0, note_on, channel=1, pitch=60 (C4), velocity=100.
153
154 These two sequences have different bytes. They represent the same musical event. Any byte-level diff between them reports a change. Any hash-based equality check reports them as different. But `$s_1 =_{\mathcal{S}} s_2$` — they are the same musical state.
155
156 Conversely, the following two sequences have similar bytes but represent different musical events:
157
158 ```
159 Before: 00 90 3C 64 ... (C4, velocity=100)
160 After: 00 90 3C 50 ... (C4, velocity=80)
161 ```
162
163 Eight bytes differ. The change is semantically significant: an expression change that a performer made deliberately. But the byte diff reports it identically to any other 1-byte change anywhere in the file.
164
165 ### 3.3 The Content-ID Solution
166
167 Muse's object store resolves the storage problem with content-addressed SHA-256 hashing: each blob is stored once, indexed by its hash. But this does not solve the equality problem — it makes it worse. Two semantically identical MIDI files with different event orderings will have different SHA-256 hashes and be stored as different objects, with no connection established between them.
168
169 The MIDI plugin resolves this by defining a domain equality relation on the **parsed representation**, not the bytes:
170
171 ```python
172 class NoteKey(TypedDict):
173 pitch: int # MIDI pitch 0–127
174 velocity: int # attack velocity 0–127
175 start_tick: int # absolute tick position (delta-time resolved)
176 duration_ticks: int # note duration in ticks
177 channel: int # MIDI channel 0–15
178 ```
179
180 Two notes are equal iff all five fields match. The content ID for a note is:
181
182 ```python
183 sha256(f"pitch:{pitch}\nvelocity:{velocity}\nstart_tick:{start_tick}\n"
184 f"duration:{duration_ticks}\nchannel:{channel}")
185 ```
186
187 This hash is **portable** across different byte serializations of the same note. It is a content ID in semantic space, not byte space. A canonical-form MIDI and a running-status-compressed MIDI of the same composition produce the same note content IDs.
188
189 **Conclusion**: The equality relation required for meaningful version control must be defined on the parsed domain model, not on the raw byte sequence. There is no universal transformation that recovers domain equality from byte equality for binary structured formats.
190
191 ---
192
193 ## 4. Argument II: No Flat Projection Preserves Dimensional Independence
194
195 **Claim**: For any multidimensional artifact with $n \geq 2$ independent dimensions, no byte serialization preserves the independence structure in a form recoverable by byte-level diff algorithms.
196
197 ### 4.1 Independence as a Semantic Property
198
199 Define a **dimensional decomposition** of a state space $\mathcal{S}$ as a set of projections $\{\pi_1, \pi_2, \ldots, \pi_n\}$ such that:
200
201 $$s \cong (\pi_1(s), \pi_2(s), \ldots, \pi_n(s))$$
202
203 Dimensions $\pi_i$ and $\pi_j$ are **independent** if edits to $\pi_i(s)$ and $\pi_j(s)$ can be merged without knowledge of the other:
204
205 $$\forall s, s', s'': \text{merge}(\pi_i(s), \pi_i(s'), \pi_i(s'')) \text{ is defined independently of } \pi_j$$
206
207 ### 4.2 The Interleaving Problem
208
209 In a MIDI file, dimension data is **interleaved** in the byte stream by temporal position. A MIDI file at tick 4800 might contain (in order): a note-on event (dimension: notes), a control change for CC7 volume (dimension: cc_volume), a control change for CC64 sustain (dimension: cc_sustain), a pitch bend event (dimension: pitch_bend).
210
211 These four events are from four independent dimensions, but they appear contiguously in the byte stream. There is no byte-level boundary between dimensions. A byte-level diff algorithm that computes the LCS of two byte streams will see:
212
213 - If the file on branch A has the same events but with a new sustain event at tick 4896, and the file on branch B has the same events but with a new CC7 volume automation event at tick 4800 — the byte diff shows both files changed in the same region (around tick 4800).
214 - A three-way byte merge declares this a conflict.
215 - The correct answer is: no conflict. The changes are in independent dimensions.
216
217 The Muse MIDI plugin recovers independence by **parsing first, then differencing**:
218
219 ```python
220 def extract_dimensions(events: list[MidiEvent]) -> MidiDimensions:
221 slices: dict[str, DimSlice] = {dim: DimSlice(events=[], sha256="")
222 for dim in ALL_DIMENSIONS}
223 for event in events:
224 dim = classify_event(event) # domain knowledge required
225 slices[dim].events.append(event)
226 for dim, slice_ in slices.items():
227 slice_.sha256 = sha256_of_events(slice_.events)
228 return MidiDimensions(slices=slices)
229 ```
230
231 The `classify_event` function encodes the MIDI specification's event taxonomy:
232
233 - `note_on` / `note_off` → dimension `notes`
234 - CC 1 (modulation wheel) → dimension `cc_modulation`
235 - CC 7 (channel volume) → dimension `cc_volume`
236 - CC 10 (pan) → dimension `cc_pan`
237 - CC 64 (sustain pedal) → dimension `cc_sustain`
238 - `set_tempo` meta-event → dimension `tempo_map`
239 - `time_signature` meta-event → dimension `time_signatures`
240
241 This classification requires **domain knowledge of the MIDI CC assignment table**. There is no algorithmic way to derive it from the bytes. CC 7 and CC 64 are "both control change events" at the byte level — they have the same status byte (`0xBn`), differing only in the controller number byte. A byte-diff algorithm cannot distinguish them as belonging to different independent dimensions.
242
243 ### 4.3 The Impossibility of Byte-Level Independence Recovery
244
245 **Theorem**: For a binary structured format with $n$ semantically independent dimensions interleaved in the byte stream, no purely syntactic byte transformation can recover the independence structure with zero false positives (spurious conflicts) and zero false negatives (missed real conflicts).
246
247 **Proof sketch**: Consider a MIDI file $F$ with events from dimensions $D_1$ and $D_2$ interleaved at the byte level. Construct two edits:
248
249 - Edit $A$: adds a $D_1$ event at tick $T$.
250 - Edit $B$: adds a $D_2$ event at tick $T$.
251
252 After serialization, both edits insert bytes at the same position in the file (since events at the same tick are serialized contiguously). Any byte-level conflict detection algorithm based on position overlap will declare a conflict. But the edits are to independent dimensions — no conflict should be declared.
253
254 To avoid the false positive, the algorithm must know that the inserted bytes belong to different semantic dimensions. This requires parsing the format — applying domain knowledge. No purely syntactic transformation of the bytes can provide this information, because the dimension membership of a byte region is determined by its semantic content (the status byte + controller number + event type), not its position.
255
256 The argument is symmetric for false negatives: two edits that change the same dimension at the same position should always conflict, but syntactic proximity is neither necessary nor sufficient for this to hold in interleaved binary formats. $\square$
257
258 ### 4.4 Quantitative Impact
259
260 In the Muse MIDI implementation, 18 of 21 dimensions are marked `independent_merge: True`. A naive file-level conflict detection system (like Git) treats these 18 dimensions as a single conflict region whenever any two are touched concurrently. The false positive rate approaches:
261
262 $$P(\text{false conflict}) = 1 - P(\text{both branches touch only one shared dimension})$$
263
264 For a development team where each commit is equally likely to touch any of the 18 independent dimensions, the probability that two concurrent commits avoid a spurious conflict is $1/18 \approx 5.6\%$. The remaining $94.4\%$ of concurrent edits will be incorrectly flagged as conflicts.
265
266 ---
267
268 ## 5. Argument III: Merge Requires Causal Awareness
269
270 **Claim**: Correct merge of multidimensional state requires awareness of **causal dependencies** between dimensions that are invisible at the byte level and derivable only from domain semantics.
271
272 ### 5.1 The Temporal Dependency Problem in MIDI
273
274 A MIDI file's temporal model uses **delta-time encoding**: each event is timestamped with the number of ticks since the previous event, not since the beginning of the track. The conversion from ticks to real time (seconds or beats) requires the tempo map — a sequence of `set_tempo` meta-events that specify beats-per-minute at specific tick positions.
275
276 This creates a **causal dependency** between the `tempo_map` dimension and all other dimensions:
277
278 $$\text{musical\_time}(\text{event}) = f(\text{event.tick}, \text{tempo\_map})$$
279
280 When Alice changes a `set_tempo` event at tick 1920 (bar 4) from 120 BPM to 132 BPM, and Bob concurrently adds a note at tick 5120, the **musical meaning** of Bob's note changes:
281
282 - At 120 BPM: tick 5120 at 480 ticks/beat = beat 10.67 = bar 3, beat 2.67 (in post-bar-4 music)
283 - At 132 BPM: tick 5120 at 480 ticks/beat shifts because the real-time duration of each beat shortens
284
285 The byte-level diff of Bob's edit is identical regardless of Alice's tempo change. The bytes Bob added are the same bytes either way. But the musical meaning of Bob's commit changes depending on whether Alice's tempo change was already in the base.
286
287 This is a **causal dependency** in the version history DAG, not a syntactic conflict. No byte-level diff or merge algorithm can detect it, because:
288
289 1. Bob's new bytes look the same regardless of Alice's tempo change.
290 2. The dependency is cross-dimensional: the `notes` dimension depends on the `tempo_map` dimension.
291 3. The dependency is **temporal and positional**: only notes *after* Alice's tempo change at tick 1920 are affected.
292
293 ### 5.2 The Muse Response: Non-Independent Dimensions
294
295 Muse explicitly models this causal dependency by marking `tempo_map` and `time_signatures` as **non-independent**:
296
297 ```python
298 DimensionSpec(
299 name="tempo_map",
300 description="set_tempo meta-events — BPM changes throughout the file",
301 schema=SequenceSchema(kind="sequence", element="tempo_event"),
302 independent_merge=False, # ← causal dependency marker
303 ),
304 DimensionSpec(
305 name="time_signatures",
306 description="time_signature meta-events — meter changes",
307 schema=SequenceSchema(kind="sequence", element="time_sig_event"),
308 independent_merge=False, # ← causal dependency marker
309 ),
310 ```
311
312 When both branches touch a non-independent dimension, the merge engine does not attempt auto-resolution — it requires human intervention. The docstring in `midi_merge.py` explains the architectural decision:
313
314 > *"Tempo and time signature changes shift the musical meaning of every subsequent tick. Two branches that independently modify tempo cannot be merged automatically — the merge would produce a file where the musical position of every note after the tempo change is ambiguous."*
315
316 A byte-level merge would cheerfully combine the two byte streams, producing a MIDI file whose musical meaning is undefined (and likely unintended) by either author.
317
318 ### 5.3 Causal Dependencies in Other Domains
319
320 The tempo-map dependency is not a MIDI quirk — it is an instance of a general class of **global parameter dependencies** that appear in every multidimensional state domain:
321
322 | Domain | Global Parameter | Dependent Dimensions |
323 |--------|------------------|---------------------|
324 | Music (MIDI) | Tempo map | All note positions, all CC automation curves |
325 | Music (MIDI) | Time signatures | Bar/beat interpretations, quantization grid |
326 | Genome | Reference sequence | All annotation positions (gene start/end coordinates) |
327 | 3D scene | Coordinate system / scale | All mesh positions, light targets, camera frustums |
328 | Animation | Playback frame rate | All keyframe positions |
329 | Climate simulation | Timestep / grid resolution | All spatial field arrays |
330 | Source code | Module dependency graph | All symbol visibility, import resolution |
331
332 In each domain, a change to the global parameter dimension shifts the semantic meaning of every element in dependent dimensions. No byte-level merge can detect this, because the dependency is **semantic, not syntactic**.
333
334 ---
335
336 ## 6. Argument IV: Entity Identity Cannot Be Recovered from Bytes
337
338 **Claim**: Meaningful version control requires **stable entity identity** — the ability to track a specific domain object across mutations. Byte sequences do not support entity identity because an object's byte representation changes under any mutation.
339
340 ### 6.1 The Diffing Identity Crisis
341
342 Consider the standard formulation of the diff problem: given byte sequences $A$ and $B$, find the minimum edit script that transforms $A$ into $B$. For text, this is the LCS problem, solved by Myers' O(nd) algorithm.
343
344 For structured data, the diff problem requires a **domain identity function** — a function $\text{id}: \text{element} \to \text{identifier}$ that is stable across mutations. Without it, the minimum edit script for any mutated element is always `delete(old) + insert(new)` — entity lineage is lost.
345
346 In MIDI, consider two successive versions of a track:
347
348 ```
349 Version 1: C4 vel=80 @beat=1.00 dur=0.50
350 E4 vel=80 @beat=1.50 dur=0.50
351 G4 vel=80 @beat=2.00 dur=0.50
352
353 Version 2: C4 vel=100 @beat=1.00 dur=0.50 ← velocity changed
354 E4 vel=80 @beat=1.50 dur=0.50
355 G4 vel=80 @beat=2.00 dur=0.50
356 ```
357
358 A byte-level diff (operating on the MIDI binary) sees: some bytes changed at the position of the first note's velocity field. It can report "bytes changed at offset 14–15." It cannot say "the velocity of note C4 at beat 1.00 changed from 80 to 100."
359
360 A note-level LCS diff (operating on the parsed NoteKey representation) sees: `DeleteOp(C4 vel=80 @beat=1.00)` + `InsertOp(C4 vel=100 @beat=1.00)`. This correctly identifies the change as a velocity mutation on a specific note, but it loses entity identity — it treats the change as a delete-and-reinsert.
361
362 Muse's `MutateOp` represents the semantically correct view:
363
364 ```python
365 MutateOp(
366 address="note:uuid-C4@beat1.00",
367 entity_id="a3f8-9b12-...", # stable UUID4 across all mutations
368 old_content_id="sha256:abc...", # hash of (C4, vel=80, tick=480, ...)
369 new_content_id="sha256:def...", # hash of (C4, vel=100, tick=480, ...)
370 fields={
371 "velocity": FieldMutation(old="80", new="100")
372 },
373 old_summary="C4 vel=80 @beat=1.00 dur=0.50",
374 new_summary="C4 vel=100 @beat=1.00 dur=0.50",
375 )
376 ```
377
378 This representation:
379 1. Preserves entity identity (the same `entity_id` across all velocity changes to this note)
380 2. Identifies exactly which field changed (velocity) without full content replacement
381 3. Enables `muse note-blame` — attributing the current velocity to the commit that last mutated it
382 4. Enables detecting that two concurrent edits both changed the velocity of the same note (a real conflict) versus one changed velocity and one changed the note's timing (independent changes to the same entity)
383
384 ### 6.2 The Three-Tier Entity Matching Algorithm
385
386 The entity resolution algorithm in Muse's MIDI plugin uses three tiers of matching, each requiring domain knowledge:
387
388 **Tier 1: Exact match** — same pitch, velocity, start_tick, duration, channel. No mutation.
389
390 **Tier 2: Fuzzy match** — same pitch and channel (±0), with velocity within ±20 and start_tick within ±10 ticks. This captures human expression: a performer adjusted the velocity of a specific note without changing its identity.
391
392 **Tier 3: New entity** — no prior match found. A genuinely new note was inserted.
393
394 The velocity tolerance of ±20 (±16% of the 0–127 range) and timing tolerance of ±10 ticks require **domain knowledge**:
395 - ±20 velocity is audible but within the range of natural performance variation.
396 - ±10 ticks at 480 PPQN at 120 BPM = ±10.4 ms — within MIDI clock resolution.
397
398 A byte-level diff has no mechanism to express these tolerances. A byte diff sees "8 bytes changed" regardless of whether the velocity moved by 1 or 127.
399
400 ### 6.3 The Lineage Tracking Capability
401
402 Entity identity enables a class of queries that is structurally impossible with byte-level VCS:
403
404 ```
405 $ muse note-blame tracks/lead.mid 60 480
406 note C4 @tick=480: commit a3f8... "adjusted expression in bar 2" by Alice (2024-03-15)
407 ```
408
409 This answers: "who last modified the velocity/timing/channel of the note C4 at tick 480, across the entire commit history?" Git `blame` can answer this question for lines of text because text lines have natural identity (their content). MIDI notes have no byte-level identity — their bytes are not at a fixed offset, the offset changes whenever a preceding event is added or removed.
410
411 The `muse note-blame` command requires:
412 1. Parsing every ancestor commit's MIDI content
413 2. Resolving the entity registry to track stable `entity_id` values
414 3. Walking the commit DAG to find the last commit where the target entity's content changed
415
416 None of these steps operate on bytes. All operate on the parsed domain model.
417
418 ---
419
420 ## 7. Argument V: Semantic Versioning Is a Structural Property
421
422 **Claim**: For artifacts with public interfaces (source code, APIs, plugin contracts), semantic version impact is a property of the **symbol structure** of the change, not the byte count. No byte-level transformation can reliably infer `major`, `minor`, or `patch` bump without understanding the domain's structural rules.
423
424 ### 7.1 The Semver Inference Problem
425
426 The semantic version specification (SemVer 2.0.0, Preston-Werner, 2013) defines:
427 - **MAJOR**: incompatible API change
428 - **MINOR**: backward-compatible new functionality
429 - **PATCH**: backward-compatible bug fixes
430
431 For source code, these map to structural change categories:
432 - MAJOR: public function/class deleted, public function signature changed
433 - MINOR: public function/class added
434 - PATCH: public function body changed, private function changed, reformatted
435
436 None of these categories are computable from a byte diff. Consider:
437
438 ```
439 Byte diff: 47 lines added, 23 lines removed in src/processor.py
440 ```
441
442 Is this MAJOR, MINOR, or PATCH? Impossible to determine without parsing the source. The same byte statistics could represent: renaming a public function (MAJOR), adding a new public method to a class (MINOR), refactoring a private method (PATCH), or reformatting the entire file (none).
443
444 ### 7.2 The Muse Implementation
445
446 Muse's code domain plugin uses tree-sitter to parse 15 programming languages into ASTs, then applies `symbol_diff.py` to produce `StructuredDelta` entries with explicit semver inference:
447
448 ```python
449 def infer_sem_ver_bump(ops: list[DomainOp]) -> Literal["major", "minor", "patch", "none"]:
450 bump = "none"
451 for op in ops:
452 if isinstance(op, DeleteOp) and op["address"].startswith("public:"):
453 return "major" # public symbol deletion — immediate major
454 if isinstance(op, ReplaceOp) and op["address"].startswith("public:"):
455 if _signature_changed(op):
456 return "major" # public signature changed — major
457 bump = "patch" # body-only change
458 if isinstance(op, InsertOp) and op["address"].startswith("public:"):
459 bump = max_bump(bump, "minor") # new public symbol
460 return bump
461 ```
462
463 The `_signature_changed` function compares AST node types for parameter lists and return types — a structural comparison at the AST level. No byte count, no line count, no diff statistics.
464
465 This capability is stored in the `CommitDict` format:
466
467 ```python
468 class CommitDict(TypedDict, total=False):
469 sem_ver_bump: Literal["major", "minor", "patch", "none"]
470 breaking_changes: list[str] # human-readable breaking change descriptions
471 ```
472
473 A `git log --format="%H %s"` cannot provide this. A `muse log --format=semver` can, because every commit carries machine-inferred semver impact derived from the typed operation algebra.
474
475 ---
476
477 ## 8. The Muse Architecture: A Constructive Counter-Proof
478
479 The five arguments above establish the impossibility of the flat-projection thesis by construction of counterexamples. Muse is the constructive counter-proof: a working system that implements correct version control for multidimensional state.
480
481 ### 8.1 Design Principles
482
483 Three architectural principles distinguish Muse from byte-level VCS systems:
484
485 **Principle 1: Domain plugins own semantic interpretation.** The core engine is domain-agnostic. It never parses MIDI, reads ASTs, or interprets genomic formats. All semantic interpretation is delegated to domain plugins through the `MuseDomainPlugin` protocol.
486
487 **Principle 2: The diff output is typed operations, not bytes.** All change representation uses a typed operation algebra (`InsertOp`, `DeleteOp`, `MoveOp`, `ReplaceOp`, `MutateOp`, `PatchOp`) that carries semantic addressing, content IDs, and human-readable summaries. The byte representation of a change is never exposed at the diff layer.
488
489 **Principle 3: Merge is dimension-aware.** Conflict detection operates on the independence structure declared by the plugin's `schema()` method. Dimensions marked `independent_merge: True` are merged independently; dimensions marked `independent_merge: False` require human resolution if both branches touch them.
490
491 ### 8.2 The Plugin-Core Separation
492
493 The architectural boundary between the core engine and domain plugins is enforced at the import level:
494
495 ```
496 muse.core.* ← domain-agnostic, never imports from muse.plugins.*
497 muse.plugins.* ← domain-specific, implements MuseDomainPlugin
498 ```
499
500 This boundary is the formal statement that **the core version control operations do not require semantic domain knowledge**. The core engine provides: content-addressed object storage, commit DAG management, BFS LCA for merge base computation, and the typed operation algebra. Domain plugins provide: parsing, diffing, merging, and schema declaration.
501
502 The boundary is enforced by `mypy` with strict typing — any import of a plugin from a core module would be a type error.
503
504 ### 8.3 Evolution: From Music to Domain-Agnostic
505
506 The commit history of Muse reveals its research trajectory:
507
508 | Commit | Milestone |
509 |--------|-----------|
510 | `e1eb9cb` | "Initial extraction from tellurstori/maestro" — music-first origin |
511 | `7a6a60f` | "Introduce Muse v2 architecture: domain-agnostic VCS with plugin interface" |
512 | `98d6f7e` | "Remove all Maestro legacy code" — clean separation from music-specific predecessor |
513 | `1dd3b47` | "Typed delta algebra — replace DeltaManifest with StructuredDelta" — Phase 1 |
514 | `957ca8d` | "Domain schema declaration + diff algorithm library" — Phase 2 |
515 | `a1a57ce` | "Operation-level merge engine — OT-based auto-merge" — Phase 3 |
516 | `efd4bce` | "CRDT semantics for convergent multi-agent writes (691 tests green)" — Phase 4 |
517
518 The four-phase evolution represents a **layered theory of semantic richness**:
519 - Phase 1: What changed (typed operations)
520 - Phase 2: What structure the data has (domain schema)
521 - Phase 3: Can the changes commute (OT-based auto-merge)
522 - Phase 4: Can conflicts be eliminated mathematically (CRDT convergence)
523
524 ---
525
526 ## 9. The MuseDomainPlugin Protocol: Six Methods That Cannot Be Bytes
527
528 The `MuseDomainPlugin` protocol defines six methods. Each method's signature is a theorem about what information is required for correct version control of a domain — information that is unavailable from byte sequences alone.
529
530 ```python
531 @runtime_checkable
532 class MuseDomainPlugin(Protocol):
533 def snapshot(self, live_state: LiveState) -> StateSnapshot: ...
534 def diff(self, base: StateSnapshot, target: StateSnapshot,
535 *, repo_root: Path | None = None) -> StateDelta: ...
536 def merge(self, base: StateSnapshot, left: StateSnapshot, right: StateSnapshot,
537 *, repo_root: Path | None = None) -> MergeResult: ...
538 def drift(self, committed: StateSnapshot, live: LiveState) -> DriftReport: ...
539 def apply(self, delta: StateDelta, live_state: LiveState) -> LiveState: ...
540 def schema(self) -> DomainSchema: ...
541 ```
542
543 ### 9.1 `snapshot`: The Projection Decision
544
545 ```python
546 def snapshot(self, live_state: LiveState) -> StateSnapshot:
547 ```
548
549 `StateSnapshot = SnapshotManifest` — a `TypedDict` with `files: dict[str, str]` and `domain: str`.
550
551 The `files` dict maps workspace-relative paths to SHA-256 content digests. The key insight: **the granularity of change detection is determined by how the plugin slices the artifact into files**.
552
553 A music plugin that stores the entire MIDI file as a single `lead.mid → sha256` entry loses all sub-file structure. A more sophisticated plugin (like Muse's) could store dimension-sliced representations: `lead.mid/notes → sha256_of_notes`, `lead.mid/tempo_map → sha256_of_tempo_map`, enabling the manifest diff to detect dimension-level changes without parsing.
554
555 The plugin's `snapshot()` method is the *only* place where this architectural decision lives. The core engine never touches it.
556
557 ### 9.2 `diff`: The Semantic Delta
558
559 ```python
560 def diff(self, base: StateSnapshot, target: StateSnapshot,
561 *, repo_root: Path | None = None) -> StateDelta:
562 ```
563
564 `StateDelta = StructuredDelta` — contains `domain`, `ops: list[DomainOp]`, `summary`, `sem_ver_bump`, and `breaking_changes`.
565
566 The `ops` list is the formal statement that **version control change representation is a typed algebra**. The ops are not bytes, not lines, not hunks — they are domain-typed operations with semantic addresses.
567
568 A Git diff of the same change would produce: `@@ -14,7 +14,7 @@ ...`. The Muse diff produces:
569
570 ```python
571 MutateOp(
572 address="note:a3f8-...",
573 entity_id="a3f8-...",
574 fields={"velocity": FieldMutation(old="80", new="100")},
575 old_summary="C4 vel=80 @beat=1.00",
576 new_summary="C4 vel=100 @beat=1.00",
577 )
578 ```
579
580 Both represent the same change. Only the second is inspectable, queryable, cherry-pickable, and auditable without re-parsing.
581
582 ### 9.3 `merge`: The Dimension-Aware Combiner
583
584 ```python
585 def merge(self, base: StateSnapshot, left: StateSnapshot, right: StateSnapshot,
586 *, repo_root: Path | None = None) -> MergeResult:
587 ```
588
589 `MergeResult` carries: `merged`, `conflicts`, `applied_strategies`, `dimension_reports`, `op_log`, and `conflict_records`.
590
591 The `dimension_reports` field is the evidence: it maps dimension names to per-dimension merge outcomes. This structure has no analogue in byte-level VCS because dimensions don't exist at the byte level.
592
593 ### 9.4 `schema`: The Independence Declaration
594
595 ```python
596 def schema(self) -> DomainSchema:
597 ```
598
599 This is the method that makes machine-verifiable independence possible. The plugin returns a typed declaration of its structure:
600
601 ```python
602 DomainSchema(
603 top_level=SequenceSchema(kind="sequence", element="midi_file"),
604 dimensions=[
605 DimensionSpec(name="notes", schema=SequenceSchema(...), independent_merge=True),
606 DimensionSpec(name="tempo_map", schema=SequenceSchema(...), independent_merge=False),
607 # ... 19 more
608 ],
609 merge_mode="three_way",
610 )
611 ```
612
613 The `DomainSchema` type system supports five structural types, each mapped to a domain-appropriate diff algorithm:
614
615 | Schema Type | Structural Class | Diff Algorithm | Example |
616 |-------------|-----------------|----------------|---------|
617 | `SequenceSchema` | Ordered list | LCS (Myers O(nd)) | MIDI notes, DNA |
618 | `TreeSchema` | Labeled tree | Zhang-Shasha edit distance | ASTs, scene graphs |
619 | `TensorSchema` | Numerical array | Sparse numerical diff | Simulation state |
620 | `SetSchema` | Unordered set | Set algebra | File collections |
621 | `MapSchema` | Key-value map | Key-based recursive | Annotation maps |
622
623 A `TensorSchema` carries:
624
625 ```python
626 class TensorSchema(TypedDict):
627 kind: Literal["tensor"]
628 dtype: Literal["float32", "float64", "int8", ...]
629 rank: int
630 epsilon: float # ← domain-aware floating-point equality
631 diff_mode: Literal["sparse", "block", "full"]
632 ```
633
634 The `epsilon` field is a formal statement that **domain equality for floating-point data is not bit equality**. A climate simulation parameter that changes by `1e-12` is numerically unchanged (floating-point rounding). A climate parameter that changes by `0.5` is meaningfully changed. The domain plugin declares which threshold separates noise from signal. No byte-level system can make this distinction.
635
636 ---
637
638 ## 10. The Typed Operation Algebra: The Language Bytes Don't Speak
639
640 The operation algebra is the formal language for expressing changes in multidimensional state. It has six primitive operations and one composite:
641
642 ### 10.1 Operation Taxonomy
643
644 | Operation | Semantic | Byte-Level Equivalent |
645 |-----------|---------|----------------------|
646 | `InsertOp` | A new element was added at a specific position | Bytes added at offset N |
647 | `DeleteOp` | An existing element was removed | Bytes removed at offset N |
648 | `MoveOp` | An element changed position without content change | Bytes deleted and re-inserted |
649 | `ReplaceOp` | An entire element was atomically replaced | Bytes at offset N changed |
650 | `MutateOp` | Specific fields of an element changed (entity preserved) | (No byte-level equivalent) |
651 | `PatchOp` | A container was modified; the sub-operations describe the children | Bytes in range N–M changed |
652
653 The crucial entry is `MutateOp`: **there is no byte-level equivalent**. Bytes are replaced; they don't remember that the replaced bytes and the replacing bytes represent the same entity with a modified attribute.
654
655 ### 10.2 The `MutateOp` Impossibility
656
657 `MutateOp` carries `fields: dict[str, FieldMutation]`, where `FieldMutation` is:
658
659 ```python
660 class FieldMutation(TypedDict):
661 old: str # string representation of old value
662 new: str # string representation of new value
663 ```
664
665 This allows the merge engine to detect: "both branch A and branch B mutated the velocity of the same note — this is a conflict." And also: "branch A mutated the velocity of this note, branch B mutated the timing of the same note — these are independent field-level changes, auto-mergeable."
666
667 Field-level merge at entity granularity requires:
668 1. Stable entity identity (the `entity_id`)
669 2. Typed field decomposition (the `fields` dict)
670 3. Domain knowledge of which fields are independent (a field-level `independent_merge` policy)
671
672 None of these are representable in a byte diff. The best a byte diff can do is flag "bytes in the same region changed on both branches" — a coarse over-approximation that produces many false conflicts.
673
674 ### 10.3 The Semantic Cherry-Pick Capability
675
676 The typed operation algebra enables **semantic cherry-pick** — applying a specific logical change from one branch to another, independent of surrounding context:
677
678 ```
679 $ muse semantic-cherry-pick feat/dynamics --range bar:3-7 --dimension notes
680 ```
681
682 This command:
683 1. Computes the `StructuredDelta` for the specified commit range on `feat/dynamics`
684 2. Filters the `ops` list to `InsertOp` and `MutateOp` entries in the `notes` dimension at addresses between bar 3 and bar 7
685 3. Applies the filtered ops to the current branch's working state
686
687 This operation has no meaningful byte-level equivalent. A Git cherry-pick applies "the diff from this commit" — all byte changes, applied at the same byte offsets (with fuzzy matching for context). It cannot selectively apply "the note-level changes in bars 3–7 but not the dynamics changes or the tempo adjustments." That distinction requires understanding the typed structure of the delta.
688
689 ---
690
691 ## 11. The Merge Hierarchy: From File to Dimension to Operation
692
693 Muse implements a four-level merge hierarchy, each level adding semantic depth:
694
695 ### Level 1: File-Level Content-Hash Merge
696
697 ```python
698 def detect_conflicts(ours_changed: set[str], theirs_changed: set[str]) -> set[str]:
699 return ours_changed & theirs_changed
700 ```
701
702 This is what Git does. Two branches that both touch the same file SHA-256 are in conflict at this level. Muse escalates before accepting this verdict.
703
704 ### Level 2: Dimension-Level Domain Merge
705
706 The MIDI plugin parses both conflicting files, extracts 21 dimension slices, computes per-dimension SHA-256 hashes, and checks for per-dimension changes:
707
708 ```
709 change = classify_dimension_change(base_sha, left_sha, right_sha)
710 # → "unchanged", "left_only", "right_only", "both_same", "conflict"
711 ```
712
713 Only `"conflict"` (both branches changed the same dimension to different values) triggers a real conflict. The `dimension_reports` output shows exactly which dimensions conflicted and which were auto-merged.
714
715 This level transforms the false positive rate from ~94% (file-level) to the true rate — only changes to the same dimension on both branches conflict.
716
717 ### Level 3: Operation-Level OT Merge
718
719 When both branches produce `StructuredDelta` with typed operations, the `StructuredMergePlugin` extension applies Operational Transformation:
720
721 ```python
722 def ops_commute(op1: DomainOp, op2: DomainOp) -> bool:
723 match (op1["op"], op2["op"]):
724 case ("insert", "insert"):
725 if op1["address"] != op2["address"]:
726 return True # different containers, always commute
727 return op1["position"] != op2["position"]
728 case ("insert", "delete"):
729 if op1["address"] != op2["address"]:
730 return True
731 return op1["position"] != op2["position"]
732 case ("mutate", "mutate"):
733 if op1["entity_id"] != op2["entity_id"]:
734 return True # different entities
735 # same entity: check for field overlap
736 return not (set(op1["fields"]) & set(op2["fields"]))
737 # ... 22 more cases
738 ```
739
740 The `("mutate", "mutate")` case is the key: two concurrent `MutateOp`s on the **same entity** are a conflict only if they touch the **same fields**. A velocity mutation and a timing mutation on the same note commute — they modify independent fields of the same entity.
741
742 This level is formally equivalent to the commutativity analysis in Operational Transformation theory (Ellis & Gibbs, 1989; Ressel et al., 1996), applied to the domain operation algebra rather than text character operations.
743
744 ### Level 4: CRDT Convergent Join
745
746 For domains with appropriate mathematical structure, the `CRDTPlugin` protocol eliminates conflicts entirely:
747
748 ```python
749 class CRDTPlugin(MuseDomainPlugin, Protocol):
750 def join(self, a: CRDTSnapshotManifest, b: CRDTSnapshotManifest) -> CRDTSnapshotManifest: ...
751 ```
752
753 The `join` operation must be commutative, associative, and idempotent — the properties of a mathematical **join-semilattice**. When the domain's state space forms a lattice under the `join` operation, concurrent edits by any number of agents always converge to the same final state, with no conflicts possible.
754
755 The five CRDT primitives implement the building blocks:
756
757 | Primitive | Mathematical Structure | Use Case |
758 |-----------|----------------------|---------|
759 | `RGA` (Replicated Growing Array) | Causal order on sequence | Collaborative note sequencing |
760 | `ORSet` (Observed-Remove Set) | Add-wins lattice | Annotation sets, reviewer lists |
761 | `LWWRegister` (Last-Write-Wins) | Timestamp-ordered lattice | Scalar parameters, metadata |
762 | `AWMap` (Add-Wins Map) | Component-wise lattice | Key-value annotation stores |
763 | `GCounter` (Grow-only Counter) | Integer maximum lattice | Monotone metrics |
764
765 The `RGA` is particularly relevant for music and genomics: it enables concurrent insertions into an ordered sequence with deterministic, conflict-free ordering, using `{timestamp}@{author}` element IDs as stable anchors.
766
767 ---
768
769 ## 12. CRDT Convergence: When Three-Way Merge Is the Wrong Model
770
771 The three-way merge model assumes a single merge base — a common ancestor from which two independent edit streams diverge. This assumption fails in several important scenarios:
772
773 ### 12.1 The Concurrent Multi-Agent Problem
774
775 When $N$ AI agents concurrently edit the same multidimensional state, the merge DAG has $N$ concurrent tips, each with the same base. Three-way merge, applied sequentially, is $O(N)$ operations, each potentially producing conflicts that block subsequent merges.
776
777 For $N = 10$ concurrent agents, this produces up to 45 pairwise merges, each potentially conflicting. In a high-throughput AI-assisted composition environment, this is untenable.
778
779 ### 12.2 The CRDT Solution
780
781 CRDTs replace the sequential merge pipeline with a single convergent `join` operation. The commit record's CRDT fields use vector clocks to establish causal ordering:
782
783 ```python
784 class CRDTSnapshotManifest(TypedDict):
785 files: dict[str, str] # path → sha256 (inherited from StateSnapshot)
786 domain: str
787 vclock: dict[str, int] # {agent_id: event_count}
788 crdt_state: dict[str, str] # per-path CRDT metadata → SHA-256
789 schema_version: str
790 ```
791
792 The vector clock `vclock` establishes causal precedence: agent $A$'s edit at `{A: 5, B: 3}` happened after agent $B$'s edit at `{A: 4, B: 3}` and is concurrent with agent $B$'s edit at `{A: 5, B: 4}`.
793
794 The `join` of two concurrent states is computed in constant time (amortized), regardless of how many concurrent edits exist:
795
796 ```python
797 def join(a: CRDTSnapshotManifest, b: CRDTSnapshotManifest) -> CRDTSnapshotManifest:
798 merged_vclock = {k: max(a.vclock.get(k, 0), b.vclock.get(k, 0)) for k in a.vclock | b.vclock}
799 merged_state = rga_join(a.crdt_state, b.crdt_state) # commutative, associative
800 return CRDTSnapshotManifest(vclock=merged_vclock, crdt_state=merged_state, ...)
801 ```
802
803 This replaces the entire conflict detection and resolution pipeline with a mathematical operation. The domain must choose: structure its state as a lattice (and get conflict-free convergence) or retain unrestricted structure (and use three-way merge with potential conflicts).
804
805 For music, the trade-off is: if we model the note sequence as an RGA (ordered, causal), concurrent note insertions are always conflict-free and converge deterministically. The trade-off is that RGA ordering (by insertion timestamp) may not match musical ordering (by beat position) — a UI concern, not a correctness concern.
806
807 ---
808
809 ## 13. Cross-Domain Generalization: Evidence Beyond Music
810
811 The Muse plugin architecture has been extended to three domains beyond music, each demonstrating a different facet of the multidimensional state thesis.
812
813 ### 13.1 Source Code: Symbols as the Unit of Change
814
815 The code plugin uses tree-sitter to parse 15 programming languages into ASTs, then applies `symbol_diff.py` to produce symbol-level diffs. The claim: **source code is not a flat byte sequence — it has at minimum a symbol dimension and a dependency dimension**.
816
817 The code plugin's `DomainSchema` would declare:
818 - `SequenceSchema` for ordered statement sequences within function bodies
819 - `TreeSchema` for the AST of expression nodes within statements
820 - `SetSchema` for import declarations (order-independent)
821 - `MapSchema` for the symbol table (function name → function body)
822
823 The `muse coupling` command computes change coupling — which files change together across the commit history — from the typed operation log, enabling architectural insight that is structurally impossible from byte diffs.
824
825 ### 13.2 Bitcoin: UTXO State as Multidimensional
826
827 The Bitcoin plugin tracks UTXO (Unspent Transaction Output) state. This demonstrates that **financial state is multidimensional** in a way that byte-level VCS cannot capture:
828
829 - The UTXO set is an `ORSet` (add-wins set): coins are created and spent, but the history of spent coins must be preserved for validation
830 - Transaction spending rules create causal dependencies: UTXO $U$ can only be spent if it was created in a previous block
831 - The block DAG creates a non-linear history structure that requires CRDT join semantics, not three-way merge
832
833 ### 13.3 The Scaffold Plugin: Formal Interface for New Domains
834
835 The scaffold plugin at `muse/plugins/scaffold/plugin.py` provides a formally typed stub that new domain implementers must fill:
836
837 ```python
838 class ScaffoldPlugin:
839 """
840 Scaffold plugin — copy this as muse/plugins/<domain>/plugin.py.
841
842 Implementation effort by feature level:
843 - Level 1 (30 min): snapshot, diff, merge, drift, apply — basic VCS operations
844 - Level 2 (30 min): schema() — enables algorithm selection by structure
845 - Level 3 (1 hr): StructuredMergePlugin — OT-based sub-file auto-merge
846 - Level 4 (1 hr): CRDTPlugin — convergent multi-agent writes, no conflicts possible
847 """
848 ```
849
850 The four levels of implementation effort are a formal hierarchy of semantic richness, each level requiring more domain knowledge than the previous:
851
852 - Level 1 requires knowing how to parse the format and extract changed elements
853 - Level 2 requires knowing the data's structural type (sequence, tree, tensor, set, map)
854 - Level 3 requires knowing which operations commute
855 - Level 4 requires knowing whether the state space forms a mathematical lattice
856
857 ### 13.4 The Domain Concept Mapping
858
859 The `docs/protocol/muse-domain-concepts.md` establishes a cross-domain vocabulary that generalizes from music:
860
861 | Music Concept | Generic Name | Genomics | Climate Simulation |
862 |---------------|-------------|----------|-------------------|
863 | Track | Dimension/channel | Chromosome | Parameter set |
864 | Tempo | Rate metadata | Replication rate | Timestep |
865 | Key signature | Structural anchor | Reference genome | Baseline run |
866 | Region | Bounded segment | CRISPR edit window | Grid cell range |
867 | Variation | Preview-before-commit | Edit review | Parameter sweep eval |
868
869 The "Variation" concept is the most theoretically interesting: every domain needs a mechanism to **preview a proposed change in the domain's native modality before committing it to the DAG**. Music: listen. Genomics: simulate. Climate: evaluate against baseline. 3D design: render. Source code: run tests. The underlying abstraction is domain-agnostic; the modality is domain-specific.
870
871 ---
872
873 ## 14. Related Work
874
875 ### 14.1 Git and the Byte-Level Baseline
876
877 Git (Torvalds, 2005) introduced content-addressed object storage and the commit DAG, establishing the foundation for modern VCS. Git's design is intentionally byte-agnostic: `git diff` for binary files produces `Binary files X and Y differ`, delegating all semantic interpretation to external tools.
878
879 Several Git extensions have addressed specific domain limitations:
880 - `git-annex`: manages large binary files via symbolic links, but provides no semantic diff
881 - `git-lfs`: large file storage via pointer files, same limitation
882 - `git-blame` for binary: unsupported
883 - Custom merge drivers (via `.gitattributes`): allow external programs to handle merge for specific file types, but require file-level invocation — no dimension-level independence, no typed operation output
884
885 ### 14.2 Operational Transformation
886
887 The OT research program (Ellis & Gibbs, 1989; Ressel et al., 1996; Sun & Ellis, 1998) developed commutativity analysis for collaborative text editing. OT algorithms ensure that concurrent character-level operations converge to the same document regardless of application order, by transforming operations to account for concurrent insertions and deletions.
888
889 Muse's `op_transform.py` applies OT commutativity analysis to domain operations rather than character operations. The key extension: domain operations have **typed semantic content** (note velocity, AST node type, genome position) that makes commutativity decidable at a coarser granularity than character level.
890
891 The known correctness conditions for OT (the "TP2 property" — Oster et al., 2006) apply in full to the Muse operation algebra when restricted to a single sequence dimension.
892
893 ### 14.3 CRDTs
894
895 The CRDT framework (Shapiro et al., 2011) provides convergence guarantees through mathematical structure rather than transformation. The five CRDT primitives in Muse implement the standard CRDT taxonomy from "A Comprehensive Study of Convergent and Commutative Replicated Data Types" (Shapiro et al., 2011):
896
897 - `GCounter` ≅ G-Counter
898 - `LWWRegister` ≅ LW-Register
899 - `ORSet` ≅ OR-Set
900 - `RGA` ≅ RGA (Roh et al., 2011)
901 - `AWMap` ≅ Add-Wins Map (Bieniusa et al., 2012)
902
903 Muse is, to the authors' knowledge, the first system to integrate CRDT primitives directly into a general-purpose VCS at the domain-plugin layer, with the core engine remaining agnostic to whether a domain uses CRDTs or three-way merge.
904
905 ### 14.4 Music-Specific Systems
906
907 Several music notation systems have addressed version control for music:
908
909 - **LilyPond**: text-based music notation, enabling standard text VCS. Represents music as a textual DSL rather than structured events. Loses MIDI's temporal precision and performance data.
910 - **MuseScore's cloud**: proprietary, file-level, no semantic diff.
911 - **Splice (DAW plugin)**: session-level snapshots, no diff, no merge.
912 - **Git-based MusicXML workflows**: store MusicXML as text (XML), enabling line-level diffs. Loses MIDI's CC automation and event-level granularity. Merging is XML merge with XML-aware tools.
913
914 None of these systems implement: dimension-level independence, entity identity tracking across mutations, typed operation algebra, or CRDT convergence.
915
916 ### 14.5 Scientific Data Versioning
917
918 The scientific data management community has developed domain-specific versioning:
919 - **DVC** (Data Version Control): content-addressed storage for data files, no semantic diff
920 - **Pachyderm**: data pipelines with lineage tracking, no domain-semantic diff
921 - **lakeFS**: Git-like operations on data lakes, file-level granularity
922
923 The gap: none of these systems declare the independence structure of scientific data dimensions, integrate domain-specific diff algorithms, or support CRDT convergence for high-concurrency simulation environments.
924
925 ---
926
927 ## 15. Discussion and Implications
928
929 ### 15.1 The Cost of Domain Indifference
930
931 The fundamental cost of treating all artifacts as byte sequences is a systematic **loss of semantic information** that is irrecoverable at the VCS layer. Once stored as bytes, the dimensional structure of a MIDI file, the entity identity of a genomic sequence, the independence structure of a scene graph — all are lost. The VCS can be forced to produce a byte diff; it cannot be forced to produce a dimension-aware diff from stored bytes alone.
932
933 The consequence is that every higher-level capability — note blame, semantic cherry-pick, dimension-independent merge, entity lineage — must be rebuilt outside the VCS, from scratch, for every domain, without any principled framework.
934
935 ### 15.2 The Proactive Archival Argument
936
937 One response to the flat-projection critique is: "just store more metadata alongside the artifact." Store the parsed note list as a JSON sidecar. Store the entity registry as a separate file. Store the dimension hashes in a `.museattributes` file.
938
939 This is correct but undermines the flat-projection thesis: the "metadata" is the semantic representation, and the byte stream is demoted to an archival format. The VCS is now operating on the metadata, not the bytes. This is exactly what Muse does — but doing it ad hoc, without a formal plugin protocol, produces fragile, domain-specific tooling rather than a reusable abstraction.
940
941 ### 15.3 The AI-Native Dimension
942
943 Muse's commit record format includes AI-specific provenance fields:
944
945 ```python
946 agent_id: str # AI model or human agent identifier
947 model_id: str # specific model version (e.g., "gpt-4o-2024-11-20")
948 toolchain_id: str # orchestration framework
949 prompt_hash: str # SHA-256 of the generating prompt
950 signature: str # HMAC-SHA256(commit_id, agent_key)
951 ```
952
953 This anticipates a future where AI agents are first-class collaborators in creative and scientific workflows. For AI-assisted music composition, genomic editing, and simulation parameter search, the rate of concurrent writes to multidimensional state will be orders of magnitude higher than human-only workflows. The CRDT layer is not a theoretical nicety — it is the only mathematically sound approach to convergent state for high-concurrency AI collaboration.
954
955 ### 15.4 The Genomics Case: Why This Matters for Science
956
957 Consider a team of ten researchers collaborating on a reference genome annotation. Each researcher works on a different chromosome. Under byte-level VCS:
958 - Each `git push` to the main annotation file is a potential conflict
959 - Merging requires a human to compare two large binary files with no semantic diff
960 - No tool can answer "which commit introduced the annotation at position 14,523 on chromosome 3?"
961 - A researcher cannot cherry-pick "just the gene boundary corrections from branch genomics/chr7-boundary-fix" without taking the entire diff
962
963 Under the Muse model with a genomics plugin:
964 - Each chromosome is a declared dimension with `independent_merge: True`
965 - Concurrent edits to different chromosomes always merge automatically
966 - `muse blame genome.gff3 chr3:14523` answers "which commit, by which researcher, established this annotation"
967 - Semantic cherry-pick applies exactly the gene boundary corrections, filtered by chromosome and position range
968
969 The byte-level alternative is not just less convenient — it is structurally incapable of providing these capabilities.
970
971 ---
972
973 ## 16. Conclusion
974
975 We have made five formal arguments that the flat-projection thesis — the claim that multidimensional state can be adequately version-controlled as byte sequences — is incorrect in principle and in practice.
976
977 The arguments are:
978 1. **Byte equality ≠ domain equality**: non-canonical serializations make byte hashes unreliable as semantic identifiers.
979 2. **Independence is destroyed by projection**: the dimensional independence structure of multidimensional artifacts is a semantic property that survives only in the parsed domain model.
980 3. **Merge requires causal awareness**: global parameter dimensions (tempo, coordinate systems, timesteps) create causal dependencies that are invisible to byte-level diff but semantically essential.
981 4. **Entity identity requires domain knowledge**: stable entity tracking across mutations requires domain-specific identity functions that cannot be derived from bytes.
982 5. **Semantic versioning is structural**: whether a change is breaking, additive, or cosmetic is a property of the domain's symbol structure, not its byte count.
983
984 The Muse implementation is the constructive counter-proof: a working VCS for multidimensional state, with 419 commits, 691 passing tests, domain plugins for music, source code, and Bitcoin, and a formal plugin protocol that can be implemented for any structured domain. The MIDI plugin's 21-dimensional independence model, Myers-LCS note diffing, entity lineage tracking, dimension-aware merge, and optional CRDT convergence are the concrete demonstrations that the alternative is not only theoretically sound but practically achievable.
985
986 The central insight is not new — it is the fundamental principle of type theory applied to version control: **the right abstraction for managing change is the type of the thing that changed, not the bytes that represent it**. Muse is an implementation of this principle at the VCS layer, and the MIDI plugin — with its 21 independently mergeable dimensions — is its clearest proof.
987
988 The next domains are waiting: genomics, 3D spatial design, scientific simulation, spacetime modeling. The plugin protocol is ready. The core engine will not change. The flat-projection thesis will not hold for any of them.
989
990 ---
991
992 ## Appendix A: The 21 Dimensions of MIDI State
993
994 The MIDI plugin declares 21 semantic dimensions, each mapping to a subset of MIDI event types:
995
996 | # | Dimension Name | Event Types | `independent_merge` | Rationale |
997 |---|---------------|-------------|--------------------|-|
998 | 1 | `notes` | note_on, note_off | ✅ True | Core melodic/harmonic content |
999 | 2 | `pitch_bend` | pitchwheel | ✅ True | Continuous pitch expression |
1000 | 3 | `channel_pressure` | aftertouch (mono) | ✅ True | Mono aftertouch expression |
1001 | 4 | `poly_pressure` | polytouch | ✅ True | Per-note aftertouch |
1002 | 5 | `cc_modulation` | CC 1 | ✅ True | Vibrato/modulation wheel |
1003 | 6 | `cc_volume` | CC 7 | ✅ True | Channel volume fader |
1004 | 7 | `cc_pan` | CC 10 | ✅ True | Stereo pan position |
1005 | 8 | `cc_expression` | CC 11 | ✅ True | Expression pedal |
1006 | 9 | `cc_sustain` | CC 64 | ✅ True | Sustain pedal |
1007 | 10 | `cc_portamento` | CC 65 | ✅ True | Portamento on/off |
1008 | 11 | `cc_sostenuto` | CC 66 | ✅ True | Sostenuto pedal |
1009 | 12 | `cc_soft_pedal` | CC 67 | ✅ True | Soft pedal |
1010 | 13 | `cc_reverb` | CC 91 | ✅ True | Reverb send level |
1011 | 14 | `cc_chorus` | CC 93 | ✅ True | Chorus send level |
1012 | 15 | `cc_other` | All other CCs | ✅ True | Remaining controller automation |
1013 | 16 | `program_change` | program_change | ✅ True | Instrument/patch selection |
1014 | 17 | `key_signatures` | key_signature meta | ✅ True | Key changes (display only) |
1015 | 18 | `markers` | marker, text meta | ✅ True | Section labels, cue points |
1016 | 19 | `tempo_map` | set_tempo meta | ❌ **False** | Shifts all subsequent tick positions |
1017 | 20 | `time_signatures` | time_signature meta | ❌ **False** | Shifts bar/beat grid interpretation |
1018 | 21 | `track_structure` | track_name, sysex | ❌ **False** | Structural/identity metadata |
1019
1020 **Independence rate**: 18/21 = **85.7%**. Under a file-level conflict detection system, any concurrent edit to any two of these 21 dimensions produces a conflict. Under Muse's dimension-level system, concurrent edits to any two of the 18 independent dimensions are auto-merged without conflict.
1021
1022 ---
1023
1024 ## Appendix B: The Operation Commutativity Table
1025
1026 The OT merge engine's commutativity oracle covers 25 operation-kind pairs:
1027
1028 | Op 1 \ Op 2 | insert | delete | move | replace | mutate | patch |
1029 |-------------|--------|--------|------|---------|--------|-------|
1030 | **insert** | iff different address or position | iff different address or position | generally no | generally no | iff different address | recurse |
1031 | **delete** | iff different address or position | iff different address | generally no | iff different address | iff different address | recurse |
1032 | **move** | generally no | generally no | iff non-overlapping position ranges | generally no | iff different address | generally no |
1033 | **replace** | generally no | iff different address | generally no | iff different address | iff different address | recurse |
1034 | **mutate** | iff different address | iff different address | iff different address | iff different address | iff different entity, or non-overlapping fields | recurse |
1035 | **patch** | recurse | recurse | generally no | recurse | recurse | recurse into child_ops |
1036
1037 "Recurse" means: apply the commutativity check recursively to `child_ops` for `PatchOp`. The operation is commutative iff **all child pairs** commute.
1038
1039 The `("mutate", "mutate")` entry is the key: two `MutateOp`s commute iff they target different entities (`entity_id` differs) or target the same entity but modify non-overlapping fields (`set(op1.fields) ∩ set(op2.fields) == ∅`). This enables field-level independent merge within a single MIDI note entity.
1040
1041 ---
1042
1043 ## Appendix C: Formal Definitions
1044
1045 **Definition 1 (Domain State Space)**: A domain state space is a triple $(\mathcal{S}, =_{\mathcal{S}}, \{\pi_i\}_{i=1}^n)$ where $\mathcal{S}$ is the set of valid states, $=_{\mathcal{S}}$ is the domain equality relation, and $\pi_i: \mathcal{S} \to \mathcal{S}_i$ are projection functions onto dimension state spaces.
1046
1047 **Definition 2 (Dimensional Independence)**: Dimensions $i$ and $j$ are *independent* if there exists a merge function $m_{ij}: \mathcal{S}_i \times \mathcal{S}_i \times \mathcal{S}_i \to \mathcal{S}_i$ such that $m_{ij}$ operates correctly without knowledge of $\pi_j$.
1048
1049 **Definition 3 (Flat Projection)**: A flat projection of $\mathcal{S}$ is an injective function $\phi: \mathcal{S} \to \{0,1\}^*$ together with a byte-level equality relation $=_{\text{bytes}}$ such that $s_1 =_{\mathcal{S}} s_2 \Leftrightarrow \phi(s_1) =_{\text{bytes}} \phi(s_2)$.
1050
1051 **Theorem (Flat Projection Fails for Independent Dimensions)**: For any domain with $n \geq 2$ independent dimensions where the serialization format interleaves dimension data, no flat projection $\phi$ enables byte-level conflict detection with zero false positives and zero false negatives.
1052
1053 **Proof**: By the independence destruction problem (Section 4.3). $\square$
1054
1055 **Definition 4 (Typed Operation)**: A typed operation is an element of the operation algebra $\mathcal{O} = \text{InsertOp} \cup \text{DeleteOp} \cup \text{MoveOp} \cup \text{ReplaceOp} \cup \text{MutateOp} \cup \text{PatchOp}$, where each variant is a typed dict carrying a semantic `address`, content identifiers, and human-readable summaries.
1056
1057 **Definition 5 (Commutativity)**: Two operations $o_1, o_2 \in \mathcal{O}$ *commute* if for any state $s$: $\text{apply}(o_2, \text{apply}(o_1, s)) = \text{apply}(o_1, \text{apply}(o_2, s))$.
1058
1059 **Definition 6 (CRDT Join-Semilattice)**: A domain state space forms a *join-semilattice* if there exists a binary operation $\sqcup: \mathcal{S} \times \mathcal{S} \to \mathcal{S}$ that is commutative ($a \sqcup b = b \sqcup a$), associative ($a \sqcup (b \sqcup c) = (a \sqcup b) \sqcup c$), and idempotent ($a \sqcup a = a$). In a join-semilattice, the merge of any two states is unique and requires no conflict resolution.
1060
1061 ---
1062
1063 *Muse is open source. The implementation discussed in this paper is at `/muse/`. The plugin protocol is in `muse/domain.py`. The MIDI plugin is in `muse/plugins/midi/plugin.py`. The test suite validating the claims in this paper is in `tests/`. All 691 tests pass.*
1064
1065 *Version: 0.1.4 · 419 commits · March 2026*