{
  "openapi": "3.1.0",
  "info": {
    "title": "Vision Calendar API",
    "version": "1.6.0",
    "description": "Employee calendar, recurrence, exceptions, availability, conflict, event, attendance-response, and expiring-hold API consumed by Vision. Vision authenticates identities; Calendar enforces workspace, actor, capability, record ownership, visibility, idempotency, and optimistic concurrency."
  },
  "tags": [
    {
      "name": "Operations"
    },
    {
      "name": "Calendar"
    },
    {
      "name": "Commands"
    }
  ],
  "paths": {
    "/health/live": {
      "get": {
        "tags": ["Operations"],
        "summary": "Process liveness",
        "responses": {
          "200": {
            "description": "Process is alive"
          }
        },
        "security": []
      }
    },
    "/calendar/v1/meta": {
      "get": {
        "tags": ["Operations"],
        "summary": "Version and contract metadata",
        "responses": {
          "200": {
            "description": "Calendar API metadata"
          }
        },
        "security": []
      }
    },
    "/calendar/v1/openapi.json": {
      "get": {
        "tags": ["Operations"],
        "summary": "OpenAPI contract",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/calendar/v1/ready": {
      "get": {
        "tags": ["Operations"],
        "summary": "Authenticated schema readiness",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:health:read",
        "responses": {
          "200": {
            "description": "Calendar is ready"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/actor-bindings": {
      "post": {
        "tags": ["Administration"],
        "summary": "Provision or reactivate a Vision human actor binding",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:actor:provision",
        "description": "Requires a bound Vision service identity; human, worker, and agent identities are denied.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActorBindingInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Actor binding provisioned",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActorBinding"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/agenda": {
      "get": {
        "tags": ["Calendar"],
        "summary": "Authorized, visibility-filtered agenda",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:agenda:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 500
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agenda page",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Agenda"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/events/{reference}": {
      "get": {
        "tags": ["Calendar"],
        "summary": "Authorized event details",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:event:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/EventReference"
          }
        ],
        "responses": {
          "200": {
            "description": "Event details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Event"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/availability/{actorReference}": {
      "get": {
        "tags": ["Calendar"],
        "summary": "Working hours, exceptions, and free/busy without event details",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:availability:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/ActorReference"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          }
        ],
        "responses": {
          "200": {
            "description": "Availability view",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Availability"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/conflicts": {
      "post": {
        "tags": ["Calendar"],
        "summary": "Find event and active-hold conflicts without record details",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:conflict:read",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConflictQuery"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Conflict intervals",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Conflicts"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/event-commands": {
      "post": {
        "tags": ["Commands"],
        "summary": "Create, update, or cancel a locally authoritative event",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:event:write",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventCommand"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Update or cancellation succeeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandResult"
                }
              }
            }
          },
          "201": {
            "description": "Event creation succeeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/attendance-commands": {
      "post": {
        "tags": ["Commands"],
        "summary": "Record the authorized actor's response to an internal invitation",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:attendance:write",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AttendanceCommand"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Attendance response recorded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/recurrence-commands": {
      "post": {
        "tags": ["Commands"],
        "summary": "Modify or cancel one materialized occurrence in a local series",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:recurrence:write",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurrenceExceptionCommand"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Occurrence exception recorded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/hold-commands": {
      "post": {
        "tags": ["Commands"],
        "summary": "Create or release an expiring scheduling hold",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:hold:write",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HoldCommand"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hold release succeeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandResult"
                }
              }
            }
          },
          "201": {
            "description": "Hold creation succeeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/availability/slots": {
      "post": {
        "tags": ["Calendar"],
        "summary": "Open bookable slots across one or more actors",
        "description": "Returns the slots that are actually bookable for the requested actors, with working hours, availability exceptions, existing events, expanded recurrence occurrences and ACTIVE UNEXPIRED HOLDS already applied. Calendar performs the timezone and interval arithmetic so a caller does not have to; GET /calendar/v1/availability/{actorReference} returns the raw inputs instead and does not account for holds. An actor with no active availability policy contributes no bookable time.",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:availability:read",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AvailabilitySlotsQuery"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bookable slots",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailabilitySlots"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/availability-commands": {
      "post": {
        "tags": ["Calendar"],
        "summary": "Set working hours, or create and delete availability exceptions",
        "description": "Closes the gap that availability_policy rows could previously only be written by direct SQL. policy.set SUPERSEDES rather than mutates: availability_policy carries a unique index on (workspace_id, actor_id) where status = active, so setting new hours marks the current row superseded and inserts a new one, preserving the policy that was active when an earlier booking was made. Omitting actorReference targets the calling actor; supplying one targets another actor in the same workspace and returns 404 — indistinguishable from a nonexistent reference — for anything outside it. Requires an Idempotency-Key header.",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:availability:write",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AvailabilityCommand"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Command applied (exception.delete)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandResult"
                }
              }
            }
          },
          "201": {
            "description": "Record created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    },
    "/calendar/v1/presentation": {
      "get": {
        "tags": ["Calendar"],
        "summary": "Calendar's interface, described for this caller",
        "description": "Module Presentation Standard: a module describes its interface and the core renders it, so installing or removing a module is a data operation rather than a build. Returns navigation, settings, views and actions, filtered to the caller EFFECTIVE permissions - narrowed by identity class first, so a service identity holding every scope receives read sections and zero actions. Grants nothing: every section returned is one the caller could already call directly. Declarative only; no executable content crosses this boundary.",
        "security": [
          {
            "visionBearer": []
          }
        ],
        "x-required-scope": "calendar:agenda:read",
        "responses": {
          "200": {
            "description": "The descriptor as this caller may see it",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarPresentation"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthenticationFailure"
          },
          "403": {
            "$ref": "#/components/responses/PermissionDenied"
          },
          "503": {
            "$ref": "#/components/responses/DependencyUnavailable"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "visionBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Vision-issued access token (JWT). Obtain via the token endpoint of the identity provider configured for this installation.",
        "x-claims": [
          "credential_version",
          "iss",
          "aud",
          "sub",
          "iat",
          "exp",
          "jti",
          "vision_org_id",
          "app_workspace_ref",
          "identity_class",
          "app_entitlements",
          "scope"
        ]
      }
    },
    "parameters": {
      "From": {
        "name": "from",
        "in": "query",
        "required": true,
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "To": {
        "name": "to",
        "in": "query",
        "required": true,
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "ActorReference": {
        "name": "actorReference",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/ActorReference"
        }
      },
      "EventReference": {
        "name": "reference",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/EventReference"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Actor-scoped key. Reusing it with an identical parsed command replays the durable result; reusing it for a different command returns IDEMPOTENCY_CONFLICT.",
        "schema": {
          "type": "string",
          "minLength": 16,
          "maxLength": 160,
          "pattern": "^[A-Za-z0-9._:-]+$"
        }
      }
    },
    "responses": {
      "AuthenticationFailure": {
        "description": "Credential missing or invalid",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PermissionDenied": {
        "description": "Credential lacks entitlement, scope, or active binding",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "InvalidRequest": {
        "description": "Request validation failed",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "No accessible record was found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Conflict": {
        "description": "Time conflict, stale record version, invalid state, or idempotency-key conflict",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "DependencyUnavailable": {
        "description": "Database or required configuration unavailable",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "ActorReference": {
        "type": "string",
        "pattern": "^ACT-[A-Z0-9]{12}$"
      },
      "EventReference": {
        "type": "string",
        "pattern": "^EVT-[A-Z0-9]{12}$"
      },
      "OccurrenceReference": {
        "type": "string",
        "pattern": "^EOC-[A-Z0-9]{12}$"
      },
      "CollectionReference": {
        "type": "string",
        "pattern": "^COL-[A-Z0-9]{12}$"
      },
      "HoldReference": {
        "type": "string",
        "pattern": "^HLD-[A-Z0-9]{12}$"
      },
      "ConflictInterval": {
        "type": "object",
        "additionalProperties": false,
        "required": ["actorReference", "startsAt", "endsAt", "source"],
        "properties": {
          "actorReference": {
            "$ref": "#/components/schemas/ActorReference"
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "endsAt": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "enum": ["event", "hold"]
          }
        }
      },
      "Error": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "status",
          "code",
          "message",
          "retryable",
          "correlationId",
          "fieldIssues",
          "conflict"
        ],
        "properties": {
          "schemaVersion": {
            "const": "vision-calendar-error.v1"
          },
          "status": {
            "const": "failed"
          },
          "code": {
            "enum": [
              "AUTHENTICATION_REQUIRED",
              "INVALID_CREDENTIAL",
              "PERMISSION_DENIED",
              "INVALID_REQUEST",
              "INVALID_STATE",
              "NOT_FOUND",
              "CONFLICT",
              "STALE_VERSION",
              "IDEMPOTENCY_CONFLICT",
              "DEPENDENCY_UNAVAILABLE",
              "INTERNAL_ERROR"
            ]
          },
          "message": {
            "type": "string"
          },
          "retryable": {
            "type": "boolean"
          },
          "correlationId": {
            "type": "string",
            "format": "uuid"
          },
          "fieldIssues": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["path", "code"],
              "properties": {
                "path": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                }
              }
            }
          },
          "conflict": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": ["currentVersion", "intervals"],
                "properties": {
                  "currentVersion": {
                    "type": ["integer", "null"],
                    "minimum": 1
                  },
                  "intervals": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ConflictInterval"
                    }
                  }
                }
              }
            ]
          }
        }
      },
      "AgendaItem": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "publicReference",
          "startsAt",
          "endsAt",
          "allDay",
          "status",
          "visibility",
          "title",
          "location",
          "owner",
          "recordVersion",
          "recurrence"
        ],
        "properties": {
          "publicReference": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/EventReference"
              },
              {
                "$ref": "#/components/schemas/OccurrenceReference"
              }
            ]
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "endsAt": {
            "type": "string",
            "format": "date-time"
          },
          "allDay": {
            "type": "boolean"
          },
          "status": {
            "enum": ["confirmed", "tentative"]
          },
          "visibility": {
            "enum": ["details", "availability_only"]
          },
          "title": {
            "type": ["string", "null"]
          },
          "location": {
            "type": ["string", "null"]
          },
          "owner": {
            "type": ["object", "null"]
          },
          "recordVersion": {
            "type": "integer",
            "minimum": 1
          },
          "recurrence": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": ["seriesReference", "originalStartsAt"],
                "properties": {
                  "seriesReference": {
                    "$ref": "#/components/schemas/EventReference"
                  },
                  "originalStartsAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            ]
          }
        }
      },
      "Agenda": {
        "type": "object",
        "additionalProperties": false,
        "required": ["schemaVersion", "range", "items", "nextCursor"],
        "properties": {
          "schemaVersion": {
            "const": "vision-calendar-agenda.v1"
          },
          "range": {
            "type": "object"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgendaItem"
            }
          },
          "nextCursor": {
            "type": ["string", "null"]
          }
        }
      },
      "Event": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AgendaItem"
          },
          {
            "type": "object",
            "required": [
              "schemaVersion",
              "description",
              "timezone",
              "attendees",
              "recurrenceRule"
            ],
            "properties": {
              "schemaVersion": {
                "const": "vision-calendar-event.v1"
              },
              "description": {
                "type": ["string", "null"]
              },
              "timezone": {
                "type": "string"
              },
              "attendees": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "recurrenceRule": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/RecurrenceSpec"
                  }
                ]
              }
            }
          }
        ]
      },
      "Availability": {
        "type": "object",
        "required": [
          "schemaVersion",
          "actor",
          "range",
          "workingHours",
          "busy",
          "exceptions"
        ],
        "properties": {
          "schemaVersion": {
            "const": "vision-calendar-availability.v1"
          },
          "actor": {
            "type": "object"
          },
          "range": {
            "type": "object"
          },
          "workingHours": {},
          "busy": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "exceptions": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "ConflictQuery": {
        "type": "object",
        "additionalProperties": false,
        "required": ["actorReferences", "startsAt", "endsAt"],
        "properties": {
          "actorReferences": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/ActorReference"
            }
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "endsAt": {
            "type": "string",
            "format": "date-time"
          },
          "excludeEventReference": {
            "$ref": "#/components/schemas/EventReference"
          }
        }
      },
      "Conflicts": {
        "type": "object",
        "additionalProperties": false,
        "required": ["schemaVersion", "range", "conflicts"],
        "properties": {
          "schemaVersion": {
            "const": "vision-calendar-conflicts.v1"
          },
          "range": {
            "type": "object"
          },
          "conflicts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConflictInterval"
            }
          }
        }
      },
      "RecurrenceSpec": {
        "type": "object",
        "additionalProperties": false,
        "required": ["frequency", "interval", "byWeekday", "count"],
        "properties": {
          "frequency": {
            "enum": ["daily", "weekly", "monthly"]
          },
          "interval": {
            "type": "integer",
            "minimum": 1,
            "maximum": 52,
            "default": 1
          },
          "byWeekday": {
            "type": "array",
            "maxItems": 7,
            "items": {
              "enum": ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]
            }
          },
          "count": {
            "type": "integer",
            "minimum": 2,
            "maximum": 366
          }
        },
        "description": "Count-bounded recurrence. The frequency, interval, and count combination must expand no farther than two years; byWeekday is required only for weekly rules. Recurring all-day events are not accepted in v1."
      },
      "EventFields": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 240
          },
          "description": {
            "type": ["string", "null"],
            "maxLength": 4000
          },
          "location": {
            "type": ["string", "null"],
            "maxLength": 500
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "endsAt": {
            "type": "string",
            "format": "date-time"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "allDay": {
            "type": "boolean",
            "default": false
          },
          "status": {
            "enum": ["confirmed", "tentative"],
            "default": "confirmed"
          },
          "visibility": {
            "enum": ["private", "standard", "restricted", "availability_only"],
            "default": "standard"
          },
          "attendeeActorReferences": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/ActorReference"
            }
          },
          "checkConflicts": {
            "type": "boolean",
            "default": true
          },
          "recurrence": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RecurrenceSpec"
              }
            ],
            "default": null
          }
        }
      },
      "EventCommand": {
        "oneOf": [
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/EventFields"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "operation",
                  "collectionReference",
                  "title",
                  "startsAt",
                  "endsAt",
                  "timezone"
                ],
                "properties": {
                  "operation": {
                    "const": "create"
                  },
                  "collectionReference": {
                    "$ref": "#/components/schemas/CollectionReference"
                  }
                }
              }
            ]
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "operation",
              "eventReference",
              "expectedVersion",
              "patch"
            ],
            "properties": {
              "operation": {
                "const": "update"
              },
              "eventReference": {
                "$ref": "#/components/schemas/EventReference"
              },
              "expectedVersion": {
                "type": "integer",
                "minimum": 1
              },
              "patch": {
                "$ref": "#/components/schemas/EventFields"
              },
              "checkConflicts": {
                "type": "boolean",
                "default": true
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": ["operation", "eventReference", "expectedVersion"],
            "properties": {
              "operation": {
                "const": "cancel"
              },
              "eventReference": {
                "$ref": "#/components/schemas/EventReference"
              },
              "expectedVersion": {
                "type": "integer",
                "minimum": 1
              },
              "reasonCode": {
                "enum": [
                  "employee_unavailable",
                  "rescheduled",
                  "no_longer_needed",
                  "duplicate",
                  "other"
                ],
                "default": "other"
              }
            }
          }
        ],
        "discriminator": {
          "propertyName": "operation"
        }
      },
      "HoldCommand": {
        "oneOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "operation",
              "actorReference",
              "startsAt",
              "endsAt",
              "expiresAt",
              "purpose"
            ],
            "properties": {
              "operation": {
                "const": "create"
              },
              "actorReference": {
                "$ref": "#/components/schemas/ActorReference"
              },
              "startsAt": {
                "type": "string",
                "format": "date-time"
              },
              "endsAt": {
                "type": "string",
                "format": "date-time"
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              },
              "purpose": {
                "type": "string",
                "minLength": 1,
                "maxLength": 160
              },
              "checkConflicts": {
                "type": "boolean",
                "default": true
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": ["operation", "holdReference", "expectedVersion"],
            "properties": {
              "operation": {
                "const": "release"
              },
              "holdReference": {
                "$ref": "#/components/schemas/HoldReference"
              },
              "expectedVersion": {
                "type": "integer",
                "minimum": 1
              }
            }
          }
        ],
        "discriminator": {
          "propertyName": "operation"
        }
      },
      "AttendanceCommand": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "operation",
          "eventReference",
          "expectedEventVersion",
          "expectedAttendeeVersion",
          "responseStatus"
        ],
        "properties": {
          "operation": {
            "const": "respond"
          },
          "eventReference": {
            "$ref": "#/components/schemas/EventReference"
          },
          "expectedEventVersion": {
            "type": "integer",
            "minimum": 1
          },
          "expectedAttendeeVersion": {
            "type": "integer",
            "minimum": 1
          },
          "responseStatus": {
            "enum": ["accepted", "declined", "tentative"]
          }
        }
      },
      "RecurrenceExceptionCommand": {
        "oneOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "operation",
              "eventReference",
              "occurrenceReference",
              "expectedEventVersion",
              "expectedOccurrenceVersion"
            ],
            "properties": {
              "operation": {
                "const": "cancelOccurrence"
              },
              "eventReference": {
                "$ref": "#/components/schemas/EventReference"
              },
              "occurrenceReference": {
                "$ref": "#/components/schemas/OccurrenceReference"
              },
              "expectedEventVersion": {
                "type": "integer",
                "minimum": 1
              },
              "expectedOccurrenceVersion": {
                "type": "integer",
                "minimum": 1
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "operation",
              "eventReference",
              "occurrenceReference",
              "expectedEventVersion",
              "expectedOccurrenceVersion",
              "patch"
            ],
            "properties": {
              "operation": {
                "const": "modifyOccurrence"
              },
              "eventReference": {
                "$ref": "#/components/schemas/EventReference"
              },
              "occurrenceReference": {
                "$ref": "#/components/schemas/OccurrenceReference"
              },
              "expectedEventVersion": {
                "type": "integer",
                "minimum": 1
              },
              "expectedOccurrenceVersion": {
                "type": "integer",
                "minimum": 1
              },
              "checkConflicts": {
                "type": "boolean",
                "default": true
              },
              "patch": {
                "type": "object",
                "additionalProperties": false,
                "minProperties": 1,
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 240
                  },
                  "description": {
                    "type": ["string", "null"],
                    "maxLength": 4000
                  },
                  "location": {
                    "type": ["string", "null"],
                    "maxLength": 500
                  },
                  "startsAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "endsAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        ],
        "discriminator": {
          "propertyName": "operation"
        }
      },
      "ActorBindingInput": {
        "type": "object",
        "additionalProperties": false,
        "required": ["visionSubject", "displayName", "timezone"],
        "properties": {
          "visionSubject": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "displayName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          }
        }
      },
      "ActorBinding": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "publicReference",
          "visionSubject",
          "displayName",
          "timezone",
          "status",
          "recordVersion"
        ],
        "properties": {
          "schemaVersion": {
            "const": "vision-calendar-actor-binding.v1"
          },
          "publicReference": {
            "type": "string",
            "pattern": "^ACT-[A-Z0-9]{12}$"
          },
          "visionSubject": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "status": {
            "const": "active"
          },
          "recordVersion": {
            "type": "integer",
            "minimum": 1
          }
        }
      },
      "CommandResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "operation",
          "outcome",
          "publicReference",
          "recordVersion",
          "replayed"
        ],
        "properties": {
          "schemaVersion": {
            "const": "vision-calendar-command-result.v1"
          },
          "operation": {
            "enum": [
              "event.create",
              "event.update",
              "event.cancel",
              "hold.create",
              "hold.release",
              "attendance.respond",
              "recurrence.exception.cancel",
              "recurrence.exception.modify"
            ]
          },
          "outcome": {
            "const": "succeeded"
          },
          "publicReference": {
            "type": "string"
          },
          "recordVersion": {
            "type": "integer",
            "minimum": 1
          },
          "replayed": {
            "type": "boolean"
          }
        }
      },
      "AvailabilitySlotsQuery": {
        "type": "object",
        "additionalProperties": false,
        "required": ["actorReferences", "from", "to", "durationMinutes"],
        "properties": {
          "actorReferences": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/ActorReference"
            }
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time",
            "description": "Must be after from; the range cannot exceed 93 days."
          },
          "durationMinutes": {
            "type": "integer",
            "minimum": 5,
            "maximum": 1440,
            "description": "Length of the meeting being offered."
          },
          "slotIntervalMinutes": {
            "type": "integer",
            "minimum": 5,
            "maximum": 1440,
            "description": "Grid spacing. Defaults to durationMinutes, giving back-to-back slots. Set smaller for overlapping offers."
          },
          "requirement": {
            "type": "string",
            "enum": ["any", "all"],
            "default": "any",
            "description": "any: at least one requested actor is free for the whole slot (round-robin booking). all: every requested actor is free (panel booking)."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 500,
            "default": 100
          }
        }
      },
      "AvailabilitySlots": {
        "type": "object",
        "required": [
          "schemaVersion",
          "range",
          "durationMinutes",
          "requirement",
          "slots"
        ],
        "properties": {
          "schemaVersion": {
            "const": "vision-calendar-availability-slots.v1"
          },
          "range": {
            "type": "object",
            "required": ["from", "to"],
            "properties": {
              "from": {
                "type": "string",
                "format": "date-time"
              },
              "to": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "durationMinutes": {
            "type": "integer"
          },
          "requirement": {
            "type": "string",
            "enum": ["any", "all"]
          },
          "slots": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["startsAt", "endsAt", "actorReferences"],
              "properties": {
                "startsAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "endsAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "actorReferences": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ActorReference"
                  },
                  "description": "Every requested actor free for this slot. With requirement=any this may be a subset; the caller picks, or assigns round-robin."
                }
              }
            }
          }
        }
      },
      "WeeklyScheduleWeek": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "monday": {
            "type": "array",
            "maxItems": 6,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["start", "end"],
              "properties": {
                "start": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                },
                "end": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                }
              }
            }
          },
          "tuesday": {
            "type": "array",
            "maxItems": 6,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["start", "end"],
              "properties": {
                "start": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                },
                "end": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                }
              }
            }
          },
          "wednesday": {
            "type": "array",
            "maxItems": 6,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["start", "end"],
              "properties": {
                "start": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                },
                "end": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                }
              }
            }
          },
          "thursday": {
            "type": "array",
            "maxItems": 6,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["start", "end"],
              "properties": {
                "start": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                },
                "end": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                }
              }
            }
          },
          "friday": {
            "type": "array",
            "maxItems": 6,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["start", "end"],
              "properties": {
                "start": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                },
                "end": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                }
              }
            }
          },
          "saturday": {
            "type": "array",
            "maxItems": 6,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["start", "end"],
              "properties": {
                "start": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                },
                "end": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                }
              }
            }
          },
          "sunday": {
            "type": "array",
            "maxItems": 6,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["start", "end"],
              "properties": {
                "start": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                },
                "end": {
                  "type": "string",
                  "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                }
              }
            }
          }
        }
      },
      "AvailabilityCommand": {
        "oneOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "required": ["operation", "timezone", "week"],
            "properties": {
              "operation": {
                "const": "policy.set"
              },
              "actorReference": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/ActorReference"
                  }
                ],
                "description": "Omit or null for the calling actor."
              },
              "timezone": {
                "type": "string"
              },
              "week": {
                "$ref": "#/components/schemas/WeeklyScheduleWeek"
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": ["operation", "startsAt", "endsAt", "availability"],
            "properties": {
              "operation": {
                "const": "exception.create"
              },
              "actorReference": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/ActorReference"
                  }
                ]
              },
              "startsAt": {
                "type": "string",
                "format": "date-time"
              },
              "endsAt": {
                "type": "string",
                "format": "date-time"
              },
              "availability": {
                "type": "string",
                "enum": ["available", "unavailable"]
              },
              "operationalLabel": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "string",
                    "maxLength": 160
                  }
                ],
                "description": "Operational facts only. Calendar owns the availability block, not the HR or medical record."
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": ["operation", "exceptionReference", "expectedVersion"],
            "properties": {
              "operation": {
                "const": "exception.delete"
              },
              "exceptionReference": {
                "type": "string",
                "pattern": "^AVX-[A-Z0-9]{12}$"
              },
              "expectedVersion": {
                "type": "integer",
                "minimum": 1
              }
            }
          }
        ]
      },
      "CalendarPresentation": {
        "type": "object",
        "required": [
          "schemaVersion",
          "appId",
          "navigation",
          "settings",
          "views",
          "actions"
        ],
        "properties": {
          "schemaVersion": {
            "const": "vision-calendar-presentation.v1"
          },
          "appId": {
            "const": "calendar"
          },
          "navigation": {
            "type": "object",
            "required": ["label", "icon", "landing", "sections"],
            "properties": {
              "label": {
                "type": "string"
              },
              "icon": {
                "type": "string"
              },
              "landing": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "string"
                  }
                ],
                "description": "Resolved AFTER filtering; null when the caller can reach no section."
              },
              "sections": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PresentationSection"
                }
              }
            }
          },
          "settings": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "required": ["label", "icon", "sections"],
                "properties": {
                  "label": {
                    "type": "string"
                  },
                  "icon": {
                    "type": "string"
                  },
                  "sections": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/PresentationSection"
                    }
                  }
                }
              }
            ],
            "description": "null rather than an empty shell when the caller may reach no settings section."
          },
          "views": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "PresentationSection": {
        "type": "object",
        "required": [
          "id",
          "label",
          "icon",
          "route",
          "order",
          "requiredScope",
          "badge"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "icon": {
            "type": "string"
          },
          "route": {
            "type": "string"
          },
          "order": {
            "type": "integer"
          },
          "requiredScope": {
            "type": "string"
          },
          "badge": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "required": ["source", "field", "tone"],
                "properties": {
                  "source": {
                    "type": "string"
                  },
                  "field": {
                    "type": "string"
                  },
                  "tone": {
                    "type": "string",
                    "enum": ["neutral", "attention", "urgent"]
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  "security": [
    {
      "visionBearer": []
    }
  ]
}
