# Validation Rules

The Storybook compiler performs multi-layered validation to catch errors before runtime. This chapter documents all validation rules, organized by declaration type, along with the error messages you can expect and how to fix them.

## Validation Layers

Storybook validation happens in four stages:

1. **Lexical**: Tokenization of raw text (invalid characters, malformed literals)
2. **Syntactic**: Grammar structure (missing braces, wrong keyword order)
3. **Semantic**: Cross-reference resolution, type checking, field merging
4. **Domain**: Narrative-specific constraints (bond ranges, schedule overlaps)

Errors at earlier stages prevent later stages from running.

## Character Validation

### Required Rules

| Rule | Description | Severity |
|------|-------------|----------|
| Unique name | Character names must be unique within their module | Error |
| Species exists | If `: Species` is used, the species must be defined | Error |
| Templates exist | All templates in `from` clause must be defined | Error |
| No circular inheritance | Template chains cannot form cycles | Error |
| Field type consistency | Field values must match expected types | Error |
| Behavior trees exist | All `uses behaviors` references must resolve | Error |
| Schedules exist | All `uses schedule` references must resolve | Error |
| Prose tag uniqueness | Each prose tag can appear at most once per character | Error |

### Examples

**Species not found:**
```storybook
character Martha: Hobbit {  // Error: species 'Hobbit' not defined
    age: 34
}
```

**Fix:** Define the species or correct the reference:
```storybook
species Hobbit {
    lifespan: 130
}

character Martha: Hobbit {
    age: 34
}
```

**Duplicate character name:**
```storybook
character Martha { age: 34 }
character Martha { age: 36 }  // Error: duplicate character name 'Martha'
```

## Template Validation

| Rule | Description | Severity |
|------|-------------|----------|
| Unique name | Template names must be unique within their module | Error |
| Includes exist | All included templates must be defined | Error |
| No circular includes | Include chains cannot form cycles | Error |
| Range validity | Range bounds must satisfy min <= max | Error |
| Range type match | Both bounds of a range must be the same type | Error |
| Strict enforcement | Characters using strict templates cannot add extra fields | Error |
| Resource links valid | Behavior/schedule references must resolve | Error |

### Examples

**Invalid range:**
```storybook
template BadRange {
    age: 65..18  // Error: range min (65) must be <= max (18)
}
```

**Strict template violation:**
```storybook
template Rigid strict {
    required_stat: 10
}

character Constrained from Rigid {
    required_stat: 15
    extra_field: 42    // Error: field 'extra_field' not allowed by strict template 'Rigid'
}
```

## Behavior Tree Validation

| Rule | Description | Severity |
|------|-------------|----------|
| At least one node | Behavior body must contain at least one node | Error |
| Composite children | `choose` and `then` require at least one child | Error |
| Decorator child | Decorators require exactly one child | Error |
| Subtree exists | `include` must reference a defined behavior | Error |
| Expression validity | Condition expressions must be well-formed | Error |
| Duration format | Decorator durations must be valid (e.g., `5s`, `10m`) | Error |
| Repeat count valid | `repeat N` requires N >= 0 | Error |
| Repeat range valid | `repeat min..max` requires 0 <= min <= max | Error |
| Retry count valid | `retry N` requires N >= 1 | Error |

### Examples

**Empty composite:**
```storybook
behavior Empty {
    choose options {
        // Error: 'choose' requires at least one child
    }
}
```

**Invalid subtree reference:**
```storybook
behavior Main {
    include NonExistentBehavior  // Error: behavior 'NonExistentBehavior' not defined
}
```

## Life Arc Validation

| Rule | Description | Severity |
|------|-------------|----------|
| At least one state | Life arc must contain at least one state | Error |
| Unique state names | State names must be unique within the life arc | Error |
| Valid transitions | Transition targets must reference defined states | Error |
| Expression validity | Transition conditions must be well-formed | Error |
| Field targets valid | On-enter field references must resolve | Error |
| Reachable states | All states should be reachable from initial state | Warning |

### Examples

**Invalid transition target:**
```storybook
life_arc Broken {
    state active {
        on timer_expired -> nonexistent  // Error: state 'nonexistent' not defined
    }
}
```

**Unreachable state (warning):**
```storybook
life_arc HasOrphan {
    state start {
        on ready -> middle
    }

    state middle {
        on done -> end
    }

    state orphan {}  // Warning: state 'orphan' is not reachable

    state end {}
}
```

## Schedule Validation

| Rule | Description | Severity |
|------|-------------|----------|
| Time format | Times must be valid HH:MM or HH:MM:SS | Error |
| Modifies exists | Base schedule must be defined | Error |
| No circular modifies | Schedule chains cannot form cycles | Error |
| Named blocks unique | Block names must be unique within a schedule | Error |
| Action references valid | Action references must resolve to defined behaviors | Error |
| Constraint values valid | Temporal constraint values must reference defined enums | Error |
| Recurrence names unique | Recurrence names must be unique within a schedule | Error |

### Examples

**Invalid time format:**
```storybook
schedule Bad {
    block work {
        25:00 - 17:00  // Error: invalid hour '25'
        action: work
    }
}
```

**Circular modifies:**
```storybook
schedule A modifies B { }
schedule B modifies A { }  // Error: circular schedule extension detected
```

## Relationship Validation

| Rule | Description | Severity |
|------|-------------|----------|
| At least two participants | Relationships require >= 2 participants | Error |
| Participants exist | All participant names must reference defined entities | Error |
| Unique participants | Each participant appears at most once | Error |
| Field type consistency | Fields must have valid value types | Error |

### Examples

**Too few participants:**
```storybook
relationship Lonely {
    Martha  // Error: relationship requires at least 2 participants
    bond: 0.5
}
```

## Species Validation

| Rule | Description | Severity |
|------|-------------|----------|
| Unique name | Species names must be unique within their module | Error |
| No circular includes | Include chains cannot form cycles | Error |
| Includes exist | All included species must be defined | Error |
| Field type consistency | Fields must have valid values | Error |
| Prose tag uniqueness | Each prose tag can appear at most once | Error |

## Enum Validation

| Rule | Description | Severity |
|------|-------------|----------|
| Unique enum name | Enum names must be unique within their module | Error |
| Unique variants | Variant names must be unique within the enum | Error |
| Non-empty | Enums must have at least one variant | Error |
| Valid identifiers | Variants must follow identifier rules | Error |

### Examples

**Duplicate variant:**
```storybook
enum Size {
    tiny,
    small,
    small,  // Error: duplicate variant 'small' in enum 'Size'
    large
}
```

## Institution and Location Validation

| Rule | Description | Severity |
|------|-------------|----------|
| Unique name | Names must be unique within their module | Error |
| Resource links valid | Behavior/schedule references must resolve | Error |
| Field type consistency | Fields must have valid values | Error |

## Expression Validation

Expressions are validated wherever they appear (life arc transitions, behavior tree conditions, if decorators).

| Rule | Description | Severity |
|------|-------------|----------|
| Type consistency | Both sides of comparison must have compatible types | Error |
| Boolean context | Logical operators require boolean operands | Error |
| Field existence | Referenced fields must exist on the entity | Error |
| Collection validity | Quantifiers require collection-typed expressions | Error |
| Variable scope | Quantifier variables only valid within their predicate | Error |
| Enum validity | Enum comparisons must reference defined values | Error |

### Examples

**Type mismatch:**
```storybook
life_arc TypeError {
    state checking {
        on count == "five" -> done  // Error: cannot compare int with string
    }

    state done {}
}
```

## Use Statement Validation

| Rule | Description | Severity |
|------|-------------|----------|
| Path exists | Imported paths must reference defined modules/items | Error |
| No circular imports | Modules cannot form circular dependency chains | Error |
| Valid identifiers | All path segments must be valid identifiers | Error |
| Grouped import validity | All items in `{}` must exist in the target module | Error |

### Examples

**Missing import:**
```storybook
use schema::nonexistent::Thing;  // Error: module 'schema::nonexistent' not found
```

## Cross-File Validation

When resolving across multiple `.sb` files, the compiler performs additional checks:

| Rule | Description | Severity |
|------|-------------|----------|
| All references resolve | Cross-file references must find their targets | Error |
| No naming conflicts | Declarations must not collide across files in the same module | Error |
| Import visibility | Only public declarations can be imported | Error |

## Common Error Patterns

### Missing Definitions

The most common error is referencing something that does not exist:

```storybook
character Martha: Human from Baker {
    specialty: sourdough
}
```

If `Human`, `Baker`, or the `sourdough` enum variant are not defined or imported, the compiler will report an error. Fix by adding the appropriate `use` statements:

```storybook
use schema::core_enums::{SkillLevel, Specialty};
use schema::templates::Baker;
use schema::beings::Human;

character Martha: Human from Baker {
    specialty: sourdough
}
```

### Circular Dependencies

Circular references are rejected at every level:

- Templates including each other
- Species including each other
- Schedules extending each other
- Modules importing each other

Break cycles by restructuring into a hierarchy or extracting shared parts into a common module.

### Type Mismatches

Storybook has no implicit type coercion. Ensure values match their expected types:

```storybook
// Wrong:
character Bad {
    age: "twenty"  // Error: expected int, got string
    is_ready: 1    // Error: expected bool, got int
}

// Correct:
character Good {
    age: 20
    is_ready: true
}
```

## Validation Summary

| Declaration | Key Constraints |
|-------------|----------------|
| Character | Unique name, valid species/templates, no circular inheritance |
| Template | Unique name, valid includes, valid ranges, strict enforcement |
| Behavior | Non-empty, valid composites, valid decorators, valid subtrees |
| Life Arc | Non-empty, unique states, valid transitions, reachable states |
| Schedule | Valid times, valid modifies chain, unique block names |
| Relationship | >= 2 participants, valid references |
| Species | Unique name, valid includes, no cycles |
| Enum | Unique name, unique variants, non-empty |
| Institution | Unique name, valid resource links |
| Location | Unique name, valid field types |
| Use | Valid paths, no circular imports |

## Cross-References

- [Characters](./10-characters.md) - Character-specific validation
- [Behavior Trees](./11-behavior-trees.md) - Behavior validation
- [Life Arcs](./13-life-arcs.md) - Life arc validation
- [Schedules](./14-schedules.md) - Schedule validation
- [Expression Language](./17-expressions.md) - Expression validation
- [Value Types](./18-value-types.md) - Type system constraints
