cgcardona / muse public
tour-de-force-code.md markdown
807 lines 27.4 KB
062ae392 feat: code-domain semantic commands + code tour de force demo (#54) Gabriel Cardona <cgcardona@gmail.com> 1d ago
1 # Muse Code Plugin — Tour de Force Demo Script
2
3 > **Format:** Terminal walkthrough narration. Run the commands live while narrating.
4 > Everything you type is real — no mocks, no pre-recorded output.
5 > Tone: direct, a little incredulous — like showing someone a tool you genuinely think
6 > changes the rules.
7 >
8 > **Companion:** Read `docs/demo/tour-de-force-script.md` first (music demo) to
9 > understand the shared infrastructure. This script builds on those ideas and
10 > applies them to the domain most engineers live in every day: source code.
11
12 ---
13
14 ## INTRO — Before typing anything (~90 s)
15
16 *(Camera on screen, terminal open, empty directory)*
17
18 Okay so — Git treats your code as text files.
19
20 Not functions. Not classes. Not imports. Not the call graph between modules.
21 Text files. Lines. Diffs.
22
23 That was the right abstraction in 1972. You had flat files, line editors, no
24 structure to speak of. A line diff was the best you could do.
25
26 But we've been doing version control the same way for fifty years, and
27 meanwhile the code we're versioning has gotten enormously more structured.
28 Your IDE knows what a function is. Your type checker knows what a function is.
29 Your language server knows what a function is.
30
31 Git still doesn't know what a function is.
32
33 Here's what that costs you. Rename a function across ten files, Git sees
34 ten modifications. Move a module, Git sees a delete and an add — it has a
35 flag called `--find-renames` that uses a heuristic based on line similarity
36 to *guess* that maybe these two things are the same function. Maybe.
37
38 Two engineers touch the same file — one modifies `calculate_total`, the other
39 modifies `validate_amount` — Git calls that a conflict. They didn't touch the
40 same thing. But Git doesn't know that. It sees the same file, both modified,
41 conflict.
42
43 I want to show you what happens when your version control system actually
44 understands what it's versioning.
45
46 This is Muse — `muse init --domain code`.
47
48 ---
49
50 ## ACT 1 — First Commit: Muse Sees Symbols, Not Lines (Steps 1–4)
51
52 *(Create and move into a new directory)*
53
54 ```
55 $ mkdir my-api && cd my-api
56 $ muse init --domain code
57 ✅ Initialized Muse repository (domain: code)
58 .muse/ created
59 Plugin: CodePlugin — AST-based semantic versioning
60 Languages: Python · TypeScript · JavaScript · Go · Rust
61 Java · C · C++ · C# · Ruby · Kotlin
62 ```
63
64 Already different. Git's `git init` doesn't tell you what it understands about
65 your files. Muse tells you: eleven languages, AST-based, semantic.
66
67 Let me write some code.
68
69 ```python
70 # src/billing.py
71 def calculate_total(items: list[Item]) -> Decimal:
72 """Sum all item prices after applying discounts."""
73 return sum(item.price * (1 - item.discount) for item in items)
74
75 def validate_amount(amount: Decimal) -> bool:
76 """Return True if amount is positive and within policy limits."""
77 return Decimal("0") < amount <= Decimal("1000000")
78
79 class Invoice:
80 def __init__(self, customer_id: str, items: list[Item]) -> None:
81 self.customer_id = customer_id
82 self.items = items
83 self.total = calculate_total(items)
84
85 def to_dict(self) -> dict[str, str | Decimal]:
86 return {"customer_id": self.customer_id, "total": str(self.total)}
87 ```
88
89 ```
90 $ muse commit -m "Add billing module: Invoice, calculate_total, validate_amount"
91 ```
92
93 Now watch what `muse show` tells you:
94
95 ```
96 $ muse show HEAD
97
98 commit a3f2c9e1 "Add billing module: Invoice, calculate_total, validate_amount"
99 Author: alice
100 Date: 2026-03-14
101
102 A src/billing.py
103 └─ added function calculate_total
104 └─ added function validate_amount
105 └─ added class Invoice
106 └─ added method Invoice.__init__
107 └─ added method Invoice.to_dict
108
109 5 symbols added across 1 file
110 ```
111
112 Git's `git show` would tell you: five lines added, eight lines added. You'd
113 read the diff and reconstruct the meaning. Muse tells you the meaning directly:
114 five specific symbols — their names, their kinds, their identities — were added.
115
116 ---
117
118 ## ACT 2 — `muse symbols`: The Full Symbol Graph (~60 s)
119
120 *(Pause here — this is a brand new capability)*
121
122 Git has no command like this. There is no `git symbols`. Because Git doesn't
123 know what a symbol is.
124
125 ```
126 $ muse symbols
127
128 commit a3f2c9e1 "Add billing module"
129
130 src/billing.py
131 fn calculate_total line 2
132 fn validate_amount line 8
133 class Invoice line 13
134 method Invoice.__init__ line 14
135 method Invoice.to_dict line 19
136
137 5 symbol(s) across 1 file (Python: 5)
138 ```
139
140 Every function. Every class. Every method. Line number, kind, stable hash
141 identity. This is the semantic interior of your repository — not a file list,
142 not a diff — the actual *structure* of your code, queryable at any commit.
143
144 Filter by kind:
145
146 ```
147 $ muse symbols --kind class
148
149 src/billing.py
150 class Invoice line 13
151
152 1 symbol(s) across 1 file (Python: 1)
153 ```
154
155 Filter to a specific file:
156
157 ```
158 $ muse symbols --file src/billing.py
159
160 src/billing.py
161 fn calculate_total line 2
162 fn validate_amount line 8
163 class Invoice line 13
164 method Invoice.__init__ line 14
165 method Invoice.to_dict line 19
166
167 5 symbol(s) across 1 file (Python: 5)
168 ```
169
170 Include content hashes — the stable identity Muse uses to detect renames
171 and cross-file moves:
172
173 ```
174 $ muse symbols --hashes
175
176 src/billing.py
177 fn calculate_total line 2 a3f2c9..
178 fn validate_amount line 8 cb4afa..
179 class Invoice line 13 1d2e3f..
180 method Invoice.__init__ line 14 4a5b6c..
181 method Invoice.to_dict line 19 7d8e9f..
182 ```
183
184 *(Pause)*
185
186 That `a3f2c9..` is the SHA-256 hash of `calculate_total`'s **normalized AST**.
187 Not the raw text. The AST. If you reformat the function — add spaces, change
188 indentation, adjust comments — the hash is unchanged. The *semantic content*
189 didn't change. Muse knows that.
190
191 ---
192
193 ## ACT 3 — Rename Is Not a Delete + Add: The Body Hash (~90 s)
194
195 *(This is the thing that makes engineers stop and stare)*
196
197 Let me add some commits and then do a rename.
198
199 We're going to add a Go file to show multi-language support:
200
201 ```go
202 // api/server.go
203 func HandleRequest(w http.ResponseWriter, r *http.Request) {
204 ctx := r.Context()
205 process(ctx, w, r)
206 }
207
208 func process(ctx context.Context, w http.ResponseWriter, r *http.Request) {
209 // core request processing logic
210 }
211 ```
212
213 ```
214 $ muse commit -m "Add Go API server"
215 $ muse show HEAD
216 commit 8f9a0b1c "Add Go API server"
217
218 A api/server.go
219 └─ added function HandleRequest
220 └─ added function process
221
222 2 symbols added across 1 file
223 ```
224
225 Now — a rename. Product decides `calculate_total` should be `compute_invoice_total`.
226 Clearer, more domain-specific.
227
228 ```python
229 # src/billing.py — rename only, body unchanged
230 def compute_invoice_total(items: list[Item]) -> Decimal:
231 """Sum all item prices after applying discounts."""
232 return sum(item.price * (1 - item.discount) for item in items)
233 ```
234
235 ```
236 $ muse commit -m "Rename: calculate_total → compute_invoice_total (domain clarity)"
237 $ muse show HEAD
238
239 commit 1d2e3faa "Rename: calculate_total → compute_invoice_total (domain clarity)"
240
241 M src/billing.py
242 └─ calculate_total → renamed to compute_invoice_total
243
244 1 rename detected
245 ```
246
247 Not "1 line deleted, 1 line added." Not "function name changed." Specifically:
248 **renamed to compute_invoice_total**. Muse detected this by comparing the
249 `body_hash` of every removed symbol against every added symbol. Same body,
250 different name — that's a rename. It's mathematically certain, not a heuristic.
251
252 Git's `--find-renames` flag gets confused when files get refactored. It needs
253 enough unchanged lines to fire the similarity threshold. A one-line function?
254 Git has no idea. Muse doesn't care — it's comparing AST hashes, not counting
255 lines.
256
257 ---
258
259 ## ACT 4 — Cross-File Move: Content Identity Across the Repository (~90 s)
260
261 Now — a module extraction. The billing team grows. `validate_amount` should live
262 in a dedicated `validation` module. We move it.
263
264 ```python
265 # src/validation.py — new file
266 def validate_amount(amount: Decimal) -> bool:
267 """Return True if amount is positive and within policy limits."""
268 return Decimal("0") < amount <= Decimal("1000000")
269 ```
270
271 ```python
272 # src/billing.py — validate_amount removed
273 from src.validation import validate_amount
274 ```
275
276 ```
277 $ muse commit -m "Extract: move validate_amount to validation module"
278 $ muse show HEAD
279
280 commit 4b5c6d7e "Extract: move validate_amount to validation module"
281
282 A src/validation.py
283 └─ added function validate_amount [moved from src/billing.py::validate_amount]
284
285 M src/billing.py
286 └─ validate_amount [moved to src/validation.py::validate_amount]
287 └─ added import::src.validation
288
289 cross-file move detected: validate_amount
290 ```
291
292 *(Stop and let this breathe)*
293
294 Git would show you: delete lines from `billing.py`, add lines to `validation.py`.
295 No connection between them. The cross-file relationship is invisible.
296
297 Muse shows you: `validate_amount` moved. Same `content_id` on both sides — SHA-256
298 of the normalized function AST — proves they're the same symbol. The connection is
299 explicit, permanent, in the DAG.
300
301 This matters six months from now when a new engineer asks: "Where did
302 `validate_amount` come from? Why does it live in `validation.py`?" With Git,
303 the answer is in a deleted-line diff somewhere in history. With Muse, the answer
304 is in the commit graph: it was extracted from `billing.py` on this date, in this
305 commit, for this reason.
306
307 ---
308
309 ## ACT 5 — Branching: Symbol-Level Merges (~2 min)
310
311 *(This is the moment Git breaks. This is where Muse wins.)*
312
313 Two engineers, `alice` and `bob`, both need to modify `billing.py`.
314
315 Alice is improving `compute_invoice_total`'s performance:
316
317 ```
318 $ muse checkout -b alice/optimise-total
319 ```
320
321 ```python
322 # Alice's version — vectorised with numpy
323 def compute_invoice_total(items: list[Item]) -> Decimal:
324 """Sum all item prices after applying discounts — vectorised."""
325 prices = [item.price for item in items]
326 discounts = [item.discount for item in items]
327 return Decimal(str(sum(p * (1 - d) for p, d in zip(prices, discounts))))
328 ```
329
330 ```
331 $ muse commit -m "Perf: optimise compute_invoice_total with explicit vectorisation"
332 ```
333
334 Bob is refactoring `Invoice.to_dict()` for a new API contract:
335
336 ```
337 $ muse checkout main
338 $ muse checkout -b bob/invoice-v2
339 ```
340
341 ```python
342 # Bob's version — richer to_dict output
343 def to_dict(self) -> dict[str, str | Decimal | list[str]]:
344 return {
345 "customer_id": self.customer_id,
346 "total": str(self.total),
347 "item_count": str(len(self.items)),
348 "currency": "USD",
349 }
350 ```
351
352 ```
353 $ muse commit -m "API: extend Invoice.to_dict with item_count and currency"
354 ```
355
356 Now we merge. In Git, this would be a conflict — same file, both modified.
357
358 ```
359 $ muse checkout main
360 $ muse merge alice/optimise-total
361 ✅ Merged 'alice/optimise-total' into 'main' (fast-forward)
362 ```
363
364 ```
365 $ muse merge bob/invoice-v2
366
367 ✅ Merged 'bob/invoice-v2' into 'main' (clean)
368
369 Symbol-level auto-merge:
370 alice modified: src/billing.py::compute_invoice_total
371 bob modified: src/billing.py::Invoice.to_dict
372 No shared symbols — operations commute
373 ```
374
375 *(Hold on that output)*
376
377 Let that sink in. Same file. Both modified. Different symbols.
378
379 The operations **commute**: Alice's change to `compute_invoice_total` and Bob's
380 change to `Invoice.to_dict` have no dependency on each other. Applying them
381 in either order produces the same result. Muse detects this at the symbol level
382 and auto-merges without asking a human.
383
384 Git's answer to this is: conflict. You open the file, you see `<<<<<<< HEAD`,
385 you figure out which half is Alice and which half is Bob, you manually combine
386 them, you mark it resolved. Every time. Even when the two changes are trivially
387 independent.
388
389 ---
390
391 ## ACT 6 — Symbol Conflict: When They Actually Disagree (~90 s)
392
393 Let me show you what a *real* conflict looks like in Muse.
394
395 Two engineers both touch `compute_invoice_total`:
396
397 ```
398 $ muse checkout -b carol/tax-handling
399 ```
400
401 Carol adds tax calculation:
402 ```python
403 def compute_invoice_total(items: list[Item], tax_rate: Decimal = Decimal("0")) -> Decimal:
404 subtotal = sum(item.price * (1 - item.discount) for item in items)
405 return subtotal * (1 + tax_rate)
406 ```
407
408 ```
409 $ muse commit -m "Feature: add tax_rate parameter to compute_invoice_total"
410 ```
411
412 ```
413 $ muse checkout main
414 $ muse checkout -b dave/currency-rounding
415 ```
416
417 Dave adds currency rounding:
418 ```python
419 def compute_invoice_total(items: list[Item]) -> Decimal:
420 raw = sum(item.price * (1 - item.discount) for item in items)
421 return raw.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
422 ```
423
424 ```
425 $ muse commit -m "Fix: round compute_invoice_total to 2 decimal places"
426 ```
427
428 Merge:
429
430 ```
431 $ muse checkout main
432 $ muse merge carol/tax-handling
433 ✅ Fast-forward
434
435 $ muse merge dave/currency-rounding
436
437 ❌ Merge conflict — symbol-level:
438
439 CONFLICT src/billing.py::compute_invoice_total
440 carol modified: signature changed (added tax_rate parameter)
441 implementation changed
442 dave modified: signature unchanged
443 implementation changed
444
445 These changes are not commutative.
446 Resolve at: src/billing.py::compute_invoice_total
447 ```
448
449 *(Point at the output)*
450
451 Notice what Muse tells you:
452 - **One symbol** — `compute_invoice_total`.
453 - **Exactly two descriptions** of what changed on each side.
454 - **Why they conflict** — Carol changed both signature and body; Dave changed body only.
455
456 Git would show you: `<<<<<<< HEAD` around the entire function, yours vs. theirs.
457 You'd manually reconstruct what both engineers were trying to do.
458
459 Muse shows you the conflict *at the semantic level*. The symbol name, the kind of
460 change on each side, exactly what you need to make a decision. And every other
461 symbol in the file — `validate_amount`, `Invoice.__init__`, `Invoice.to_dict` —
462 is already merged. You resolve one thing, not a file.
463
464 ---
465
466 ## ACT 7 — `muse symbol-log`: The History of a Single Function (~90 s)
467
468 *(This command does not exist in Git. Period.)*
469
470 ```
471 $ muse symbol-log "src/billing.py::compute_invoice_total"
472
473 Symbol: src/billing.py::compute_invoice_total
474 ──────────────────────────────────────────────────────────────
475
476 ● a3f2c9e1 2026-03-14 "Add billing module"
477 created added function calculate_total
478
479 ● 1d2e3faa 2026-03-15 "Rename: calculate_total → compute_invoice_total"
480 renamed calculate_total → compute_invoice_total
481 (tracking continues as src/billing.py::compute_invoice_total)
482
483 ● cb4afaed 2026-03-16 "Perf: optimise compute_invoice_total"
484 modified implementation changed
485
486 ● 8f9a0b1c 2026-03-17 "Feature: add tax_rate parameter"
487 signature signature changed (implementation changed)
488
489 4 event(s) (created: 1, modified: 1, renamed: 1, signature: 1)
490 ```
491
492 *(Pause)*
493
494 Every event in the life of this one function. When it was created. When it was
495 renamed — and the name it had *before* the rename. When its implementation changed.
496 When its signature changed.
497
498 In Git: `git log -p src/billing.py`. You get every commit that touched the file,
499 and you wade through line diffs for every function in the file to find the ones
500 that touched your function. Then you try to figure out if a rename happened by
501 looking at the diffs by eye.
502
503 In Muse: one command, one symbol address, complete semantic history.
504
505 And notice — Muse tracked through the rename. The function was called
506 `calculate_total` at the beginning. When it was renamed, Muse updated its
507 tracking identity. The entire history follows the function, not the name.
508
509 ---
510
511 ## ACT 8 — `muse detect-refactor`: The Refactoring Report (~60 s)
512
513 *(Another impossible-in-Git command)*
514
515 You've just onboarded to a new codebase. You want to understand what
516 structural changes happened in the last sprint.
517
518 ```
519 $ muse detect-refactor --from HEAD~8 --to HEAD
520
521 Semantic refactoring report
522 From: a3f2c9e1 "Add billing module"
523 To: 4b5c6d7e "Extract: move validate_amount to validation module"
524 ──────────────────────────────────────────────────────────────
525
526 RENAME src/billing.py::calculate_total
527 → compute_invoice_total
528 commit 1d2e3faa "Rename: calculate_total → compute_invoice_total"
529
530 MOVE src/billing.py::validate_amount
531 → src/validation.py::validate_amount
532 commit 4b5c6d7e "Extract: move validate_amount to validation module"
533
534 SIGNATURE src/billing.py::compute_invoice_total
535 signature changed (added tax_rate parameter)
536 commit 8f9a0b1c "Feature: add tax_rate parameter"
537
538 IMPLEMENTATION src/billing.py::compute_invoice_total
539 implementation changed (signature stable)
540 commit cb4afaed "Perf: optimise compute_invoice_total"
541
542 ──────────────────────────────────────────────────────────────
543 4 refactoring operation(s) detected
544 (1 implementation · 1 move · 1 rename · 1 signature)
545 ```
546
547 In Git: `git log --oneline HEAD~8..HEAD`. You get commit messages. You read each
548 one and try to infer from the prose what structurally changed. If the commit
549 messages are good, great. If not, you're reading diffs.
550
551 In Muse: a classified report of every semantic refactoring operation. Rename.
552 Move. Signature change. Implementation change. Automatically, from the symbol graph.
553
554 Filter to just renames:
555
556 ```
557 $ muse detect-refactor --kind rename
558
559 RENAME src/billing.py::calculate_total
560 → compute_invoice_total
561 commit 1d2e3faa "Rename: calculate_total → compute_invoice_total"
562
563 1 refactoring operation(s) detected
564 (1 rename)
565 ```
566
567 ---
568
569 ## ACT 9 — Multi-Language: One Repository, Eleven Languages (~60 s)
570
571 *(The moment to widen the aperture)*
572
573 Everything I just showed you works across all eleven supported languages.
574
575 Let me add a TypeScript service file:
576
577 ```typescript
578 // services/payment.ts
579 export class PaymentService {
580 async processPayment(invoice: Invoice): Promise<PaymentResult> {
581 const validated = await this.validate(invoice);
582 return this.charge(validated);
583 }
584
585 private async validate(invoice: Invoice): Promise<Invoice> {
586 if (!invoice.total) throw new Error("Invalid invoice");
587 return invoice;
588 }
589 }
590 ```
591
592 ```
593 $ muse commit -m "Add TypeScript PaymentService"
594 $ muse symbols --file services/payment.ts
595
596 services/payment.ts
597 class PaymentService line 2
598 method PaymentService.processPayment line 3
599 method PaymentService.validate line 8
600
601 3 symbol(s) across 1 file (TypeScript: 3)
602 ```
603
604 And a Rust domain model:
605
606 ```rust
607 // domain/invoice.rs
608 pub struct Invoice {
609 pub customer_id: String,
610 pub total: Decimal,
611 }
612
613 impl Invoice {
614 pub fn new(customer_id: String, items: Vec<Item>) -> Self {
615 Invoice { customer_id, total: compute_total(&items) }
616 }
617
618 pub fn is_valid(&self) -> bool {
619 self.total > Decimal::ZERO
620 }
621 }
622 ```
623
624 ```
625 $ muse commit -m "Add Rust Invoice domain model"
626 $ muse symbols --file domain/invoice.rs
627
628 domain/invoice.rs
629 class Invoice line 2
630 method Invoice.new line 7
631 method Invoice.is_valid line 11
632
633 3 symbol(s) across 1 file (Rust: 3)
634 ```
635
636 Python. TypeScript. Rust. Go. Java. C. C++. C#. Ruby. Kotlin. JavaScript.
637 Same commands. Same symbol addresses. Same rename and move detection. Same
638 semantic merge engine.
639
640 One abstraction. Eleven languages. The entire symbol graph queryable and
641 version-controlled at the function level.
642
643 ---
644
645 ## ACT 10 — Why This Beats Git for Real Engineering Teams (~60 s)
646
647 *(Step back from the terminal)*
648
649 Let me tell you the scenarios where this matters most — where teams actually feel it.
650
651 **Code review.** Instead of reading a 400-line diff and reconstructing what changed
652 semantically, your reviewer sees: "three functions modified, one renamed, one moved
653 to a new module." The review is scoped to the real changes.
654
655 **Onboarding.** A new engineer asks: "Who owns `compute_invoice_total` and why does
656 it work the way it does?" With Muse: `muse symbol-log "src/billing.py::compute_invoice_total"`.
657 Full history, including the rename from `calculate_total`, including the perf
658 improvement, including the tax parameter. The story of the function, not the file.
659
660 **Merge conflicts.** Your team's most expensive meetings are merge conflict
661 resolution sessions. With Muse: only functions that genuinely conflict get flagged.
662 Not "same file, different lines" false positives — actual semantic disagreements
663 between two engineers about the same named function.
664
665 **Refactoring fearlessly.** Extract a module. Move a function. Rename a class
666 across ten files. Muse records the semantic intent, not the text change. Future
667 readers see what you did, not just that bytes changed.
668
669 **Audit and compliance.** "Has this function's signature ever changed?"
670 `muse symbol-log --kind signature`. "What functions did we move last quarter?"
671 `muse detect-refactor --kind move --from Q1-tag`. Answers in milliseconds.
672
673 ---
674
675 ## ACT 11 — The Domain Schema: Code as Five Dimensions (~60 s)
676
677 ```
678 $ muse domains
679
680 ╔══════════════════════════════════════════════════════════════╗
681 ║ Muse Domain Plugin Dashboard ║
682 ╚══════════════════════════════════════════════════════════════╝
683
684 Registered domains: 2
685 ──────────────────────────────────────────────────────────────
686
687 ● code ← active repo domain
688 Module: plugins/code/plugin.py
689 Capabilities: Typed Deltas · Domain Schema · OT Merge
690 Schema: v1 · top_level: set · merge_mode: three_way
691 Dimensions: structure, symbols, imports, variables, metadata
692 Description: Semantic code versioning — AST-based symbol graph
693
694 ○ music
695 Module: plugins/music/plugin.py
696 Capabilities: Typed Deltas · Domain Schema · OT Merge
697 Schema: v1 · top_level: set · merge_mode: three_way
698 Dimensions: melodic, harmonic, dynamic, structural
699 Description: MIDI and audio file versioning with note-level diff
700 ```
701
702 The code domain has five dimensions — parallel to music's five dimensions:
703
704 | Dimension | What it tracks | Diff algorithm |
705 |-----------|---------------|----------------|
706 | `structure` | Module and file tree | GumTree tree-edit |
707 | `symbols` | Functions, classes, methods | GumTree tree-edit (AST) |
708 | `imports` | Import statements | Set algebra |
709 | `variables` | Top-level assignments | Set algebra |
710 | `metadata` | Config, non-code files | Set algebra |
711
712 An import added on one branch and a function renamed on another? Different
713 dimensions. Auto-merged. No conflict.
714
715 Two branches both add the same new function name? Same dimension, same address.
716 Symbol conflict — one message, one decision.
717
718 ---
719
720 ## OUTRO — Muse: What Version Control Becomes (~60 s)
721
722 *(Back to camera)*
723
724 Git was designed when "a file" was the smallest meaningful unit of software.
725 That was correct in 1972. We're building differently now.
726
727 Muse treats code the way your IDE, your compiler, and your type checker already
728 treat it — as a collection of named, typed, structured symbols with identities
729 that persist across renames and moves.
730
731 Every commit carries a full semantic delta — not which lines changed, but which
732 functions were added, removed, renamed, moved, or internally modified.
733
734 Every merge operates at symbol granularity — only genuine semantic disagreements
735 produce conflicts.
736
737 Every refactoring is permanent and queryable — rename, move, extract, inline —
738 all recorded with their semantic meaning, visible through `muse detect-refactor`
739 and `muse symbol-log`.
740
741 And it works across eleven languages. Today. With the same plugin interface that
742 already works for music, and will work for genomics, for scientific simulation,
743 for any structured data type you want to version.
744
745 `muse init --domain code`. Git is still there if you need it. But once you see
746 symbol-level history, you don't go back.
747
748 ---
749
750 ## APPENDIX — Speaker Notes
751
752 ### On the three new commands
753
754 **`muse symbols`** is the simplest to explain: it's `git ls-files` except it
755 shows the semantic *interior* of your files, not just their names. Every function.
756 Every class. Every method. Stable hash identities. Filter by kind, file, or
757 language.
758
759 **`muse symbol-log`** is the hardest for Git users to absorb because it has no
760 analogue. The closest is `git log -p -- <file>` but that shows line diffs for
761 the entire file. `muse symbol-log` follows a *specific function* through history,
762 including across renames and moves, and shows only the semantic events.
763
764 **`muse detect-refactor`** is the one that makes engineering managers say "I want
765 this." Onboarding, code review, audit trails — all benefit from a machine-generated
766 classification of structural changes rather than prose commit messages.
767
768 ### On the rename detection
769
770 The rename detection is mathematically exact, not heuristic. It compares
771 `body_hash` values — SHA-256 of the normalized function body (AST, not text).
772 Two functions with the same `body_hash` but different names are definitionally a
773 rename. No line-similarity threshold. No "60% similar" guessing. Certain.
774
775 ### On the multi-language support
776
777 All eleven languages use `tree-sitter` as the parsing backend — the same parser
778 used by GitHub Copilot, VS Code, Neovim, and Zed. This is not a hand-rolled
779 regex. Each language gets a grammar-specific query that extracts the same
780 `SymbolRecord` shape. The core engine is language-agnostic; the language detail
781 lives in `LangSpec` dicts of ~15 lines each.
782
783 ### On "you can't do this in Git"
784
785 Be precise. Git *can* detect renames at the file level (poorly). Git *cannot*
786 detect renames at the function level. Git *cannot* tell you which functions
787 two branches modified. Git *cannot* auto-merge based on whether two changes
788 touched the same *symbol*. Git *cannot* track the history of a function through
789 renames. These are structural limitations, not missing flags.
790
791 ### Suggested YouTube chapter markers
792
793 | Timestamp | Chapter |
794 |-----------|---------|
795 | 0:00 | Intro — what Git gets wrong |
796 | 1:30 | Act 1 — first commit, semantic show |
797 | 3:30 | Act 2 — muse symbols: the full symbol graph |
798 | 6:00 | Act 3 — rename detection via body hash |
799 | 8:30 | Act 4 — cross-file move detection |
800 | 11:00 | Act 5 — symbol-level auto-merge (no conflict) |
801 | 14:00 | Act 6 — symbol-level conflict (genuine disagreement) |
802 | 17:00 | Act 7 — muse symbol-log: the life of a function |
803 | 20:00 | Act 8 — muse detect-refactor: the refactoring report |
804 | 23:00 | Act 9 — eleven languages, one abstraction |
805 | 26:00 | Act 10 — why this matters for real teams |
806 | 29:00 | Act 11 — domain schema and five dimensions |
807 | 31:30 | Outro |