inside-a-muse-repository.md markdown
462 lines 10.7 KB
Raw
sha256:5472be4fece32b606c308fad9d57295ce327955fb2b87b8beec6ea1626050473 Add published YouTube URL to Episode 00 Sonnet 5 7 hours ago

Episode 02 --- Inside a Muse Repository

Working YouTube title:
What's Actually Inside .muse/?

Thumbnail thought:
no magic. just files.

Target runtime: ~7:30


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

[CAMERA --- exact terminal Episode 01 ended on. hello-muse, main branch, five commits deep.]

GABRIEL:

Last episode I ran the whole workflow and never once told you what .muse actually is.

[beat]

Let's fix that.

[TITLE CARD --- fast]

INSIDE A MUSE REPOSITORY

[Music enters.]


[0:20--1:10] THE SHAPE OF THE DIRECTORY

[TERMINAL]

$ ls .muse

[ENTER.]

HEAD  cache  config.toml  logs  objects  refs  remotes  repo.json  shelf  tags

GABRIEL VO:

Ten entries. That's it. That's the entire engine underneath everything we ran last episode.

[CAMERA --- point at each name as it's said]

HEAD and refs are pointers.

objects is where content actually lives.

repo.json and config.toml are identity and configuration.

cache, logs, shelf, tags, remotes are exactly what they sound like --- nothing sinister in any of them.

[beat]

No proprietary binary format. No database you need a special tool to open. Every one of these is something cat can read.


[1:10--1:55] HEAD AND REFS

[TERMINAL]

$ cat .muse/HEAD
ref: refs/heads/main
$ cat .muse/refs/heads/main
sha256:d51cb8...

GABRIEL:

HEAD doesn't point at a commit. It points at a name.

That name --- main --- points at a commit.

[SCREEN --- simple arrow diagram: HEAD → refs/heads/main → commit]

That indirection is the entire mechanism behind checkout and branch. Moving to a different branch is just repointing one text file at a different ref.

[beat]

Committing on that branch is just overwriting one line in another text file with a new hash.

That's it. That's branching.


[1:55--2:35] REPO IDENTITY AND CONFIG

[TERMINAL]

$ cat .muse/repo.json
{
  "repo_id": "sha256:2a7766...",
  "domain": "code",
  "schema_version": 1,
  "muse_version": "0.2.1rc4"
}
$ cat .muse/config.toml
[user]
type = "human"

[hub]
url = "https://localhost:1337"

[remotes.local]
url = "https://localhost:1337/gabriel/hello-muse"

GABRIEL VO:

repo.json answers one question: what kind of repository is this.

We picked code when we ran muse init. That single field is why hello.py got treated as source, not as an opaque blob --- and it's why a MIDI file would have been treated completely differently.

[CAMERA]

We'll spend an entire episode on domains later. For now, just notice: the domain isn't inferred, and it isn't hardcoded into the engine. It's one string, sitting in a JSON file, that you can read right now.


[2:35--3:20] INSIDE OBJECTS/

[TERMINAL]

$ find .muse/objects -type f | wc -l
      13
$ find .muse/objects/sha256 -maxdepth 1
.muse/objects/sha256/09
.muse/objects/sha256/25
.muse/objects/sha256/47
.muse/objects/sha256/55
.muse/objects/sha256/72
.muse/objects/sha256/80
...

GABRIEL:

Thirteen objects for five commits. More objects than commits, because commits, snapshots, and file contents are all stored as separate objects.

[beat]

And notice the folder names. Two hex characters, then a subfolder with the rest of the hash.

[SCREEN --- full path highlighted]

.muse/objects/sha256/e7/967762d936553ad4f8264b72d1b0d7390ee8276a0cec0a6e3dd3d4ad33d20c

That's not decoration. That is the object's address. The filename is the SHA-256 hash of the thing inside it.

[CAMERA]

Why that matters --- really matters, not just "feels tidy" --- is next episode. Today we're just confirming it's real, and it's just files on disk.


[3:20--4:05] READ A COMMIT

[TERMINAL]

$ muse read-commit sha256:d51cb8... --json

[SCREEN --- JSON, key fields highlighted as spoken]

{
  "commit_id": "sha256:d51cb8...",
  "message": "Merge branch 'feature/farewell' into main",
  "snapshot_id": "sha256:25ed18...",
  "parent_commit_id": "sha256:e5e7da...",
  "parent2_commit_id": "sha256:09218e...",
  "author": "gabriel",
  "agent_id": "",
  "model_id": "",
  "signature": ""
}

GABRIEL VO:

A commit is not the content. A commit is a record --- a message, an author, a pointer to exactly one snapshot, and pointers to its parents.

[beat]

Look at parent2_commit_id. Most commits only have one parent. This one has two --- because this is our merge commit. Both branches' history, right there as two plain hash strings.

[CAMERA --- slow down here]

And look at these three fields. agent_id. model_id. signature.

All empty. Because I typed this commit myself, by hand, with no signing key configured.

[beat]

They're not empty because the feature doesn't exist. They're empty because nobody asked for it yet. That's an entire episode, coming up.


[4:05--4:45] READ A SNAPSHOT

[TERMINAL]

$ muse read-snapshot sha256:25ed18... --json
{
  "snapshot_id": "sha256:25ed18...",
  "file_count": 1,
  "manifest": {
    "hello.py": "sha256:e79677..."
  }
}

GABRIEL:

If the commit is the record, the snapshot is the state.

[beat]

One file in our case, but the shape doesn't change at ten files or ten thousand. A snapshot is just a map: path, to the hash of that path's content.

Nothing here knows or cares that hello.py is Python. That distinction lives one layer up, in the domain. Down here, it's just a name and an address.


[4:45--5:20] READ THE ACTUAL BYTES

[TERMINAL]

$ muse cat-object sha256:e79677...
def greet(name):
    return f"Hey there, {name}!"

if __name__ == "__main__":
    print(greet("world"))

def farewell(name):
    return f"See you, {name}!"

GABRIEL VO:

That's it. That's the object. Not a wrapper, not a container format --- the literal file, exactly as it existed at that commit, both merged changes present.

[CAMERA]

Commit, to snapshot, to object, to bytes. Every arrow in that chain is just a hash lookup.


[5:20--5:55] VERIFY

[TERMINAL]

$ muse verify --json
{
  "refs_checked": 3,
  "commits_checked": 5,
  "snapshots_checked": 5,
  "objects_checked": 13,
  "all_ok": true,
  "failures": []
}

GABRIEL:

Every ref, every commit, every snapshot, every object --- rehashed and checked against its own filename.

[beat]

If one byte of hello.py had flipped on disk since we committed it, this would fail, loudly, and tell us exactly which object.

[CAMERA]

That's not a feature bolted on top. That's a direct consequence of everything being named after its own content.


[5:55--6:30] THE POINT

[CAMERA]

There is no black box in here.

[beat]

Ten folders and files. A pointer chain you can trace by hand. Records you can print with cat. Content you can read directly off disk.

[ON SCREEN]

IT'S JUST FILES. THAT'S THE WHOLE TRICK.

Everything from Episode 01 --- every branch, every merge, every push --- was built entirely out of the ten things you just looked at.


[6:30--7:10] OUT

[TERMINAL --- back at the objects/ listing from earlier]

GABRIEL VO:

We kept saying the folder name is the hash, and moving on.

[beat]

Next episode, we stop moving on. Why SHA-256, specifically. What a snapshot really buys you that a plain file tree doesn't. And why a commit DAG --- not a list, not a tree, a DAG --- is the shape that makes merging even possible.

[CAMERA.]

Same repository. One layer deeper.

[CUT TO BLACK]

musehub.ai


Production Notes

Episode 02 should feel like opening the hood on a car you already drove. The viewer trusted the machine enough to use it in Episode 01; this episode is the reward for that trust, not a prerequisite for it. Nothing here should feel like homework.

Opening

No recap of what a commit or a branch is conceptually --- Episode 01 already demonstrated that behaviorally. Open directly on the same terminal, same repo, and go straight to ls .muse. The cold open is the first shot of the episode's actual content.

Everything Shown Must Be cat-able

This is the episode's one hard rule: every artifact shown on screen must be something the viewer could open themselves with cat, ls, or a muse read-* command, on the exact repository Episode 01 built. No diagrams standing in for real output. If a concept can't be shown as real bytes on real disk, it belongs in a later episode, not this one.

Plant Three Seeds, Pay Off None of Them

This episode should visibly gesture at three things it deliberately does not explain yet:

  • The empty agent_id / model_id / signature fields --- Episode 04.
  • The domain field in repo.json determining how content is interpreted --- Episode 05 and 06.
  • The fanout folder name literally being a hash --- Episode 03, immediately next.

Naming the tease explicitly on screen (as dialogue, not just a visual) is deliberate. It tells the viewer these aren't loose threads being forgotten, they're a released trailer for what's coming.

Production Style

Slower and calmer than Episode 01. Episode 01's energy was a stopwatch; this episode's energy is a flashlight. Let shots of raw JSON and file contents sit on screen a beat longer than feels necessary in the edit --- the viewer needs time to actually read what's there, not just be told it exists.

The Seed

The viewer arrives thinking:

.muse is probably some database or binary format I'll never actually understand.

They should leave thinking:

Wait --- that's a hash of a hash of a hash. Why SHA-256 specifically, and why does chaining it like that actually matter?

That's Episode 03, and the final shot should point straight at the objects/ fanout folder that started the question.

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