{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://heartcortex.ai/schemas/1.0/schedule.schema.json",
  "title": "schedule",
  "type": "object",
  "required": [
    "id",
    "kind",
    "status"
  ],
  "properties": {
    "id": {
      "$ref": "common.schema.json#/$defs/uuid",
      "x-heart-privacy": "public"
    },
    "kind": {
      "enum": [
        "operation",
        "maintenance-window"
      ],
      "x-heart-privacy": "public",
      "description": "operation: run one API operation at the given time(s). maintenance-window: a period in which the system is in maintenance and requiresMaintenance guards pass."
    },
    "enabled": {
      "type": "boolean",
      "x-heart-privacy": "public"
    },
    "status": {
      "description": "A schedule created by an ai or peer initiator stays proposed until a human adopts it. Only an adopted, enabled schedule fires.",
      "enum": [
        "proposed",
        "adopted",
        "suspended"
      ],
      "x-heart-privacy": "public"
    },
    "cron": {
      "type": "string",
      "x-heart-privacy": "internal",
      "description": "Repeating times, in five-field cron syntax (minute, hour, day of month, month, day of week; numbers, ranges, lists, steps and three-letter names), interpreted in timezone."
    },
    "at": {
      "$ref": "common.schema.json#/$defs/timestamp",
      "x-heart-privacy": "internal",
      "description": "One single time, instead of cron."
    },
    "timezone": {
      "type": "string",
      "x-heart-privacy": "internal",
      "description": "IANA time zone name for cron, such as UTC or Europe/Berlin. Default UTC. A system that does not know the zone refuses the schedule with 400 invalid-request."
    },
    "durationSec": {
      "type": "integer",
      "minimum": 1,
      "x-heart-privacy": "internal",
      "description": "Length of a maintenance window, in seconds. MUST be set for kind maintenance-window."
    },
    "operation": {
      "description": "What to run, for kind operation. The same shape as a batch item. The system MUST record it for kind operation.",
      "type": "object",
      "required": [
        "method",
        "path"
      ],
      "additionalProperties": false,
      "properties": {
        "method": {
          "enum": [
            "GET",
            "POST",
            "PUT",
            "PATCH",
            "DELETE"
          ]
        },
        "path": {
          "type": "string",
          "pattern": "^/heart/v1/"
        },
        "body": {}
      },
      "x-heart-privacy": "private"
    },
    "initiator": {
      "type": "object",
      "x-heart-privacy": "internal",
      "required": [
        "kind"
      ],
      "properties": {
        "kind": {
          "enum": [
            "human",
            "peer",
            "ai",
            "rule"
          ]
        },
        "id": {
          "type": "string",
          "x-heart-privacy": "private"
        },
        "onBehalfOf": {
          "description": "Principal whose authority an AI-initiated action runs under.",
          "type": "string",
          "x-heart-privacy": "private"
        }
      },
      "description": "Who created the schedule. When it fires, the operation passes the gate as this initiator (API Standard 6.3). The system MUST record it for every schedule. It is internal, so it is not in the required list (public views stay valid)."
    },
    "adoptedBy": {
      "type": "string",
      "x-heart-privacy": "private",
      "description": "The person whose approval, or own request, adopted it."
    },
    "createdAt": {
      "$ref": "common.schema.json#/$defs/timestamp",
      "x-heart-privacy": "internal"
    },
    "nextRunAt": {
      "$ref": "common.schema.json#/$defs/timestamp",
      "x-heart-privacy": "internal",
      "description": "When it fires next. Absent once a single-time schedule has fired."
    },
    "runs": {
      "type": "array",
      "x-heart-privacy": "internal",
      "description": "The latest runs, oldest first, in a bounded list. Each run is a new Action, passed through the gate as the initiator.",
      "items": {
        "type": "object",
        "required": [
          "at",
          "status"
        ],
        "properties": {
          "at": {
            "$ref": "common.schema.json#/$defs/timestamp"
          },
          "actionId": {
            "$ref": "common.schema.json#/$defs/uuid"
          },
          "status": {
            "type": "string",
            "description": "The Action's status when the run started, or missed when the system was not running at the time."
          },
          "detail": {
            "type": "string"
          }
        }
      }
    },
    "ext": {
      "$ref": "common.schema.json#/$defs/ext",
      "x-heart-privacy": "private"
    }
  },
  "description": "Something to do later, or a maintenance window. It runs later as its author, and passes the gate again when it fires (API Standard 6.3)."
}
