cgcardona / muse public
tour-de-force-script.md markdown
758 lines 28.1 KB
45fd2148 fix: config and versioning audit — TOML attributes, v0.1.1, no Phase N labels Gabriel Cardona <cgcardona@gmail.com> 2d ago
1 # Muse Tour de Force — Video Narration Script (v0.1.1)
2
3 > **Format:** YouTube walkthrough of the Tour de Force interactive demo.
4 > Open `artifacts/tour_de_force.html` before recording. Click **Play Tour**
5 > and let the demo advance step by step while you narrate. Timestamps are
6 > approximate at 1.2 s/step; adjust to your natural pace.
7 >
8 > **Tone:** conversational, curious, a little excited — like showing a friend
9 > something you built that you genuinely believe in.
10 >
11 > **What's new in v0.1.1:** After the original 5 acts, we now have **4 additional
12 > acts** covering Typed Delta Algebra, Domain Schema & Diff Algorithms,
13 > Operation-Level OT Merge, CRDT Convergent Writes, and the live Domain Dashboard.
14 > The original 41 steps are unchanged — new acts continue from step 42.
15
16 ---
17
18 ## INTRO — Before clicking anything (~90 s)
19
20 *(Camera on screen, demo paused at step 0)*
21
22 Hey — so I want to show you something I've been building called **Muse**.
23
24 The elevator pitch: Muse is a version control system for multidimensional
25 state. Think Git, but instead of treating a file as the smallest thing you
26 can reason about, Muse understands the *internal structure* of your files —
27 and that changes everything about what a conflict means.
28
29 To make this concrete I'm going to use music, because music is a perfect
30 example of something that *looks* like a file but is actually several
31 completely independent things layered on top of each other.
32
33 Take a MIDI file. On disk it's one blob of bytes. But inside it there are at
34 least five things that have nothing to do with each other:
35
36 - **Melodic** — the notes being played, the pitch and duration of each one
37 - **Rhythmic** — when those notes land in time, the groove, the syncopation
38 - **Harmonic** — chord voicings, key changes, the tonal color
39 - **Dynamic** — velocity, expression, how hard or soft each note hits
40 - **Structural** — tempo, time signature, the skeleton the rest hangs on
41
42 These are orthogonal axes. A drummer and a pianist can edit the same MIDI
43 file — one touching only the rhythmic dimension, the other only the harmonic
44 — and there is *no conflict*. They didn't touch the same thing. Git would
45 flag the whole file. Muse resolves it in silence.
46
47 That's the idea. Let me show you the demo.
48
49 ---
50
51 ## HEADER — Reading the stats (~20 s)
52
53 *(Point to the stats bar: 14 commits · 6 branches · 1 merge · 1 conflict resolved · 41 operations)*
54
55 Everything you're about to see ran against a real Muse repository — real
56 commits, real branches, real SHA-256 content hashes. The whole demo took
57 about 150 milliseconds to execute.
58
59 Fourteen commits. Six branches. One merge conflict. All resolved. Let's
60 walk through how we got here.
61
62 ---
63
64 ## ACT 1 — Foundation (Steps 1–5)
65
66 *(Click Play Tour — steps 1–5 advance. Pause after step 5.)*
67
68 ### Step 1 — `muse init`
69
70 We start with an empty directory. `muse init` creates the `.muse/` folder —
71 the repository root. Content-addressed object store, branch metadata, config
72 file. Same idea as `git init`, but designed from scratch to be domain-agnostic.
73
74 ### Step 2 — `muse commit -m "Root: initial state snapshot"`
75
76 This is the first commit. Notice in the dimension matrix at the bottom —
77 every single dimension lights up on this first commit. Melodic, rhythmic,
78 harmonic, dynamic, structural — all five. Because this is the root: we're
79 establishing the baseline state for every dimension simultaneously.
80
81 Under the hood, Muse called `MusicPlugin.snapshot()` — which walked the
82 working directory, hashed every MIDI file with SHA-256, and returned a
83 content-addressed manifest. That manifest is what got committed to the DAG.
84
85 ### Step 3 — `muse commit -m "Layer 1: add rhythmic dimension"`
86
87 Now we add a layer. Look at the dimension matrix: only **rhythmic** and
88 **structural** light up. Rhythmic because we're adding a new rhythmic layer
89 file. Structural because adding a file changes the shape of the snapshot.
90 The melodic, harmonic, and dynamic dimensions? Untouched. Muse sees that.
91
92 ### Step 4 — `muse commit -m "Layer 2: add harmonic dimension"`
93
94 Same pattern — **harmonic** and **structural** light up. We're adding a
95 harmonic layer. The rhythmic work from the previous commit is preserved
96 exactly as-is. These are independent operations on independent dimensions.
97
98 ### Step 5 — `muse log --oneline`
99
100 Quick sanity check. Three commits, linear history, on `main`. This is your
101 foundation — the musical canvas everyone will branch from.
102
103 ---
104
105 ## ACT 2 — Divergence (Steps 6–16)
106
107 *(Resume Play Tour — steps 6–16. Pause after step 16.)*
108
109 *(Point to the DAG as branches appear)*
110
111 This is where it gets interesting. We're going to branch the repository three
112 ways simultaneously — three different creative directions diverging from the
113 same base.
114
115 ### Steps 6–8 — Branch `alpha`
116
117 `muse checkout -b alpha` creates a new branch. We commit two texture patterns:
118
119 - **"Alpha: texture pattern A (sparse)"** — melodic and rhythmic dimensions.
120 A sparse arrangement: few notes, lots of space.
121 - **"Alpha: texture pattern B (dense)"** — melodic and dynamic dimensions.
122 The dense version: more notes, more expression.
123
124 Watch the dimension dots on the DAG nodes — each commit shows exactly which
125 dimensions it touched. Alpha is doing melodic work.
126
127 ### Steps 9–11 — Branch `beta`
128
129 Back to `main`, then `muse checkout -b beta`. One commit:
130
131 - **"Beta: syncopated rhythm pattern"** — rhythmic and dynamic dimensions.
132
133 Beta is a completely different musical idea. It's not touching melody at all —
134 it's a rhythm section, working in its own lane. Rhythmic and dynamic only.
135
136 ### Steps 12–15 — Branch `gamma`
137
138 Back to `main`, then `muse checkout -b gamma`. Two commits:
139
140 - **"Gamma: ascending melody A"** — pure melodic dimension.
141 - **"Gamma: descending melody B"** — melodic and harmonic. The descending
142 line implies a harmonic movement, so two dimensions change.
143
144 ### Step 16 — `muse log --oneline`
145
146 Three parallel stories. Alpha is building texture. Beta is building rhythm.
147 Gamma is building melody. None of them know about each other. The DAG is
148 starting to look like a real project.
149
150 ---
151
152 ## ACT 3 — Clean Merges (Steps 17–21)
153
154 *(Resume Play Tour — steps 17–21. Pause after step 21.)*
155
156 Now we bring it together. This is the part that's usually painful in Git.
157 In Muse, it's going to be boring — which is the point.
158
159 ### Steps 17–18 — Merge `alpha` → `main`
160
161 `muse checkout main`, then `muse merge alpha`. The output says:
162 `Fast-forward to cb4afaed`.
163
164 Alpha was strictly ahead of main — no divergence. Fast-forward. Zero conflict.
165
166 ### Step 19 — `muse status`
167
168 `Nothing to commit, working tree clean.` Main now has all of alpha's work.
169
170 ### Step 20 — Merge `beta` → `main`
171
172 `muse merge beta`. This one creates a real merge commit —
173 `Merged 'beta' into 'main'`.
174
175 Here's what happened under the hood: Muse found the common ancestor (the
176 `Layer 2` commit), computed the three-way delta, and asked: did the same
177 dimension change on both sides?
178
179 - Alpha touched **melodic** and **dynamic**.
180 - Beta touched **rhythmic** and **dynamic**.
181 - Dynamic changed on *both sides*.
182
183 In Git: `CONFLICT`. In Muse: the dynamic changes are on different files, so
184 the union is clean. Merge commit. No human intervention. Done.
185
186 *(Point to the merge commit node in the DAG — it has the double-ring that marks it as a merge)*
187
188 ### Step 21 — `muse log --oneline`
189
190 The DAG shows the merge. Main now contains the work of three contributors.
191 Clean.
192
193 ---
194
195 ## ACT 4 — Conflict & Resolution (Steps 22–31)
196
197 *(Resume Play Tour — steps 22–31. Pause after step 31.)*
198
199 *(Lean in a little — this is the money shot)*
200
201 Now we're going to manufacture a real conflict. Two branches are going to
202 modify the *same file* on the *same dimension*. This is where Muse shows
203 what makes it different.
204
205 ### Steps 22–23 — Branch `conflict/left`
206
207 `muse checkout -b conflict/left`. Commit: **"Left: introduce shared state
208 (version A)"**.
209
210 This branch adds `shared-state.mid` and edits it with a **melodic** approach
211 and a **structural** change.
212
213 ### Steps 24–26 — Branch `conflict/right`
214
215 Back to main, then `muse checkout -b conflict/right`. Commit: **"Right:
216 introduce shared state (version B)"**.
217
218 This branch adds its own version of `shared-state.mid` with a **harmonic**
219 approach and also a **structural** change.
220
221 *(Point to dimension matrix — both conflict/left and conflict/right columns)*
222
223 Look at the dimension matrix. Left touched melodic + structural. Right touched
224 harmonic + structural. **Structural appears on both sides.** That's the conflict.
225
226 ### Steps 27–28 — Merge `conflict/left`
227
228 Fast-forward. Clean.
229
230 ### Step 29 — Merge `conflict/right`
231
232 ```
233 ❌ Merge conflict in 1 file(s):
234 CONFLICT (both modified): shared-state.mid
235 ```
236
237 Here it is. Now — in Git, you'd open the file, see angle-bracket markers,
238 and try to figure out what "their" version of a binary MIDI file even means.
239 Good luck.
240
241 In Muse, the merge engine already knows *which dimensions* conflicted.
242 It ran `MusicPlugin.merge()` with `repo_root` set, which:
243
244 1. Loaded `.museattributes` to check for strategy rules
245 2. Called `merge_midi_dimensions()` on `shared-state.mid`
246 3. Extracted the five dimension slices from base, left, and right
247 4. Compared them: melodic only changed on the left. Harmonic only changed on
248 the right. Structural changed on **both**.
249 5. Auto-merged melodic from left. Auto-merged harmonic from right.
250 6. Flagged structural as the one dimension that needs a human decision.
251
252 *(Point to the red-bordered structural cell in the dimension matrix for that commit)*
253
254 **One dimension conflicted. Four resolved automatically.** Git would have
255 thrown the entire file at you.
256
257 ### Step 30 — Resolve and commit
258
259 The human makes a decision on the structural dimension and commits:
260 `"Resolve: integrate shared-state (A+B reconciled)"`.
261
262 Look at the dimension matrix for this commit — only **structural** lights up.
263 That's the exact scope of what was resolved. The merge result carries
264 `applied_strategies` and `dimension_reports` that document exactly which
265 dimension was manually resolved and which were auto-merged.
266
267 ### Step 31 — `muse status`
268
269 `Nothing to commit, working tree clean.`
270
271 The conflict is history. Literally — it's in the DAG, attributed, auditable,
272 permanent.
273
274 ---
275
276 ## ACT 5 — Advanced Operations (Steps 32–41)
277
278 *(Resume Play Tour — steps 32–41. Let it play to completion.)*
279
280 The last act shows that Muse has the full surface area you'd expect from a
281 modern VCS.
282
283 ### Steps 32–38 — The audition arc *(pause here and explain this slowly)*
284
285 This sequence is subtle but it's one of the most important things Muse
286 demonstrates. Watch what happens.
287
288 `muse cherry-pick` — we grab the *ascending melody* commit from the `gamma`
289 branch and replay it on top of `main`. This is an **audition**. We're not
290 merging gamma — we're borrowing one idea and trying it on.
291
292 Notice: this cherry-pick has no structural connection to gamma in the DAG.
293 It's a content copy — a new commit with a new hash, parented to main's HEAD.
294 Gamma doesn't know it happened. The two commits are not linked by an edge.
295
296 *(Brief pause — let the cherry-pick commit appear in the DAG)*
297
298 `muse show` — we inspect what actually changed. `muse diff` — working tree
299 is clean. The idea is in. Now we listen.
300
301 `muse stash`, `muse stash pop` — showing you can shelve unfinished work
302 mid-session without losing anything. Bread and butter.
303
304 Now — `muse revert`. The ascending melody doesn't fit. We undo it.
305
306 *(Point to the revert commit in the DAG — pause)*
307
308 This is the moment. Look at what just happened in the DAG: there are now
309 **two** commits sitting between the resolve and the tag. One that says
310 "here's the melody." One that says "never mind." Both are permanent. Both
311 are in the history forever.
312
313 That's not a mistake — that's the *point*. Six months from now, when someone
314 asks "did we ever try a melody in this section?" the answer is in the DAG:
315 yes, on this date, here's exactly what it was, and here's the explicit
316 decision to reject it. You can check it out, listen to it, and put it back
317 if you change your mind.
318
319 The `descending melody B` commit on gamma? It's still there too — never
320 used, never merged, never deleted. Muse doesn't garbage-collect ideas. The
321 entire creative history of the project — including the roads not taken — is
322 preserved.
323
324 *(Let that land before moving on)*
325
326 ### Steps 39–40 — `muse tag add release:v1.0` / `muse tag list`
327
328 Tag the final state. `release:v1.0`. Permanent named reference to this point
329 in history.
330
331 ### Step 41 — `muse log --stat`
332
333 Full log with file-level stats for every commit. The entire history of this
334 project — 14 commits, 6 branches, 1 real conflict, resolved — in one
335 scrollable view.
336
337 *(Let the demo settle. Let it breathe for a second.)*
338
339 ---
340
341 ## DIMENSION MATRIX — Closing walkthrough (~60 s)
342
343 *(Scroll down to the Dimension State Matrix. Let the audience take it in.)*
344
345 This is the view I want to leave you with.
346
347 Every column is a commit. Every row is a dimension. Every colored cell is
348 a dimension that changed in that commit. The red-bordered cell — that one
349 structural change — is the only moment in this entire session where a human
350 had to make a decision.
351
352 *(Trace across the rows)*
353
354 Look at the melodic row. It moves. It's active on alpha commits, on gamma
355 commits, on the cherry-pick, on the revert. A continuous creative thread.
356
357 Look at the rhythmic row. It's its own thread. Beta's work. Completely
358 parallel. Never interfered with melody.
359
360 Look at structural — it barely touches anything until the conflict commit.
361 Then it lights up on both sides at once. That's the red cell. That's the
362 conflict. One cell out of seventy.
363
364 This is what multidimensional version control means. Not "track files better."
365 Track the *dimensions of your work* so that conflicts only happen when two
366 people genuinely disagree about the same thing — not because they happened
367 to edit the same file on the same day.
368
369 ---
370
371 ## ACT 6 — Typed Delta Algebra (Steps 42–46, Phase 1)
372
373 *(New section — show terminal, not the HTML demo)*
374
375 *(Camera on terminal. Switch to showing raw muse commands.)*
376
377 I want to show you what's under the hood now — the new engine that powers
378 every operation you just saw.
379
380 In v0.x, `muse show` gave you: `files modified: shared-state.mid`. That's it.
381 A filename. A black box. You had no idea what changed inside the file.
382
383 ### Step 42 — `muse show` on a commit with note-level changes
384
385 ```
386 $ muse show HEAD
387 commit: a3f2c9... "Alpha: texture pattern B (dense)"
388
389 patch shared-state.mid (melodic layer)
390 insert note C4 tick=480 vel=80 dur=240 +
391 insert note E4 tick=720 vel=64 dur=120 +
392 delete note G3 tick=240 vel=90 dur=480 -
393
394 3 operations: 2 added, 1 removed
395 ```
396
397 That's Phase 1 — the **Typed Delta Algebra**. Every commit now carries a
398 `StructuredDelta` — a list of typed operations. Not "file changed." Note added
399 at tick 480 with velocity 80 and duration 240. That's the actual thing that
400 happened.
401
402 *(Pause to let that sink in)*
403
404 There are five operation types:
405
406 - `InsertOp` — something was added (note, row, element)
407 - `DeleteOp` — something was removed
408 - `MoveOp` — something was repositioned
409 - `ReplaceOp` — something's value changed (has before/after content hashes)
410 - `PatchOp` — a container was internally modified (carries child ops)
411
412 ### Step 43 — `muse diff` between two commits
413
414 ```
415 $ muse diff HEAD~2 HEAD
416 patch tracks/bass.mid (rhythmic layer)
417 insert note F2 tick=0 vel=100 dur=120 +
418 insert note F2 tick=480 vel=80 dur=120 +
419 replace note G2 tick=240 vel=90 dur=480 → vel=70
420
421 2 added, 1 modified
422 ```
423
424 Every diff is now operation-level. You're not comparing binary blobs —
425 you're comparing structured semantic events. The merge engine works on these
426 typed operations. So does the conflict detector.
427
428 ### Step 44 — `muse log --stat`
429
430 The log now shows operation summaries inline:
431
432 ```
433 a3f2c9 Alpha: texture pattern B (dense)
434 2 notes added, 1 note removed
435 cb4afa Alpha: texture pattern A (sparse)
436 1 note added, 3 notes removed
437 ```
438
439 Every commit has a `summary` field — computed by the plugin at commit time,
440 stored for free display later. No re-scanning. No re-parsing.
441
442 ---
443
444 ## ACT 7 — Domain Schema & Diff Algorithms (Steps 47–51, Phase 2)
445
446 *(Show `muse domains` output)*
447
448 ### Step 47 — `muse domains`
449
450 ```
451 ╔══════════════════════════════════════════════════════════════╗
452 ║ Muse Domain Plugin Dashboard ║
453 ╚══════════════════════════════════════════════════════════════╝
454
455 Registered domains: 2
456 ──────────────────────────────────────────────────────────────
457
458 ● music ← active repo domain
459 Module: plugins/music/plugin.py
460 Capabilities: Phase 1 · Phase 2 · Phase 3 · Phase 4
461 Schema: v1 · top_level: set · merge_mode: three_way
462 Dimensions: melodic, harmonic, dynamic, structural
463 Description: MIDI and audio file versioning with note-level diff
464
465 ○ scaffold
466 Module: plugins/scaffold/plugin.py
467 Capabilities: Phase 1 · Phase 2 · Phase 3 · Phase 4
468 Schema: v1 · top_level: set · merge_mode: three_way
469 Dimensions: primary, metadata
470 Description: Scaffold domain — copy-paste this to build your own
471
472 ──────────────────────────────────────────────────────────────
473 To scaffold a new domain:
474 muse domains --new <name>
475 ```
476
477 This is the **Domain Dashboard** — a live inventory of every registered domain
478 plugin, its capability level, and its declared schema. The `●` bullet marks
479 the domain of the current repository. The `○` is a template.
480
481 ### Step 48 — What the schema does
482
483 The `schema()` method is Phase 2. When a plugin declares its schema, the core
484 engine knows:
485
486 - **Melodic dimension**: `sequence` of `note_event` elements → use Myers LCS diff
487 - **Harmonic dimension**: `sequence` of `chord_event` elements → use Myers LCS diff
488 - **Dynamic dimension**: `tensor` of float32 values → use epsilon-tolerant numerical diff
489 - **Structural dimension**: `tree` of track nodes → use Zhang-Shasha tree edit diff
490
491 One schema declaration. Four different algorithms. The right algorithm for each
492 dimension, automatically.
493
494 ### Step 49 — `muse domains --new genomics`
495
496 ```
497 $ muse domains --new genomics
498 ✅ Scaffolded new domain plugin: muse/plugins/genomics/
499 Class name: GenomicsPlugin
500
501 Next steps:
502 1. Implement every NotImplementedError in muse/plugins/genomics/plugin.py
503 2. Register the plugin in muse/plugins/registry.py
504 3. muse init --domain genomics
505 4. See docs/guide/plugin-authoring-guide.md for the full walkthrough
506 ```
507
508 That's it. Thirty seconds to scaffold a fully typed, Phase 1–4 capable domain
509 plugin for any structured data type you can imagine. Copy, fill in, register.
510
511 *(Point to the scaffold file)*
512
513 The scaffold is fully typed. Zero `Any`. Zero `object`. Zero `cast()`. It passes
514 `mypy --strict` out of the box. It's a copy-paste starting point, not a toy.
515
516 ---
517
518 ## ACT 8 — Operation-Level OT Merge (Steps 52–56, Phase 3)
519
520 *(Back to the conflict scenario — two branches editing the same MIDI file)*
521
522 Let me show you what happens when two musicians edit the same MIDI file at
523 the note level, concurrently.
524
525 ### Step 50 — Two branches, same file, different notes
526
527 ```
528 Branch alpha-notes: inserts note C4 at tick 480
529 Branch beta-notes: inserts note G4 at tick 960
530 ```
531
532 Both branches modified `melody.mid`. In old Muse — file-level merge — this
533 would be a conflict. One file, both modified, done.
534
535 In Phase 3 — **Operational Transformation merge** — the engine asks:
536
537 > Do these two operations commute? Can I apply them in either order and
538 > get the same result?
539
540 ### Step 51 — `muse merge beta-notes` with Phase 3
541
542 ```
543 $ muse merge beta-notes
544 ✅ Merged 'beta-notes' into 'alpha-notes' (clean)
545 2 operations auto-merged:
546 insert note C4 tick=480 (from alpha-notes)
547 insert note G4 tick=960 (from beta-notes)
548 Conflicts: none
549 ```
550
551 Two insertions at different tick positions → they commute → auto-merged.
552 No human needed. The notes are in the same file. They're at different positions.
553 They don't interfere.
554
555 ### Step 52 — When ops genuinely conflict
556
557 ```
558 Branch left: replace note C4 tick=480 vel=64 → vel=80
559 Branch right: replace note C4 tick=480 vel=64 → vel=100
560 ```
561
562 Now we have a real conflict: both branches changed the velocity of the *same
563 note* from the *same base value* to *different target values*. That's a
564 genuine disagreement. The engine flags it:
565
566 ```
567 $ muse merge right
568 ❌ Merge conflict:
569 CONFLICT (op-level): melody.mid note C4 tick=480 vel (64→80 vs 64→100)
570 ```
571
572 One note. One parameter. That's the minimal conflict unit.
573
574 *(This is what "operation-level" means — the conflict detector understood
575 the internal structure of your file well enough to isolate the conflict to
576 a single note parameter.)*
577
578 ---
579
580 ## ACT 9 — CRDT Convergent Writes (Steps 57–61, Phase 4)
581
582 *(Switch to CRDT scenario — many agents writing simultaneously)*
583
584 Everything I've shown so far is for human-paced collaboration: commits once
585 an hour, a day, a week. Three-way merge is exactly right for that.
586
587 But what if you have twenty automated agents writing simultaneously? What if
588 you're collecting telemetry from a distributed sensor network? What if your
589 domain is a set of annotations where a thousand researchers are contributing
590 concurrently?
591
592 Three-way merge breaks down. You can't resolve 10,000 conflicts per second
593 with a human.
594
595 ### Step 57 — CRDT mode: join always succeeds
596
597 Phase 4 introduces **CRDT Semantics**. A plugin that implements `CRDTPlugin`
598 replaces `merge()` with `join()`. The join is a mathematical operation on a
599 **lattice** — a partial order where any two states have a unique least upper bound.
600
601 The key property: **join always succeeds. No conflict state ever exists.**
602
603 ### Step 58 — The six CRDT primitives
604
605 ```python
606 from muse.core.crdts import (
607 VectorClock, # causal ordering between agents
608 LWWRegister, # last-write-wins scalar
609 ORSet, # unordered set — adds always win
610 RGA, # ordered sequence — commutative insertion
611 AWMap, # key-value map — adds win
612 GCounter, # grow-only counter
613 )
614 ```
615
616 Each one satisfies the three lattice laws:
617
618 1. `join(a, b) == join(b, a)` — order of messages doesn't matter
619 2. `join(join(a, b), c) == join(a, join(b, c))` — batching is fine
620 3. `join(a, a) == a` — duplicates are harmless
621
622 These three laws are the mathematical guarantee that all replicas converge to
623 the same state — regardless of how late or how many times messages arrive.
624
625 ### Step 59 — ORSet: adds always win
626
627 ```python
628 # Agent A and Agent B write simultaneously:
629 s_a, tok_a = ORSet().add("annotation-GO:0001234")
630 s_b = ORSet().remove("annotation-GO:0001234") # B doesn't know about A's add
631
632 # After join:
633 merged = s_a.join(s_b)
634 assert "annotation-GO:0001234" in merged.elements() # A's add survives
635 ```
636
637 This is the semantics for a genomics annotation set: concurrent adds win.
638 If you didn't know I added that annotation, your remove doesn't count. No
639 silent data loss. Ever.
640
641 ### Step 60 — `muse merge` in CRDT mode
642
643 ```
644 $ muse merge agent-branch-1 (CRDT mode detected)
645 ✅ Joined 'agent-branch-1' into HEAD
646 CRDT join: 847ms
647 Labels joined: 3 adds merged
648 Sequence joined: RGA converged (12 elements)
649 Conflicts: none (CRDT join never conflicts)
650 ```
651
652 Joins never conflict. You can run `muse merge` on a thousand agent branches
653 and it always succeeds. The result is always the convergent state — the
654 least upper bound — of all writes.
655
656 ### Step 61 — When to use CRDT vs. three-way
657
658 This is the judgment call every plugin author makes:
659
660 | Scenario | Right choice |
661 |----------|-------------|
662 | Human composer editing a MIDI score | Three-way merge (Phase 3) |
663 | 100 agents annotating a genome | CRDT `ORSet` |
664 | DAW with multi-cursor note input | CRDT `RGA` |
665 | Distributed IoT telemetry counter | CRDT `GCounter` |
666 | Configuration parameter (one writer) | `LWWRegister` |
667
668 CRDTs give up human arbitration in exchange for infinite scalability. Use them
669 when you have more concurrent writes than humans can handle.
670
671 ---
672
673 ## OUTRO — Muse v1.0 (~60 s)
674
675 *(Back to camera or full screen)*
676
677 So that's Muse v0.1.1.
678
679 We started with the foundation — a domain-agnostic VCS where conflicts are
680 defined by dimension, not by file. That's still the core. But we've now built
681 four layers on top of it that progressively close the gap between "a VCS that
682 understands files" and "a VCS that understands your domain."
683
684 **Phase 1**: Every operation is typed. Every commit carries a semantic operation
685 list. `muse show` tells you what changed inside the file, not just which file.
686
687 **Phase 2**: Every domain declares its data structure. The diff engine
688 automatically selects the right algorithm — LCS for sequences, tree-edit for
689 hierarchies, epsilon-tolerant for tensors, set algebra for unordered collections.
690
691 **Phase 3**: Merges happen at operation granularity. Two musicians editing
692 the same file at different positions don't conflict. The merge engine uses
693 Operational Transformation to compute the minimal, real conflict set.
694
695 **Phase 4**: For high-throughput multi-agent scenarios, CRDT semantics replace
696 merge with a mathematical join that always converges. No conflict state ever
697 exists. Hundreds of agents can write simultaneously.
698
699 And all of this is accessible to any domain through a single five-method plugin
700 interface. Music is the proof. Genomics, climate simulation, 3D spatial design,
701 neural network checkpoints — any domain with structure can be versioned with Muse.
702
703 `muse domains --new <your_domain>`. Thirty seconds to scaffold. Fill in the
704 methods. Register. Done.
705
706 The code is on GitHub. The link is in the description. If you're building
707 something with structured state that deserves better version control — reach out.
708
709 ---
710
711 ## APPENDIX — Speaker Notes
712
713 ### On questions you might get
714
715 **"Why not just use Git with LFS?"**
716 Git LFS stores big files — it doesn't understand them. You still get binary
717 merge conflicts on the whole file. The dimension is the thing.
718
719 **"What does 'domain-agnostic' actually mean?"**
720 The core engine — DAG, branches, object store, merge state machine — has
721 zero knowledge of music. It calls five methods on a plugin object. Swap the
722 plugin, get a different domain. The same commit graph, the same `muse merge`,
723 different semantics.
724
725 **"What's the difference between Phase 3 OT and Phase 4 CRDT?"**
726 OT assumes you have a base and can identify the common ancestor. It produces
727 a minimal conflict set when ops genuinely disagree. CRDT assumes there is no
728 shared base — every agent writes to their local replica and the join is
729 always clean. OT is right for human-paced editing; CRDT is right for
730 machine-speed concurrent writes.
731
732 **"Is this production-ready?"**
733 v0.1.1 is solid: strict typing, 691 passing tests, CI, four semantic layers
734 fully implemented. Not production for a studio yet — but the architecture is
735 sound and the hard parts (content-addressed storage, OT, CRDT) are working.
736
737 **"What about performance?"**
738 The original demo runs in 150ms for 14 commits and 41 operations. The CRDT
739 joins run in sub-millisecond. The bottleneck will be large files — handled
740 by chunked object storage in the roadmap.
741
742 ### Suggested chapter markers for YouTube
743
744 | Timestamp | Chapter |
745 |-----------|---------|
746 | 0:00 | Intro — what is multidimensional VCS? |
747 | 1:30 | The five musical dimensions |
748 | 3:00 | Act 1 — Foundation |
749 | 5:30 | Act 2 — Three branches diverge |
750 | 9:00 | Act 3 — Clean merges |
751 | 11:30 | Act 4 — The conflict (and why it's different) |
752 | 16:00 | Act 5 — Full VCS surface area |
753 | 18:30 | Dimension Matrix walkthrough |
754 | 20:00 | Act 6 — Typed Delta Algebra (Phase 1) |
755 | 23:00 | Act 7 — Domain Schema & muse domains dashboard (Phase 2) |
756 | 27:00 | Act 8 — Operation-level OT Merge (Phase 3) |
757 | 31:00 | Act 9 — CRDT Convergent Writes (Phase 4) |
758 | 36:00 | Outro — Muse v1.0 and what's next |