tour-de-force-code.md
markdown
| 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 | |