# Year-Long Composable Schedule System - REVISION **Author:** Resource Linking Architect (Schedule System Designer) **Date:** 2026-02-12 **Status:** Revised based on User Feedback **Version:** 0.2 **Supersedes:** year-long-schedule-system.md v0.1 --- ## Changes from v0.1 This revision addresses Sienna's feedback: 1. ✅ **Simplified composition** - Keep only `extends` and `override`, remove `remove`/`append`/`replace all` 2. ✅ **User-configurable calendars** - Define seasons/days as enums in schema, not hardcoded 3. ✅ **Behavior references** - Blocks reference behaviors/actions, not string activity names 4. ✅ **Required block names** - All blocks must be named for override system 5. ✅ **Time overlap detection** - Validator warns on overlapping blocks 6. ✅ **Explicit time ranges** - No default durations, must specify start/end 7. ✅ **Recurrence keyword** - Named recurring patterns instead of `every` --- ## Executive Summary This document proposes a **year-long, composable schedule system** for the Storybook DSL that: - **User-defined calendars**: Seasons, days, months defined as enums (8 seasons? 5-day weeks? You decide!) - **Simple composition**: Only `extends` and `override` (no complex operators) - **Behavior integration**: Schedule blocks reference behaviors, not string activities - **Temporal patterns**: Day-specific, seasonal, and recurring event patterns - **Type-safe**: Validator ensures calendar references are valid - **Backward compatible**: Current simple schedules still work --- ## 1. User-Configurable Calendar System ### 1.1 The Problem **Original design** hardcoded Euro-centric calendar: - 4 seasons (Spring, Summer, Fall, Winter) - 7-day week (Monday-Sunday) - 12 Gregorian months **User need:** Lonni wants 8 seasons, fantasy day names, custom time systems. ### 1.2 The Solution: Calendar Enums **Define calendar in schema files** using existing enum system: ```storybook // In schema/calendar.sb enum Season { EarlySpring LateSpring EarlySummer LateSummer EarlyFall LateFall EarlyWinter LateWinter } enum DayOfWeek { Fireday Waterday Earthday Airday Spiritday } enum Month { FirstMonth SecondMonth ThirdMonth FourthMonth FifthMonth SixthMonth SeventhMonth EighthMonth NinthMonth TenthMonth EleventhMonth TwelfthMonth } ``` **Benefits:** - ✅ Uses existing enum system (no new concepts) - ✅ Type-safe (validator checks references) - ✅ Version-controlled with content - ✅ Infinitely flexible (any calendar system) - ✅ Self-documenting (enum values show available options) ### 1.3 Using Calendar Enums in Schedules ```storybook schedule FarmSchedule { season (EarlySpring, LateSpring) { block planting { 5:00 - 18:00, action: PlantCrops } } season (EarlySummer, LateSummer) { block tending { 6:00 - 16:00, action: TendFields } } on Fireday { block ritual { 6:00 - 7:00, action: FireRitual } } } ``` **Validator checks:** - `EarlySpring` exists in `Season` enum? ✓ - `Fireday` exists in `DayOfWeek` enum? ✓ - Clear error if user typos: "Unknown season 'EarlySrping'. Did you mean 'EarlySpring'?" ### 1.4 Standard Calendar (Convenience) **For users who want standard calendar**, we ship a default schema: ```storybook // In schema/standard_calendar.sb enum Season { Spring Summer Fall Winter } enum DayOfWeek { Monday Tuesday Wednesday Thursday Friday Saturday Sunday } enum Month { January February March April May June July August September October November December } ``` Users can `use schema::standard_calendar::*` or define their own! --- ## 2. Simplified Composition System ### 2.1 Only Two Operators **Keep:** - `extends` - Inherit from base schedule - `override` - Replace specific blocks **Remove:** - ~~`remove`~~ - Too complex, just override with empty/different block - ~~`append`~~ - Just define new blocks directly - ~~`replace all`~~ - Just don't extend if you want fresh start ### 2.2 Composition Examples **Basic Extension:** ```storybook schedule BaseWorkday { block sleep { 0:00 - 6:00, action: Sleep } block work { 9:00 - 17:00, action: Work } block leisure { 17:00 - 22:00, action: Leisure } block sleep_late { 22:00 - 24:00, action: Sleep } } schedule BakerSchedule extends BaseWorkday { override work { 5:00 - 13:00, action: BakeryWork } block baking { 3:00 - 5:00, action: PrepBread } // New block, not override } ``` **Result:** - `sleep` (0:00-6:00) - inherited - `baking` (3:00-5:00) - new - `work` (5:00-13:00) - overridden - `leisure` (17:00-22:00) - inherited - `sleep_late` (22:00-24:00) - inherited ### 2.3 Override Semantics **Override by block name**, not by time: ```storybook schedule Base { block work { 9:00 - 17:00, action: GenericWork } } schedule Baker extends Base { override work { 5:00 - 13:00, action: BakeryWork } } // Baker's 'work' block replaces Base's 'work' block entirely // Time changed from 9:00-17:00 to 5:00-13:00 // Action changed from GenericWork to BakeryWork ``` **Partial override** (only change some fields): ```storybook schedule Base { block work { 9:00 - 17:00, action: GenericWork, location: Office } } schedule Remote extends Base { override work { location: Home } // Only change location } // Result: work { 9:00 - 17:00, action: GenericWork, location: Home } ``` --- ## 3. Behavior References (Not String Activities) ### 3.1 The Change **Old (v0.1):** ```storybook block work { 9:00 - 17:00, activity: "work" } // String ``` **New (v0.2):** ```storybook block work { 9:00 - 17:00, action: WorkBehavior } // Behavior reference ``` ### 3.2 Rationale **Benefits:** - Type-safe: Validator ensures `WorkBehavior` exists - Flexible: Different schedules can use different behaviors for same time - Composable: Behaviors are already defined elsewhere - Clear: No ambiguity about what "work" means **Example:** ```storybook behavior BakeryWork { > { check_oven serve_customers clean_workspace } } behavior OfficeWork { > { check_email attend_meetings write_reports } } schedule BakerSchedule { block work { 5:00 - 13:00, action: BakeryWork } } schedule OfficeSchedule { block work { 9:00 - 17:00, action: OfficeWork } } ``` Both schedules have a `work` block, but they reference different behaviors! ### 3.3 Optional Fields Blocks can still have additional fields for context: ```storybook block work { time: 9:00 - 17:00, action: BakeryWork, location: Bakery, priority: high, notes: "Must arrive early to prep dough" } ``` --- ## 4. Temporal Patterns ### 4.1 Day-Specific Patterns ```storybook schedule WeeklyRoutine { on Fireday { block ritual { 6:00 - 7:00, action: FireRitual } block work { 8:00 - 16:00, action: CraftWork } } on Waterday { block meditation { 6:00 - 7:00, action: WaterMeditation } block work { 8:00 - 16:00, action: CraftWork } } on Spiritday { block rest { 0:00 - 24:00, action: Rest } } } ``` **Can extend base schedule per day:** ```storybook schedule WeeklyRoutine { on Fireday extends BaseWorkday { override work { action: FireWork } block ritual { 6:00 - 7:00, action: FireRitual } } } ``` ### 4.2 Seasonal Patterns ```storybook schedule FarmSchedule { season (EarlySpring, LateSpring) { block planting { 5:00 - 18:00, action: PlantCrops } } season (EarlySummer, LateSummer) { block tending { 6:00 - 16:00, action: TendFields } } season (EarlyFall, LateFall) { block harvest { 5:00 - 19:00, action: HarvestCrops } } season (EarlyWinter, LateWinter) { block planning { 9:00 - 15:00, action: PlanNextYear } } } ``` **Multiple seasons in one pattern:** ```storybook season (Bloom, Growth) { // Both use same schedule block outdoor_work { 5:00 - 18:00, action: FarmWork } } ``` ### 4.3 Recurrence Patterns **Named recurring events:** ```storybook schedule AnnualPattern extends BaseWorkday { recurrence MarketDay on Earthday { block market { 8:00 - 13:00, action: SellAtMarket } } recurrence GuildMeeting on FirstFiredayOfMonth { block meeting { 19:00 - 21:00, action: GuildBusiness } } recurrence Festival on MidsummerDay { block celebration { 0:00 - 24:00, action: Celebrate } } } ``` **Recurrence types:** - `on ` - Every week on that day - `on FirstOfMonth` - First occurrence each month - `on LastOfMonth` - Last occurrence each month - `on ` - Specific calendar date (e.g., Midsummer Day 15) **Why `recurrence` keyword:** - More explicit than `every` - Can be named (useful for override/reference) - Clear that it's a repeating pattern - Consistent with other constructs (behavior, character, etc.) --- ## 5. Required Block Names ### 5.1 All Blocks Must Be Named **Old (v0.1):** ```storybook block { 9:00 - 17:00, activity: work } // Anonymous ``` **New (v0.2):** ```storybook block work { 9:00 - 17:00, action: Work } // Named ``` ### 5.2 Rationale **Why required:** - Override system needs names to identify blocks - Better error messages ("overlap in 'work' block") - Self-documenting code - Enables referencing blocks **Syntax:** ```storybook block { } block {