# 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\]** ``` text $ ls .muse ``` **\[ENTER.\]** ``` text 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\]** ``` text $ cat .muse/HEAD ``` ``` text ref: refs/heads/main ``` ``` text $ cat .muse/refs/heads/main ``` ``` text 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\]** ``` text $ cat .muse/repo.json ``` ``` json { "repo_id": "sha256:2a7766...", "domain": "code", "schema_version": 1, "muse_version": "0.2.1rc4" } ``` ``` text $ cat .muse/config.toml ``` ``` 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\]** ``` text $ 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\]** ``` text .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\]** ``` text $ muse read-commit sha256:d51cb8... --json ``` **\[SCREEN --- JSON, key fields highlighted as spoken\]** ``` json { "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\]** ``` text $ muse read-snapshot sha256:25ed18... --json ``` ``` 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\]** ``` text $ muse cat-object sha256:e79677... ``` ``` text 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\]** ``` text $ muse verify --json ``` ``` 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.