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

# Validation Rules

> Progressive validation pipeline for MRS-Ops operations.

MRS uses progressive validation to catch errors before state mutation, provide specific feedback, and enable partial application when appropriate.

See: [`/MRS-Specification-RFC#13-progressive-validation`](/MRS-Specification-RFC#13-progressive-validation)

## Validation Pipeline

```
┌─────────────┐   ┌─────────────┐   ┌─────────────┐   ┌─────────────┐
│   Syntax    │ → │ References  │ → │ Permissions │ → │  Musical    │
│ Validation  │   │ Validation  │   │ Validation  │   │  Rules      │
└─────────────┘   └─────────────┘   └─────────────┘   └─────────────┘
```

Operations are validated in stages. Each stage must pass before proceeding to the next.

## Stage 1: Syntax Validation

Verifies operations are well-formed.

| Check           | Description                                             |
| --------------- | ------------------------------------------------------- |
| Operation type  | Recognized operation (create-event, update-event, etc.) |
| Required fields | All required fields present                             |
| Field types     | Values have correct types                               |
| Rational format | Beat positions are valid rationals                      |

### Syntax Errors

| Code    | Description               |
| ------- | ------------------------- |
| SYN-001 | Unknown operation type    |
| SYN-002 | Missing required field    |
| SYN-003 | Invalid field type        |
| SYN-004 | Malformed rational number |
| SYN-005 | Invalid tmp-id format     |

## Stage 2: Reference Validation

Verifies all references are valid.

| Check             | Description                            |
| ----------------- | -------------------------------------- |
| UUID existence    | Referenced UUIDs exist in source       |
| Tmp-id uniqueness | All tmp-ids unique within envelope     |
| Cross-references  | Ops can reference each other's tmp-ids |
| Measure reference | Target measure exists                  |

### Reference Errors

| Code    | Description                       |
| ------- | --------------------------------- |
| REF-001 | UUID not found in source          |
| REF-002 | Duplicate tmp-id                  |
| REF-003 | Tmp-id referenced but not defined |
| REF-004 | Circular reference                |

## Stage 3: Permission Validation

Verifies operations are within granted permissions.

| Check             | Description                    |
| ----------------- | ------------------------------ |
| Operation allowed | Op type in `:allowed-ops` list |
| Lane permission   | Content within granted lanes   |
| Scope bounds      | Targets within granted scope   |
| Lock respect      | Not modifying locked lanes     |

### Permission Errors

| Code     | Description                |
| -------- | -------------------------- |
| PERM-001 | Operation type not allowed |
| PERM-002 | Lane not granted           |
| PERM-003 | Outside granted scope      |
| PERM-004 | Modifying locked lane      |

## Stage 4: Musical Rule Validation

Verifies musical constraints are satisfied.

### Structural Rules

| Rule       | Severity | Description                         |
| ---------- | -------- | ----------------------------------- |
| STRUCT-001 | ERROR    | Would create duplicate UUID         |
| STRUCT-002 | ERROR    | Invalid measure number              |
| STRUCT-003 | ERROR    | Beat position out of bounds         |
| STRUCT-004 | ERROR    | Duration overflow (exceeds measure) |
| STRUCT-005 | WARNING  | Gap in measure numbering            |

### Musical Rules

| Rule      | Severity | Description                         |
| --------- | -------- | ----------------------------------- |
| MUSIC-001 | ERROR    | Tie connects different pitches      |
| MUSIC-002 | ERROR    | Span endpoints reversed (from > to) |
| MUSIC-003 | WARNING  | Pitch out of instrument range       |
| MUSIC-004 | WARNING  | Parallel fifths/octaves             |
| MUSIC-005 | WARNING  | Voice crossing                      |
| MUSIC-006 | WARNING  | Large melodic leap (> octave)       |

### Constraint Rules

| Rule      | Severity | Description                        |
| --------- | -------- | ---------------------------------- |
| CONST-001 | ERROR    | Violates range constraint          |
| CONST-002 | WARNING  | Violates avoid constraint          |
| CONST-003 | INFO     | Does not satisfy prefer constraint |

## Severity Levels

| Level   | Meaning                         | Action             |
| ------- | ------------------------------- | ------------------ |
| ERROR   | Invalid; cannot apply           | Operation rejected |
| WARNING | Suspicious; may be intentional  | Apply with warning |
| INFO    | Informational; style suggestion | Apply; log info    |

## Validation Results

### All Pass

```clojure theme={null}
(validation-result
  :status passed
  :warnings []
  :info [])
```

### Errors Found

```clojure theme={null}
(validation-result
  :status rejected
  :stage permissions
  :errors
    ((error :op 3 :code PERM-001 
            :message "Operation 'create-measure' not in allowed-ops"
            :detail (:allowed [create-event update-event delete-event]))))
```

### Warnings Only

```clojure theme={null}
(validation-result
  :status passed-with-warnings
  :warnings
    ((warning :op 2 :code MUSIC-003
              :message "Pitch D7 exceeds clarinet-bb range [E3 C7]")))
```

## Constraint Validation

Constraints from the Working Set Envelope are checked in Stage 4.

### Range Constraint

```clojure theme={null}
(range clarinet-bb E3 C7)
```

Checks all pitches for clarinet-bb are within E3-C7.

### Avoid Constraint

```clojure theme={null}
(avoid parallel-fifths violin-1)
```

Checks for parallel fifths between the modified part and violin-1.

### Prefer Constraint

```clojure theme={null}
(prefer chord-tones downbeats)
```

Checks if downbeat notes are chord tones. Generates INFO if not satisfied.

### Density Constraint

```clojure theme={null}
(note-density 2 8)
```

Checks notes per measure is between 2 and 8.

## Partial Application

When some operations fail:

| Policy           | Behavior                                   |
| ---------------- | ------------------------------------------ |
| `all-or-nothing` | Reject entire batch on any error           |
| `partial`        | Apply valid ops; return errors for invalid |
| `interactive`    | Pause and await human decision             |

```clojure theme={null}
(mrs-ops-result
  :status partial
  :applied 4
  :rejected 2
  :id-mapping (...)
  :errors
    ((error :op 5 :code MUSIC-001 :message "...")
     (error :op 6 :code REF-003 :message "...")))
```

## Best Practices

### For Agent Implementers

1. Validate operations locally before sending
2. Use tmp-ids consistently within envelope
3. Respect constraints from Working Set
4. Handle partial success gracefully

### For Orchestrator Implementers

1. Run all stages; collect all errors
2. Provide specific, actionable error messages
3. Include operation index in errors
4. Support configurable severity thresholds
