> ## Documentation Index
> Fetch the complete documentation index at: https://musicready.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Model

> The semantic model underlying MRS-S and MRS-Ops.

MRS uses a unified semantic model expressed through two formats: MRS-S (storage) and MRS-Ops (mutation).

See: [`/MRS-Specification-RFC#11-data-model`](/MRS-Specification-RFC#11-data-model)

## Core Type Hierarchy

```
Score
├── meta: Metadata
├── players: List<Player>
├── instruments: List<Instrument>
├── measures: List<Measure> | movements: List<Movement>
├── spans: List<Span>
├── overlays: List<Overlay>?
├── structural-index: StructuralIndex?
└── alternatives: List<Alternative>?
```

## Player-Instrument-Staff Model

MRS uses a three-level model for professional orchestration semantics.

### Player

```
Player
├── id: Identifier
├── name: String
├── instruments: List<InstrumentId>
└── default: InstrumentId
```

A Player represents a performer who may play multiple instruments (doubling).

```clojure theme={null}
(player woodwind-2
  :name "Flute 2 / Piccolo"
  :instruments [flute-2 piccolo]
  :default flute-2)
```

### Instrument

```
Instrument
├── id: Identifier
├── name: String
├── abbr: String
├── family: InstrumentFamily
├── staves: List<Clef>
├── transposition: Interval | none
├── range: [Pitch, Pitch]?
├── kit: List<KitItem>?  ; percussion only
└── staff-connect: ConnectType?
```

An Instrument is a specific sound source with fixed transposition and range.

```clojure theme={null}
(instrument clarinet-bb
  :name "Clarinet in Bb"
  :abbr "Cl."
  :family woodwinds
  :staves [treble]
  :transposition (down M2)
  :range [E3 C7])
```

### Instrument Families

```
woodwinds brass strings percussion keyboards voices choir other
```

## Measure

```
Measure
├── id: UUIDv7              ; Stable identity
├── number: Integer         ; Display number
├── beat-start: Rational    ; Orchestrator-computed
├── time: TimeSignature?    ; Inherits if omitted
├── key: PitchClass?        ; Inherits if omitted
├── mode: Mode?             ; Inherits if omitted
├── tempo: Integer?         ; Inherits if omitted
├── tempo-text: String?
├── rehearsal: String?
├── barline-left: BarlineType?
├── barline-right: BarlineType?
├── directions: List<Direction>
└── content: Map<InstrumentId, InstrumentContent>
```

### Measure Identity

* `:id` — Stable UUIDv7, survives structural changes
* `:number` — Display only, can change on insert/delete
* `:beat-start` — Orchestrator-computed, absolute position

### Attribute Inheritance

| Attribute               | Inherits?           |
| ----------------------- | ------------------- |
| `:time`                 | Yes, until changed  |
| `:key`, `:mode`         | Yes, until changed  |
| `:tempo`, `:tempo-text` | Yes, until changed  |
| `:rehearsal`            | No (single-measure) |
| `:barline-*`            | No (per-measure)    |

## Event

```
Event
├── beat: Rational          ; Position within measure (0-indexed)
├── pitch: PitchExpr        ; Pitch, chord, or rest
├── id: UUIDv7              ; Stable identity
├── dyn: Dynamic?
├── art: Articulation?
├── orn: Ornament?
├── tech: Technique?
├── lyrics: List<LyricSyllable>?
├── grace: Boolean?
├── cue: Boolean?
├── cue-source: InstrumentId?
└── ...other properties
```

### Event Position

Events have structural position (beat within measure). The orchestrator computes absolute position:

```
event.:at = measure.:beat-start + event.beat
```

In MRS-S storage, `:at` is optional (can be computed). In MRS-Ops, agents provide `:beat`; orchestrator computes `:at`.

### Pitch Expression

| Type        | Example        | Description            |
| ----------- | -------------- | ---------------------- |
| Single note | `C4.q`         | C4 quarter note        |
| Chord       | `[C4 E4 G4].q` | C major triad, quarter |
| Rest        | `r.q`          | Quarter rest           |

## Span

```
Span
├── id: UUIDv7
├── type: SpanType
├── from: UUIDv7?           ; Start event (for from/to spans)
├── to: UUIDv7?             ; End event (for from/to spans)
├── events: List<UUIDv7>?   ; Event list (for beams)
├── boundary-entry: Boolean?
├── boundary-exit: Boolean?
└── ...type-specific attributes
```

### Span Types

| Type      | Endpoint Style | Description              |
| --------- | -------------- | ------------------------ |
| `slur`    | from/to        | Phrasing slur            |
| `tie`     | from/to        | Tie between same pitches |
| `hairpin` | from/to        | Crescendo/diminuendo     |
| `beam`    | events list    | Beam grouping            |
| `ottava`  | from/to        | Octave transposition     |
| `pedal`   | from/to        | Piano pedal              |

### Span Immutability

Once created, span endpoints (`:from`, `:to`, `:events`) are immutable. To change endpoints, delete the span and create a new one.

## Identifier Rules

| Type          | Format                      | Example                     |
| ------------- | --------------------------- | --------------------------- |
| UUID          | UUIDv7                      | `#uuid "018c3f40-0001-..."` |
| Instrument ID | `[a-z][a-z0-9-]*`           | `clarinet-bb`, `flute-1`    |
| Player ID     | `[a-z][a-z0-9-]*`           | `woodwind-2`                |
| Voice ID      | `v1`-`v4` or `:rh`/`:lh`    | `v1`, `:rh`                 |
| Tmp-ID        | String starting with letter | `"e1"`, `"span-a"`          |

## Rational Numbers

All temporal positions use exact rationals:

```
Canonical forms:
  0, 1, 2, ...       ; Integers
  2+1/2              ; Two and a half
  0+1/3              ; One third
  3+3/4              ; Three and three quarters

NOT permitted:
  2.5                ; Decimal
  0.333              ; Decimal
```

Implementations MUST treat rationals as exact; no floating-point approximation.

## Voices and Layers

### Voices

Independent melodic/rhythmic streams within an instrument:

* `v1` through `v4` for single-staff instruments
* `:rh`/`:lh` for keyboard instruments (then `v1`, `v2` within each)

### Layers

Same-rhythm sub-structure within a voice:

```clojure theme={null}
(v1
  (layer 1
    (: 0 C4.q :id #uuid "...") (: 1 D4.q :id #uuid "..."))
  (layer 2
    (: 0 E4.q :id #uuid "...") (: 1 F4.q :id #uuid "...")))
```

## HarmonyPlan Layer

The HarmonyPlan is an embedded optional layer for chord symbols and harmonic structure:

```clojure theme={null}
(harmony-plan
  (region :measures #uuid "..." #uuid "..."
    (chord :beat 0 :symbol Cm :function i)
    (chord :beat 2 :symbol Fm :function iv)))
```

This enables:

* Composing harmony before notes
* Validating notes against harmony
* Extracting harmonic context for agents
