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