# 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