{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:hos:schema:0.1:producer-manifest",
  "title": "HOS 0.1 Event Producer manifest",
  "description": "Draft. A producer's versioned statement of exactly what it produces and authoritatively controls: events, dimensions, authority, snapshot support, delivery, replay, retention and known limitations. Public systems publish it at /.well-known/hos/manifest.json; private systems may use a configured authenticated URL. At most one producer may be authoritative for a given event type and dimension at a property. The manifest carries no signature: its producer signs it with a detached JWS, published beside it at /.well-known/hos/manifest.jws, and publishes its keys at /.well-known/hos/jwks.json.",
  "type": "object",
  "required": [
    "hosmanifestversion",
    "producer",
    "name",
    "organization",
    "system_role",
    "property_ids",
    "events",
    "delivery",
    "replay",
    "retention",
    "limitations"
  ],
  "properties": {
    "hosmanifestversion": {
      "const": "0.1"
    },
    "producer": {
      "type": "string",
      "format": "uri",
      "description": "Must equal the source attribute of every event the producer emits."
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "organization": {
      "type": "object",
      "required": ["name"],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "url": {
          "type": "string",
          "format": "uri"
        }
      },
      "additionalProperties": false
    },
    "system_role": {
      "enum": ["pms", "housekeeping", "maintenance", "messaging", "integration", "other"]
    },
    "property_ids": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "$ref": "urn:hos:schema:0.1:core#/$defs/hosId"
      }
    },
    "entities": {
      "type": "array",
      "uniqueItems": true,
      "items": {
        "enum": [
          "Tenant",
          "Property",
          "Unit",
          "MaintenanceWindow",
          "Reservation",
          "Stay",
          "Task",
          "Guest",
          "Message"
        ]
      },
      "description": "Core entities the producer exposes."
    },
    "events": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["type", "authoritative"],
        "properties": {
          "type": {
            "enum": [
              "reservation.created",
              "reservation.updated",
              "reservation.cancelled",
              "stay.expected",
              "stay.checked_in",
              "stay.check_in_reverted",
              "stay.checked_out",
              "stay.unit_assigned",
              "stay.unit_unassigned",
              "unit.status_changed",
              "unit.maintenance_scheduled",
              "unit.maintenance_cancelled",
              "housekeeping.task.created",
              "housekeeping.task.completed",
              "guest.message.received"
            ]
          },
          "dimensions": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "urn:hos:schema:0.1:core#/$defs/unitStatusDimension"
            },
            "description": "For unit.status_changed: the dimensions this declaration covers."
          },
          "authoritative": {
            "type": "boolean",
            "description": "true when this producer is the system of record for the event type (and dimensions) at the declared properties. Non-authoritative facts are recorded and shown, never merged into the authoritative value."
          },
          "snapshot": {
            "type": "boolean",
            "description": "true when the producer may send this type in snapshot mode. Snapshots from a producer that does not declare them are ignored."
          },
          "note": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    },
    "delivery": {
      "type": "object",
      "required": ["mechanisms", "guarantee", "ordering"],
      "properties": {
        "mechanisms": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "enum": ["webhook", "polling", "stream", "file"]
          }
        },
        "guarantee": {
          "const": "at-least-once",
          "description": "HOS delivery is at-least-once; consumers deduplicate on source and id."
        },
        "ordering": {
          "enum": ["none", "per-subject", "total"],
          "description": "Ordering is never global; it holds only as declared here."
        }
      },
      "additionalProperties": false
    },
    "replay": {
      "type": "object",
      "required": ["supported"],
      "properties": {
        "supported": {
          "type": "boolean"
        },
        "window_days": {
          "type": "integer",
          "minimum": 0,
          "description": "A certified Event Producer profile provides at least 30 days."
        },
        "format": {
          "const": "jsonl",
          "description": "Replays are JSON Lines: one event per line, in delivery order."
        }
      },
      "additionalProperties": false
    },
    "retention": {
      "type": "object",
      "required": ["event_days"],
      "properties": {
        "event_days": {
          "type": "integer",
          "minimum": 0
        }
      },
      "additionalProperties": false
    },
    "limitations": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "description": "Known gaps, unsupported states and access constraints, stated explicitly. Empty only when there are none."
    }
  },
  "additionalProperties": false
}
