{
  "title": "Rotating shift schedule generator form specification",
  "version": "1.0",
  "date_representation": "Date-only ISO 8601; step dates in UTC calendar arithmetic",
  "fields": [
    {
      "name": "start_date",
      "type": "date",
      "required": true,
      "format": "YYYY-MM-DD"
    },
    {
      "name": "days",
      "type": "integer",
      "required": true,
      "minimum": 1,
      "maximum": 366
    },
    {
      "name": "cycle_labels",
      "type": "array<string>",
      "required": true,
      "minimum_items": 1,
      "maximum_items": 31,
      "item_rules": [
        "nonblank",
        "include OFF label"
      ]
    },
    {
      "name": "people",
      "type": "array<object>",
      "required": true,
      "fields": [
        {
          "name": "person_id",
          "type": "string",
          "required": true,
          "unique": true
        },
        {
          "name": "name",
          "type": "string",
          "required": true,
          "unique": true
        },
        {
          "name": "phase_offset",
          "type": "integer",
          "required": true,
          "minimum": 0
        }
      ]
    },
    {
      "name": "required_workers",
      "type": "integer",
      "required": true,
      "minimum": 0,
      "maximum": 100
    },
    {
      "name": "exports",
      "type": "array<enum>",
      "allowed": [
        "CSV",
        "all-day ICS"
      ],
      "required": true
    }
  ],
  "formula": "labels[(day_index + phase_offset) % cycle_length]",
  "coverage": "Count distinct people with assigned label other than OFF for each date.",
  "validation": [
    "Output exactly people_count × days rows.",
    "Preserve date and label in both exports.",
    "Do not optimize constraints or infer availability/compliance."
  ]
}
