Files
storybook/docs/reference/19-validation.md
Sienna Meridian Satterwhite 47fafdc2bf feat(lang): complete extends to modifies keyword migration
This commit completes the migration started in the previous commit,
updating all remaining files:

- Lexer: Changed token from Extends to Modifies
- Parser: Updated lalrpop grammar rules and AST field names
- AST: Renamed Schedule.extends field to modifies
- Grammar: Updated tree-sitter grammar.js
- Tree-sitter: Regenerated parser.c and node-types.json
- Examples: Updated baker-family work schedules
- Tests: Updated schedule composition tests and corpus
- Docs: Updated all reference documentation and tutorials
- Validation: Updated error messages and validation logic
- Package: Bumped version to 0.3.1 in all package manifests

All 554 tests pass.
2026-02-16 22:55:04 +00:00

12 KiB

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:

character Martha: Hobbit {  // Error: species 'Hobbit' not defined
    age: 34
}

Fix: Define the species or correct the reference:

species Hobbit {
    lifespan: 130
}

character Martha: Hobbit {
    age: 34
}

Duplicate character name:

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:

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

Strict template violation:

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:

behavior Empty {
    choose options {
        // Error: 'choose' requires at least one child
    }
}

Invalid subtree reference:

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:

life_arc Broken {
    state active {
        on timer_expired -> nonexistent  // Error: state 'nonexistent' not defined
    }
}

Unreachable state (warning):

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:

schedule Bad {
    block work {
        25:00 - 17:00  // Error: invalid hour '25'
        action: work
    }
}

Circular modifies:

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:

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:

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:

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:

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:

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:

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:

// 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