{
  "suite": "org.classprofiles.calendar/core@1",
  "fixtures": [
    {
      "id": "core.create_event.basic",
      "title": "Job 2: create a simple timed event, then fetch it back",
      "steps": [
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "Dentist",
              "start": "2026-02-25T09:00:00-05:00",
              "end": "2026-02-25T09:45:00-05:00",
              "timezone": "America/New_York"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.id",
                "nonempty_string": true,
                "bind": "EVT"
              },
              {
                "path": "$.title",
                "equals": "Dentist"
              },
              {
                "path": "$.start",
                "rfc3339": true
              },
              {
                "path": "$.state",
                "equals": "confirmed"
              },
              {
                "path": "$.all_day",
                "absent": true
              },
              {
                "path": "$.location",
                "absent": true
              },
              {
                "path": "$.description_md",
                "absent": true
              },
              {
                "path": "$.attendees",
                "absent": true
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.get_event",
            "args": {
              "event_id": "{EVT}"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.title",
                "equals": "Dentist"
              },
              {
                "path": "$.start",
                "equals": "2026-02-25T09:00:00-05:00"
              },
              {
                "path": "$.end",
                "equals": "2026-02-25T09:45:00-05:00"
              }
            ]
          }
        }
      ]
    },
    {
      "id": "core.list_events.range_and_query",
      "title": "Job 1: list a week; pagination is continuous and query narrows correctly",
      "steps": [
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "CP-PAGE Dentist",
              "start": "2026-02-25T09:00:00-05:00",
              "end": "2026-02-25T09:45:00-05:00",
              "location": "CP-LOC South Wing",
              "description_md": "CP-DESC followup note"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.id",
                "bind": "A"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "CP-PAGE Groceries",
              "start": "2026-02-25T17:00:00-05:00",
              "end": "2026-02-25T17:30:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.id",
                "bind": "B"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "Ends at range start",
              "start": "2026-02-23T23:30:00-05:00",
              "end": "2026-02-24T00:00:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.id",
                "bind": "RANGE_LOW"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "Starts at range end",
              "start": "2026-02-26T00:00:00-05:00",
              "end": "2026-02-26T00:30:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.id",
                "bind": "RANGE_HIGH"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-24T00:00:00-05:00",
              "range_end": "2026-02-26T00:00:00-05:00",
              "query": "CP-PAGE",
              "limit": 1
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "length_gte": 1
              },
              {
                "path": "$.events",
                "length_lte": 1
              },
              {
                "path": "$.events[*].id",
                "snapshot": "PAGE_ONE_IDS"
              },
              {
                "path": "$.events[0].id",
                "equals": "{A}"
              },
              {
                "path": "$.next_cursor",
                "nonempty_string": true,
                "bind": "NEXT_CURSOR"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-24T00:00:00-05:00",
              "range_end": "2026-02-26T00:00:00-05:00",
              "query": "CP-PAGE",
              "limit": 1,
              "cursor": "{NEXT_CURSOR}"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "length_gte": 1
              },
              {
                "path": "$.events",
                "length_lte": 1
              },
              {
                "path": "$.events[*].id",
                "disjoint_from_snapshot": "PAGE_ONE_IDS"
              },
              {
                "path": "$.events[0].id",
                "equals": "{B}"
              },
              {
                "path": "$.next_cursor",
                "absent": true
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-24T00:00:00-05:00",
              "range_end": "2026-02-26T00:00:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "length_gte": 2,
                "length_lte": 2
              },
              {
                "path": "$.events[*].id",
                "equals": [
                  "{A}",
                  "{B}"
                ]
              },
              {
                "path": "$.events[*].title",
                "equals": [
                  "CP-PAGE Dentist",
                  "CP-PAGE Groceries"
                ]
              },
              {
                "path": "$.next_cursor",
                "absent": true
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-24T00:00:00-05:00",
              "range_end": "2026-02-26T00:00:00-05:00",
              "query": "dentist"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "length_gte": 1,
                "length_lte": 1
              },
              {
                "path": "$.events[*].title",
                "equals": [
                  "CP-PAGE Dentist"
                ]
              },
              {
                "path": "$.events[*].id",
                "equals": [
                  "{A}"
                ]
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-24T00:00:00-05:00",
              "range_end": "2026-02-26T00:00:00-05:00",
              "query": "south wing"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "length_gte": 1,
                "length_lte": 1
              },
              {
                "path": "$.events[*].id",
                "equals": [
                  "{A}"
                ]
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-24T00:00:00-05:00",
              "range_end": "2026-02-26T00:00:00-05:00",
              "query": "followup"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "length_gte": 1,
                "length_lte": 1
              },
              {
                "path": "$.events[*].id",
                "equals": [
                  "{A}"
                ]
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-23T00:00:00-05:00",
              "range_end": "2026-03-02T00:00:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "length_gte": 4,
                "length_lte": 4
              },
              {
                "path": "$.events[*].id",
                "equals": [
                  "{RANGE_LOW}",
                  "{A}",
                  "{B}",
                  "{RANGE_HIGH}"
                ]
              },
              {
                "path": "$.next_cursor",
                "absent": true
              }
            ]
          }
        }
      ]
    },
    {
      "id": "core.create_event.all_day",
      "title": "Job 3: all-day event uses date-boundary timestamps in its timezone",
      "steps": [
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "PA state holiday",
              "start": "2026-02-27T00:00:00-05:00",
              "end": "2026-02-28T00:00:00-05:00",
              "timezone": "America/New_York",
              "all_day": true
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.all_day",
                "equals": true
              },
              {
                "path": "$.start",
                "equals": "2026-02-27T00:00:00-05:00"
              },
              {
                "path": "$.end",
                "equals": "2026-02-28T00:00:00-05:00"
              },
              {
                "path": "$.timezone",
                "equals": "America/New_York"
              },
              {
                "path": "$.id",
                "bind": "H"
              }
            ]
          }
        }
      ]
    },
    {
      "id": "core.update_event.move_and_edit",
      "title": "Jobs 4–5: repeated patching moves, edits, clears, and preserves state",
      "steps": [
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "Sprint review",
              "start": "2026-02-26T15:00:00-05:00",
              "end": "2026-02-26T16:00:00-05:00",
              "location": "Room 2",
              "description_md": "Keep this agenda."
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.id",
                "bind": "S"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.update_event",
            "args": {
              "event_id": "{S}",
              "patch": {
                "start": "2026-02-26T16:00:00-05:00",
                "end": "2026-02-26T17:00:00-05:00",
                "title": "Sprint review — revised",
                "location": null
              }
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.start",
                "equals": "2026-02-26T16:00:00-05:00"
              },
              {
                "path": "$.end",
                "equals": "2026-02-26T17:00:00-05:00"
              },
              {
                "path": "$.title",
                "equals": "Sprint review — revised"
              },
              {
                "path": "$.location",
                "absent": true
              },
              {
                "path": "$.description_md",
                "equals": "Keep this agenda."
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.update_event",
            "args": {
              "event_id": "{S}",
              "patch": {
                "start": "2026-02-26T16:00:00-05:00",
                "end": "2026-02-26T17:00:00-05:00",
                "title": "Sprint review — revised",
                "location": null
              }
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.start",
                "equals": "2026-02-26T16:00:00-05:00"
              },
              {
                "path": "$.end",
                "equals": "2026-02-26T17:00:00-05:00"
              },
              {
                "path": "$.title",
                "equals": "Sprint review — revised"
              },
              {
                "path": "$.location",
                "absent": true
              },
              {
                "path": "$.description_md",
                "equals": "Keep this agenda."
              }
            ]
          }
        }
      ]
    },
    {
      "id": "core.cancel_event.tombstone_repeated",
      "title": "Job 6: repeated cancellation preserves a fetchable tombstone",
      "steps": [
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "Doomed",
              "start": "2026-02-24T10:00:00-05:00",
              "end": "2026-02-24T10:30:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.id",
                "bind": "D"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.cancel_event",
            "args": {
              "event_id": "{D}"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.state",
                "equals": "cancelled"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.cancel_event",
            "args": {
              "event_id": "{D}",
              "notify_attendees": true
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.state",
                "equals": "cancelled"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.get_event",
            "args": {
              "event_id": "{D}"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.state",
                "equals": "cancelled"
              }
            ]
          }
        }
      ]
    },
    {
      "id": "core.find_free_time.respects_busy",
      "title": "Jobs 7–8: free slots are bounded, avoid busy time, and answer exact windows",
      "steps": [
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "Blocker",
              "start": "2026-02-26T10:30:00-05:00",
              "end": "2026-02-26T12:00:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.id",
                "bind": "BLK"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.find_free_time",
            "args": {
              "duration_minutes": 45,
              "window_start": "2026-02-26T09:00:00-05:00",
              "window_end": "2026-02-26T13:00:00-05:00",
              "max_results": 5
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.slots",
                "length_gte": 1
              },
              {
                "path": "$.slots",
                "length_lte": 5
              },
              {
                "path": "$.slots[*]",
                "no_overlap_with": {
                  "start": "2026-02-26T10:30:00-05:00",
                  "end": "2026-02-26T12:00:00-05:00"
                }
              },
              {
                "path": "$.slots[*]",
                "min_duration_minutes": 45
              },
              {
                "path": "$.slots[*]",
                "within_interval": {
                  "start": "2026-02-26T09:00:00-05:00",
                  "end": "2026-02-26T13:00:00-05:00"
                }
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.find_free_time",
            "args": {
              "duration_minutes": 45,
              "window_start": "2026-02-26T10:30:00-05:00",
              "window_end": "2026-02-26T11:15:00-05:00",
              "max_results": 1
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.slots",
                "length_lte": 0
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.find_free_time",
            "args": {
              "duration_minutes": 45,
              "window_start": "2026-02-26T12:00:00-05:00",
              "window_end": "2026-02-26T12:45:00-05:00",
              "max_results": 1
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.slots",
                "length_gte": 1
              },
              {
                "path": "$.slots",
                "length_lte": 1
              },
              {
                "path": "$.slots[*]",
                "min_duration_minutes": 45
              },
              {
                "path": "$.slots[*]",
                "within_interval": {
                  "start": "2026-02-26T12:00:00-05:00",
                  "end": "2026-02-26T12:45:00-05:00"
                }
              }
            ]
          }
        }
      ]
    },
    {
      "id": "core.create_event.with_attendee",
      "title": "Job 10: request an invitation; attendee round-trips with sparse default response",
      "steps": [
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "Leo / Priya",
              "start": "2026-02-26T13:00:00-05:00",
              "end": "2026-02-26T13:45:00-05:00",
              "attendees": [
                {
                  "email": "priya@example.com",
                  "name": "Priya"
                }
              ]
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.attendees[0].email",
                "equals": "priya@example.com"
              },
              {
                "path": "$.attendees[0].response",
                "absent": true
              }
            ]
          }
        }
      ]
    },
    {
      "id": "core.risk.read_verbs_are_readonly",
      "title": "Risk/default check: list, get, and free-time reads leave state unchanged",
      "steps": [
        {
          "call": {
            "verb": "calendar.create_event",
            "args": {
              "title": "Read-only sentinel",
              "start": "2026-02-23T14:00:00-05:00",
              "end": "2026-02-23T14:30:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.id",
                "bind": "READ_ID"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-23T00:00:00-05:00",
              "range_end": "2026-03-02T00:00:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "snapshot": "BEFORE"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-23T00:00:00-05:00",
              "range_end": "2026-03-02T00:00:00-05:00",
              "limit": 50
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "unordered_equals_snapshot": "BEFORE"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.get_event",
            "args": {
              "event_id": "{READ_ID}"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.title",
                "equals": "Read-only sentinel"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-23T00:00:00-05:00",
              "range_end": "2026-03-02T00:00:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "unordered_equals_snapshot": "BEFORE"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.find_free_time",
            "args": {
              "duration_minutes": 30,
              "window_start": "2026-02-23T09:00:00-05:00",
              "window_end": "2026-02-23T17:00:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.slots",
                "snapshot": "SLOTS_DEFAULT"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.find_free_time",
            "args": {
              "duration_minutes": 30,
              "window_start": "2026-02-23T09:00:00-05:00",
              "window_end": "2026-02-23T17:00:00-05:00",
              "max_results": 5
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.slots",
                "unordered_equals_snapshot": "SLOTS_DEFAULT"
              }
            ]
          }
        },
        {
          "call": {
            "verb": "calendar.list_events",
            "args": {
              "range_start": "2026-02-23T00:00:00-05:00",
              "range_end": "2026-03-02T00:00:00-05:00"
            }
          },
          "expect": {
            "state": "ok",
            "assert": [
              {
                "path": "$.events",
                "unordered_equals_snapshot": "BEFORE"
              }
            ]
          }
        }
      ]
    },
    {
      "id": "core.errors.unknown_id",
      "title": "Unknown event_id fails loudly with a JSON-RPC invalid-params error, never a fabricated event",
      "steps": [
        {
          "call": {
            "verb": "calendar.get_event",
            "args": {
              "event_id": "evt_never_existed"
            }
          },
          "expect": {
            "state": "error",
            "assert": [
              {
                "path": "$.error.code",
                "equals": -32602
              }
            ]
          }
        }
      ]
    }
  ]
}
