README.md
markdown
| 1 | # Muse |
| 2 | |
| 3 | > **A domain-agnostic version control system for multidimensional state.** |
| 4 | |
| 5 | Git works on text because text is one-dimensional — a sequence of lines. Diffs are additions and deletions to that sequence. |
| 6 | |
| 7 | Muse works on *any* state space where a "change" is a delta across multiple axes simultaneously. Music is the first domain. It is not the definition. |
| 8 | |
| 9 | --- |
| 10 | |
| 11 | ## The Core Abstraction |
| 12 | |
| 13 | Strip Muse down to its invariants and what remains is: |
| 14 | |
| 15 | ``` |
| 16 | State = a serializable, content-addressed snapshot of any multidimensional space |
| 17 | Commit = a named delta from a parent state, recorded in a DAG |
| 18 | Branch = a divergent line of intent forked from a shared ancestor |
| 19 | Merge = three-way reconciliation of two divergent state lines against a common base |
| 20 | Drift = the gap between committed state and live state |
| 21 | Checkout = deterministic reconstruction of any historical state from the DAG |
| 22 | Lineage = the causal chain from root to any commit |
| 23 | ``` |
| 24 | |
| 25 | None of those definitions contain the word "music." |
| 26 | |
| 27 | --- |
| 28 | |
| 29 | ## Plugin Architecture |
| 30 | |
| 31 | A domain plugin implements five interfaces. Muse provides the rest — the DAG engine, content-addressed object store, branching, lineage walking, topological log graph, and merge base finder. |
| 32 | |
| 33 | ```python |
| 34 | class MuseDomainPlugin(Protocol): |
| 35 | def snapshot(self, live_state: LiveState) -> StateSnapshot: |
| 36 | """Capture current live state as a serializable, hashable snapshot.""" |
| 37 | |
| 38 | def diff(self, base: StateSnapshot, target: StateSnapshot) -> StateDelta: |
| 39 | """Compute the minimal delta between two snapshots.""" |
| 40 | |
| 41 | def merge( |
| 42 | self, |
| 43 | base: StateSnapshot, |
| 44 | left: StateSnapshot, |
| 45 | right: StateSnapshot, |
| 46 | ) -> MergeResult: |
| 47 | """Three-way merge. Return merged snapshot + conflict report.""" |
| 48 | |
| 49 | def drift( |
| 50 | self, |
| 51 | committed: StateSnapshot, |
| 52 | live: LiveState, |
| 53 | ) -> DriftReport: |
| 54 | """Compare committed state against current live state.""" |
| 55 | |
| 56 | def apply(self, delta: StateDelta, live_state: LiveState) -> LiveState: |
| 57 | """Apply a delta to produce a new live state (checkout execution).""" |
| 58 | ``` |
| 59 | |
| 60 | The music plugin — the reference implementation — implements these five interfaces for MIDI state: notes, velocities, controller events, pitch bends, aftertouch, and region-to-track mapping. Every other domain is a new plugin. |
| 61 | |
| 62 | --- |
| 63 | |
| 64 | ## Music — The Reference Implementation |
| 65 | |
| 66 | Music is the domain that proved the abstraction. State is a snapshot of notes and controller events per region, with track routing. Diff is note matching and event diffing. Merge is three-way reconciliation across MIDI axes. Drift compares the committed snapshot against the live DAW state. Checkout executes a replay plan against the state store. |
| 67 | |
| 68 | The music plugin ships with a full CLI — 70+ subcommands covering every VCS primitive plus music-domain analysis: |
| 69 | |
| 70 | ```bash |
| 71 | # Initialize a Muse repository |
| 72 | muse init |
| 73 | |
| 74 | # Stage and commit the current working tree |
| 75 | muse commit -m "Add verse melody" |
| 76 | |
| 77 | # Create and switch to a new branch |
| 78 | muse checkout -b feature/chorus |
| 79 | |
| 80 | # View commit history as an ASCII graph |
| 81 | muse log --graph |
| 82 | |
| 83 | # Show uncommitted changes vs HEAD |
| 84 | muse status |
| 85 | |
| 86 | # Three-way merge a branch |
| 87 | muse merge feature/chorus |
| 88 | |
| 89 | # Cherry-pick a specific commit |
| 90 | muse cherry-pick <commit-id> |
| 91 | |
| 92 | # Binary-search for a regression |
| 93 | muse bisect start --bad HEAD --good <commit-id> |
| 94 | |
| 95 | # Analyse rhythmic groove drift across history |
| 96 | muse groove-check |
| 97 | |
| 98 | # Compare emotion vectors between two commits |
| 99 | muse emotion-diff <commit-a> <commit-b> |
| 100 | ``` |
| 101 | |
| 102 | Run `muse --help` for the full command list. |
| 103 | |
| 104 | --- |
| 105 | |
| 106 | ## Domain Instantiations |
| 107 | |
| 108 | ### Music *(reference implementation)* |
| 109 | MIDI state across notes, velocities, controller events, pitch bends, and aftertouch. Three-way merge reconciles divergent takes. Drift detection compares the committed snapshot against the live DAW. **Already ships with full DAG, branching, three-way merge, and E2E tests.** |
| 110 | |
| 111 | ### Scientific Simulation *(planned)* |
| 112 | A climate model is a multidimensional state space: temperature, pressure, humidity, ocean current, ice coverage at every grid point. Commit a named checkpoint. Branch to explore a parameter variation. Merge two teams' adjustments against a common baseline run. Drift detection flags when a running simulation has diverged from its last committed checkpoint. |
| 113 | |
| 114 | ### Genomics *(planned)* |
| 115 | A genome under CRISPR editing is a high-dimensional sequence state. Each editing session is a commit. Alternate intervention strategies are branches. When two research teams converge on the same baseline organism and apply different edits, merge reconciles those edit sets against the common ancestor genome. The Muse DAG becomes the provenance record of every edit. |
| 116 | |
| 117 | ### 3D Spatial Design *(planned)* |
| 118 | Architecture, urban planning, game world construction. Branch to explore "what if we moved the load-bearing wall." Merge the structural engineer's changes and the lighting consultant's changes against the architect's baseline. Drift detection surfaces the delta between the committed design and the as-built state. |
| 119 | |
| 120 | ### Spacetime *(theoretical)* |
| 121 | A spacetime plugin models state as a configuration of matter-energy distribution across a coordinate grid. A commit is a named configuration at a set of coordinates. A branch is a counterfactual — what would the state space look like if this mass had been positioned differently at T₀. |
| 122 | |
| 123 | This is exactly what large-scale physics simulation does, without the version control semantics. Adding Muse semantics — content-addressed states, causal lineage, merge — makes simulation runs composable in a way they currently are not. Two simulations that share a common initialization can be merged or compared with the same rigor that two branches of a codebase can. |
| 124 | |
| 125 | Whether this scales to actual spacetime is a question for physics. Whether it applies to spacetime *simulation* is just engineering. |
| 126 | |
| 127 | --- |
| 128 | |
| 129 | ## Agent Collaboration |
| 130 | |
| 131 | Muse's most transformative application is **shared persistent memory for teams of collaborating agents**. |
| 132 | |
| 133 | Without a shared state store, collaborating agents are stateless with respect to each other. Each agent knows what it has done; none knows what the others have committed, branched, or abandoned. There is no canonical record of what has happened. |
| 134 | |
| 135 | Muse solves this at the protocol level. Every agent in a tree sees the same DAG. An agent can: |
| 136 | |
| 137 | - Read the full commit history to understand what has been tried |
| 138 | - Branch from any commit to explore an alternative without polluting the main line |
| 139 | - Commit its work with a message that becomes part of the permanent record |
| 140 | - Merge its branch back, with three-way reconciliation handling conflicts |
| 141 | - Check out any historical state to understand what the system looked like at any prior point |
| 142 | |
| 143 | This is the missing primitive for agent collaboration — not a message queue, not a shared database, but a **versioned, branchable, mergeable, content-addressed state store** that every agent in the tree can read and write coherently. |
| 144 | |
| 145 | A tree of musical agents with distinct cognitive identities, collaborating over a shared Muse repository: |
| 146 | |
| 147 | ``` |
| 148 | Composer (root coordinator) |
| 149 | ├── Bach agent — commits fugue subject on branch counterpoint/main |
| 150 | ├── Jimi Hendrix agent — commits lead response on branch lead/main |
| 151 | └── Miles Davis agent — commits harmonic reframing on branch modal/main |
| 152 | ``` |
| 153 | |
| 154 | The Composer runs a three-way merge. Conflicts are real musical conflicts — two agents wrote to the same beat, the same frequency range, the same structural moment. The Composer's cognitive architecture resolves them. |
| 155 | |
| 156 | This is not AI generating music from a prompt. This is structured improvisation between agents with distinct cognitive identities, mediated by a version control system. |
| 157 | |
| 158 | --- |
| 159 | |
| 160 | ## Repository Structure |
| 161 | |
| 162 | ``` |
| 163 | muse/ |
| 164 | domain.py — MuseDomainPlugin Protocol + shared type definitions |
| 165 | core/ — domain-agnostic VCS engine |
| 166 | store.py — file-based commit/snapshot store (no external DB) |
| 167 | repo.py — repository detection and management |
| 168 | snapshot.py — content-addressed snapshot computation |
| 169 | object_store.py — SHA-256 blob storage under .muse/objects/ |
| 170 | merge_engine.py — three-way merge state machine |
| 171 | errors.py — exit codes and error primitives |
| 172 | plugins/ |
| 173 | music/ — music domain plugin (reference implementation) |
| 174 | plugin.py — implements MuseDomainPlugin for MIDI state |
| 175 | cli/ |
| 176 | app.py — Typer application root |
| 177 | commands/ — 70+ subcommands |
| 178 | |
| 179 | tests/ |
| 180 | test_muse_*.py — unit/integration tests |
| 181 | muse_cli/ — CLI-level tests |
| 182 | e2e/ — end-to-end tests |
| 183 | |
| 184 | docs/ |
| 185 | architecture/ — canonical architecture references |
| 186 | protocol/ — language-agnostic protocol specs |
| 187 | reference/ — .museattributes format and attribute references |
| 188 | ``` |
| 189 | |
| 190 | --- |
| 191 | |
| 192 | ## Installation |
| 193 | |
| 194 | ```bash |
| 195 | pip install muse-vcs |
| 196 | ``` |
| 197 | |
| 198 | Core dependencies: |
| 199 | |
| 200 | - Python 3.11+ |
| 201 | - Typer (CLI) |
| 202 | - mido (MIDI parsing, music plugin only) |
| 203 | - toml |
| 204 | |
| 205 | No database required. Muse stores all state in the `.muse/` directory — objects, snapshots, commits, refs — exactly like Git stores state in `.git/`. |
| 206 | |
| 207 | --- |
| 208 | |
| 209 | ## Documentation |
| 210 | |
| 211 | - [Architecture](docs/architecture/muse-vcs.md) — full technical design |
| 212 | - [E2E Demo](docs/architecture/muse-e2e-demo.md) — step-by-step lifecycle walkthrough |
| 213 | - [Protocol Spec](docs/protocol/muse-protocol.md) — language-agnostic protocol definition |
| 214 | - [Variation Spec](docs/protocol/muse-variation-spec.md) — variation UX and wire contract |
| 215 | - [`.museattributes` Reference](docs/reference/muse-attributes.md) — per-repo merge strategies |
| 216 | |
| 217 | --- |
| 218 | |
| 219 | ## Origin |
| 220 | |
| 221 | Muse began as the version control subsystem of [Maestro](https://github.com/tellurstori/maestro), the AI music composition backend powering the [Stori DAW](https://tellurstori.com). The music domain proved the abstraction. Muse v2 generalizes it. |
| 222 | |
| 223 | *Built from the couch. March 2026.* |