build-something-weird-with-muse.md markdown
370 lines 11.0 KB
Raw
sha256:5472be4fece32b606c308fad9d57295ce327955fb2b87b8beec6ea1626050473 Add published YouTube URL to Episode 00 Sonnet 5 11 hours ago

Episode 22 --- Build Something Weird With Muse

Working YouTube title:
I Built a Chess Domain From Scratch to Prove I Wasn't Lying

Thumbnail thought:
conflict_type: "variation".

Target runtime: ~10:00


[0:00--0:30] COLD OPEN

[CAMERA --- Episode 21's closing line, on screen: "something nobody asked Muse to do."]

GABRIEL:

Twenty-one episodes. Code, MIDI, identity, todo lists, CRDTs, mists, agents, the wire protocol, security. Every one of those domains either already existed or got built specifically to teach a concept. This one's different. I'm building a domain I made up five minutes before recording, live, right now, and I'm not touching a single line of the six-method protocol to make it work.

[TITLE CARD --- slower this time]

BUILD SOMETHING WEIRD WITH MUSE

[Music enters --- the season's theme, but fuller.]


[0:30--1:20] THE DOMAIN: CHESS

[CAMERA]

Not code. Not music. A chess game --- one file, game.moves, one SAN move per line. e4. Nf3. Bc4. Ordered. Position matters. And here's the thing that made me pick it: chess already has a word for "two people made different decisions from the same position." It's called a variation. If Muse's merge conflicts are real, a chess domain shouldn't need to invent a new concept for that --- it should just be able to use the word chess players already use.


[1:20--2:40] THE SIX METHODS, FOR REAL, ONE MORE TIME

[TERMINAL]

$ muse code cat "muse/plugins/chess/plugin.py::ChessPlugin" --all | head -30

GABRIEL VO:

snapshot. diff --- Python's own difflib.SequenceMatcher, the same LCS algorithm Episode 05 promised any sequence domain could use, producing real InsertOp/DeleteOp entries at real integer positions. merge --- three-way, walk the shared prefix both branches still agree on, and if both sides played a different next move, that's not resolvable by any silent rule. drift, apply, schema. Same six. No new engine code. No changes to merge_engine.py, checkout.py, or the CLI.

$ python3 -m pytest tests/test_chess_plugin.py -v
13 passed

GABRIEL:

Thirteen tests, written before I ever touched the real CLI, exactly the discipline Episode 06 established. Register it in one dict entry.


[2:40--3:20] THE OPENING

[TERMINAL]

$ muse-dev init --domain chess
$ echo -e "e4\ne5" > game.moves
$ muse-dev commit -m "1. e4 e5 -- the open game" --sign

GABRIEL VO:

muse-dev, not muse --- this plugin isn't in a published release yet, it's dev-branch source I wrote an hour ago. That distinction is Episode 13's rule, still holding, still mattering.


[3:20--4:30] TWO REAL OPENINGS, ONE SHARED POSITION

[TERMINAL]

$ muse-dev checkout -b variation/italian --intent "explore 3. Bc4"
$ echo -e "e4\ne5\nBc4" > game.moves && muse-dev commit -m "3. Bc4" --sign

$ muse-dev switch main
$ muse-dev checkout -b variation/spanish --intent "explore 3. Nf3"
$ echo -e "e4\ne5\nNf3" > game.moves && muse-dev commit -m "3. Nf3" --sign

GABRIEL:

Two branches. Same first two moves. Different third move. Real chess theory --- the Italian Game against the road toward the Ruy Lopez --- expressed as two muse branches off the same commit.


[4:30--5:20] THE STRUCTURED DELTA, POSITION-ADDRESSED

[TERMINAL]

$ muse-dev read variation/italian --json --manifest | jq .structured_delta
{
  "domain": "chess",
  "ops": [{
    "op": "patch", "address": "game.moves",
    "child_ops": [{
      "op": "insert", "position": 2,
      "content_summary": "played move 3: Bc4"
    }]
  }]
}

GABRIEL VO:

Position 2. Not "line 3 changed." An actual insert at an actual index in an actual ordered sequence --- indistinguishable in shape from a MIDI note-on event at a beat, or a code symbol insertion. Same infrastructure, completely different subject matter.


[5:20--6:00] THE EASY MERGE

[TERMINAL]

$ muse-dev switch main
$ muse-dev merge variation/spanish
status: fast_forward

GABRIEL:

Nothing diverged yet on main's side --- clean, instant, exactly what you'd want.


[6:00--7:20] THE REAL CONFLICT

[TERMINAL]

$ muse-dev merge variation/italian
{
  "status": "conflict",
  "conflict_records": [{
    "path": "game.moves",
    "conflict_type": "variation",
    "ours_summary": "ours continues: Nf3...",
    "theirs_summary": "theirs continues: Bc4..."
  }]
}

[beat, GABRIEL reading conflict_type: "variation" out loud]

GABRIEL:

I didn't write "variation" anywhere in the merge engine. I wrote it once, in my own plugin's merge() method, as the label for exactly this situation. The core engine had no idea what a chess variation was. It didn't need to. It just needed a plugin that could describe its own domain honestly --- and the conflict-record taxonomy from Episode 08 was already generic enough to carry it.

$ cat game.moves
e4
e5
<<<<<<< main [inserted]
Nf3
||||||| base
======= variation/italian [inserted]
Bc4
>>>>>>> end conflict

GABRIEL VO:

Real conflict markers. In a chess game. Nobody designed for this specific case --- it fell out of the same machinery Episode 08 built for source code.


[7:20--8:00] THE RESOLUTION THAT ISN'T A RESOLUTION

[CAMERA]

Here's the part that only makes sense for this domain. I'm not picking a winner.

$ muse-dev merge --abort
$ muse-dev branch
main               -- (no intent)
variation/italian  -- explore 3. Bc4, the Italian Game
variation/spanish  -- explore 3. Nf3 heading toward the Ruy Lopez

GABRIEL:

Both lines survive, permanently, as named branches. A code conflict usually wants one true resolution. A chess repertoire wants both --- an opening book is a tree, not a line. The "conflict" wasn't a problem to solve. It was correct information: these two things are different, and that's fine.


[8:00--8:40] REGISTERED, FOR REAL

[TERMINAL]

$ muse-dev domains
["chess", "code", "identity", "mist", "scaffold", "social", "timeline", "todo"]

GABRIEL VO:

Alphabetized right next to code. Not a demo mode. Not a special flag. A domain, in the actual registry, committed and pushed to muse's real dev branch on every environment, the same way every other domain in this list got there.


[8:40--9:40] WHAT THIS EPISODE WAS ACTUALLY FOR

[CAMERA]

Look back at the whole season. Episode 00 made a claim: Git is one point in a much larger design space, and the parts of it that are actually timeless --- content addressing, a commit DAG, branches, three-way merge --- can teach an arbitrary state space if you give them six methods. Every episode since has been testing that claim against something real, including against the season's own bugs. This episode is the control group. Nobody needed a chess VCS. That's exactly why building one, correctly, in an afternoon, with thirteen passing tests and a genuine domain-specific conflict type, is the actual proof.


[9:40--10:00] OUT

[TERMINAL --- the season's very first terminal prompt from Episode 00, side by side with this episode's last one]

GABRIEL VO:

Twenty-two episodes. A dozen real bugs, filed, triaged, and in one case, already known before I found it. A wire format I tried to break and couldn't. A chess domain that didn't exist an hour before this recording. That's the whole pitch, end to end.

[beat]

Build something. See what happens.

[CUT TO BLACK, hold longer than usual]

musehub.ai


Production Notes

Episode 22 is the finale --- pacing should feel unhurried compared to the rest of the season, especially the 8:40 callback to Episode 00. This is the one episode where finding zero bugs is not just acceptable but the correct outcome: the entire point is demonstrating that the architecture holds up under a genuinely novel domain without needing any core-engine changes. Don't manufacture a finding here.

The "I Didn't Write conflict_type Into the Engine" Beat Is the Thesis

6:00–7:20 is the single most important moment in the episode, maybe the season: the word "variation" originates entirely in ChessPlugin.merge(), a ~200-line file with zero access to or knowledge of merge_engine.py's internals beyond the ConflictRecord dataclass's generic fields. Make sure the script's delivery treats this as the payoff it is, not a minor detail.

The Non-Resolution Is Not A Cop-Out

7:20's "both branches survive" beat needs to land as a correct domain-specific choice, not an evasion of doing the merge properly. Chess opening theory is genuinely a tree of permanently-valid alternatives — contrast explicitly with how code conflicts (Episode 08) and MIDI note conflicts (Episode 11) did need a single winner, so the audience understands this is the domain's own logic asserting itself, not the plugin dodging work.

Everything Here Is Real

The chess plugin (muse/plugins/chess/plugin.py), its 13 tests, and the registry change are real commits on muse's actual dev branch, pushed to local/staging/production alongside every other commit this season made. Every command in this episode was run against the real muse-dev CLI, not simulated. Re-run make-chess-episode22-demo.sh at record time — if the plugin has since gone through a real release and become available via plain muse, update the script and this production note accordingly rather than silently leaving the muse-dev framing stale.

The Seed

The viewer arrives having watched 21 episodes thinking:

Okay, I believe code and MIDI and identity graphs all use the same six methods. That's still three domains someone already had a reason to build.

They should leave the season thinking:

He built a fourth one, for a reason that amounts to "why not," and it took an afternoon, and the hardest part — the part that would prove the whole architecture was fake if it didn't work — worked on the first real test. What would I build?

That question is the actual final shot of the season. Everything after it is up to the viewer.

File History 1 commit
sha256:5472be4fece32b606c308fad9d57295ce327955fb2b87b8beec6ea1626050473 Add published YouTube URL to Episode 00 Sonnet 5 11 hours ago