---
"$schema": http://json-schema.org/draft-07/schema#
"$id": https://github.com/edoxen/edoxen-model/schema/meeting.yaml
title: Edoxen Meeting Schema
description: |
  Schema for validating Edoxen Meeting/Agenda YAML files.

  Mirrors the canonical LutaML information model in
  https://github.com/edoxen/edoxen-model/tree/main/models (meeting*.lutaml,
  agenda*.lutaml, etc.).

  The root accepts either a single Meeting or a MeetingCollection.

  Enum lists in this schema are kept in lockstep with
  Edoxen::Enums::* (Meeting side) by
  `spec/edoxen/schema_meeting_enum_sync_spec.rb`.
type: object
oneOf:
- "$ref": "#/$defs/MeetingCollection"
- "$ref": "#/$defs/Meeting"
- "$ref": "#/$defs/MeetingSeries"
"$defs":
  StructuredIdentifier:
    type: object
    description: An identifier (prefix + number). A Decision carries 1..* of these.
    additionalProperties: false
    required:
    - prefix
    - number
    properties:
      prefix:
        type: string
      number:
        type: string
  EntityRef:
    type: object
    description: |
      Typed cross-reference between entities (1.0, TODO.refactor/1.0-design).
      Exactly one of `urn`, `identifier`, or `local_ref` should be set;
      the gem's `EntityRef#valid?` enforces this in Ruby.
    additionalProperties: false
    properties:
      urn:
        type: string
      identifier:
        "$ref": "#/$defs/StructuredIdentifier"
      local_ref:
        type: string
      kind:
        type: string
      role:
        type: string
      note:
        type: string
  SourceUrl:
    type: object
    description: Per-spelling canonical source URL (e.g. one PDF per language).
    additionalProperties: false
    required:
    - ref
    properties:
      ref:
        type: string
      format:
        type: string
      spelling:
        type: string
        description: ISO 24229 spelling/conversion system code
      kind:
        "$ref": "#/$defs/SourceUrlKind"
  DateRange:
    type: object
    description: Start + end date pair for multi-day meetings.
    additionalProperties: false
    properties:
      start:
        type: string
        format: date
      end:
        type: string
        format: date
  ContactMethodKind:
    type: string
    description: Polymorphic communication channel kind.
    enum:
    - phone
    - mobile
    - fax
    - email
    - url
    - mail
    - pager
    - message
    - other
  LocalizedString:
    type: object
    description: |
      One language-specific value of a translatable String field.
      `spelling` is an ISO 24229 spelling/conversion system code.
      Always verbose — single-language data uses the same
      `[{ spelling, value }]` shape as multi-language data.
    additionalProperties: false
    required:
    - spelling
    - value
    properties:
      spelling:
        type: string
      value:
        type: string
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  LocalizedName:
    type: object
    description: |
      One language-specific value of a translatable Name field.
      Mirrors LocalizedString but carries a structured Name.
    additionalProperties: false
    required:
    - spelling
    - value
    properties:
      spelling:
        type: string
      value:
        "$ref": "#/$defs/Name"
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  ContactMethod:
    type: object
    description: |
      One polymorphic communication channel — phone, email, fax, url,
      mail, etc. `kind` discriminates the channel; `value` carries the
      address/number; `label` is a free-form display hint ("Office",
      "Front desk"). OCP: new channel kinds are added via the
      ContactMethodKind enum (or `other` + extensions).
    additionalProperties: false
    properties:
      kind:
        "$ref": "#/$defs/ContactMethodKind"
      value:
        type: string
      label:
        type: string
      primary:
        type: boolean
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  ContactIdentifierKind:
    type: string
    description: Polymorphic external identifier scheme for a Contact.
    enum:
    - orcid
    - isni
    - wikidata
    - ror
    - ringgold
    - github
    - other
  ContactIdentifier:
    type: object
    description: |
      One polymorphic external identifier — ORCID, ISNI, Wikidata QID,
      ROR, Ringgold, GitHub handle, etc. Replaces the hard-coded `orcid`
      field. OCP: new identifier schemes are added via the
      ContactIdentifierKind enum (or `other` + extensions).
    additionalProperties: false
    properties:
      kind:
        "$ref": "#/$defs/ContactIdentifierKind"
      value:
        type: string
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  Name:
    type: object
    description: |
      Structured personal/organisational name (VCARD RFC 6350
      conventions). `formatted` is the pre-built display string (FN);
      the structured components (N) are stored separately for sorting,
      indexing, or locale-aware rendering.
    additionalProperties: false
    properties:
      formatted:
        type: string
      family:
        type: string
      given:
        type: string
      additional:
        type: string
      prefix:
        type: string
      suffix:
        type: string
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  Contact:
    type: object
    description: |
      VCARD-like abstract contact. 1.0: per-field Localized
      (name, title, affiliation, address). Added `urn` (registry
      identity) and `ref` (reference-by-URN).
    additionalProperties: false
    properties:
      ref:
        type: string
      local_ref:
        type: string
      urn:
        type: string
        pattern: "^urn:edoxen:contact:[^:]+:[^:]+$"
      name:
        type: array
        items:
          "$ref": "#/$defs/LocalizedName"
      kind:
        type: string
      role:
        type: string
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      affiliation:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      contact_methods:
        type: array
        items:
          "$ref": "#/$defs/ContactMethod"
      identifiers:
        type: array
        items:
          "$ref": "#/$defs/ContactIdentifier"
      address:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  Person:
    type: object
    description: |
      A Contact that is specifically an individual human. Schema
      duplicates Contact's properties because JSON-Schema draft-07
      doesn't support `extends`. Same shape; semantically a subclass.
    additionalProperties: false
    properties:
      ref:
        type: string
      local_ref:
        type: string
      urn:
        type: string
        pattern: "^urn:edoxen:contact:[^:]+:[^:]+$"
      name:
        type: array
        items:
          "$ref": "#/$defs/LocalizedName"
      kind:
        type: string
      role:
        type: string
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      affiliation:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      contact_methods:
        type: array
        items:
          "$ref": "#/$defs/ContactMethod"
      identifiers:
        type: array
        items:
          "$ref": "#/$defs/ContactIdentifier"
      address:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  HostRef:
    type: object
    description: Typed reference to a hosting organization.
    additionalProperties: false
    required:
    - ref
    properties:
      ref:
        type: string
      type:
        "$ref": "#/$defs/HostType"
      role:
        type: string
      contact:
        "$ref": "#/$defs/Contact"
  Attendance:
    type: object
    description: One attendance record per person at a Meeting.
    additionalProperties: false
    required:
    - person
    - status
    properties:
      person:
        "$ref": "#/$defs/Person"
      status:
        "$ref": "#/$defs/ParticipationStatus"
      role:
        "$ref": "#/$defs/AttendanceRole"
      response:
        "$ref": "#/$defs/AttendanceResponse"
      affiliation:
        type: string
      proxy_for:
        "$ref": "#/$defs/Person"
      notes:
        type: string
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  VoteRecord:
    type: object
    description: One vote by one person on one decision/voting.
    additionalProperties: false
    required:
    - person
    - vote
    properties:
      decision_ref:
        type: string
      voting_ref:
        type: string
      person:
        "$ref": "#/$defs/Person"
      affiliation:
        type: string
      vote:
        "$ref": "#/$defs/VoteType"
      role:
        type: string
      notes:
        type: string
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  MinutesSection:
    type: object
    description: 'One section of a Meeting''s minutes — typically tied to an agenda item by `number`. 1.0: per-field Localized.'
    additionalProperties: false
    properties:
      number:
        type: string
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      narrative:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      page_start:
        type: integer
      page_end:
        type: integer
      references:
        type: array
        items:
          "$ref": "#/$defs/Reference"
      statements:
        type: array
        items:
          "$ref": "#/$defs/Statement"
      topic_ref:
        type: string
        description: |
          URN back-reference to the Topic this section records.
          Optional; formalises the convention that
          `MinutesSection#number` matches `AgendaItem#label`.
  Minutes:
    type: object
    description: |
      The narrative record of a Meeting. 1.0: per-document language_code
      + script replaced by a single `spelling` (ISO 24229).
    additionalProperties: false
    properties:
      identifier:
        type: array
        items:
          "$ref": "#/$defs/StructuredIdentifier"
      urn:
        type: string
      spelling:
        type: string
        description: ISO 24229 spelling/conversion system code
      source_doc:
        type: string
      source_pages:
        type: string
      sections:
        type: array
        items:
          "$ref": "#/$defs/MinutesSection"
  Deadline:
    type: object
    description: 'A time-bound requirement. 1.0: per-field Localized.'
    additionalProperties: false
    required:
    - date
    properties:
      date:
        type: string
        format: date
      description:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
  Reference:
    type: object
    description: Generic document reference.
    additionalProperties: false
    properties:
      ref:
        type: string
      kind:
        type: string
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
  AgendaItem:
    type: object
    description: |
      One entry on an Agenda. 1.0: per-field Localized.
      `urn` is the first-class URN of this item, derived from the
      parent meeting URN and label (e.g.
      `urn:oiml:ciml:meeting:ciml-60:agenda:6.2`). Optional in source
      data; can be computed via `Edoxen::UrnFor.agenda_item`.
    additionalProperties: false
    properties:
      urn:
        type: string
        description: |
          First-class URN for this agenda item. Hierarchical under the
          parent meeting URN: `urn:oiml:{body}:meeting:{slug}:agenda:{label}`.
      label:
        type: string
      kind:
        "$ref": "#/$defs/AgendaItemKind"
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      description:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      references:
        type: array
        items:
          "$ref": "#/$defs/Reference"
      outcome:
        "$ref": "#/$defs/AgendaItemOutcome"
      decision_ref:
        type: string
      topics:
        type: array
        items:
          "$ref": "#/$defs/Topic"
      components:
        type: array
        items:
          type: string
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  Agenda:
    type: object
    description: |
      The business-order document of a Meeting. Versioned independently
      of the Meeting via the `status` field (draft, final, amended).
    additionalProperties: false
    properties:
      identifier:
        type: array
        items:
          "$ref": "#/$defs/StructuredIdentifier"
      status:
        "$ref": "#/$defs/AgendaStatus"
      source_doc:
        type: string
      items:
        type: array
        items:
          "$ref": "#/$defs/AgendaItem"
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  TopicDocument:
    type: object
    description: 'Text-bearing document about a Topic. 1.0: per-field Localized.'
    additionalProperties: false
    properties:
      identifier:
        type: string
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      version:
        type: string
      status:
        type: string
      url:
        type: string
      format:
        type: string
      spelling:
        type: string
        description: ISO 24229 spelling/conversion system code
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  TopicAsset:
    type: object
    description: 'Non-text resource about a Topic. 1.0: per-field Localized.'
    additionalProperties: false
    properties:
      identifier:
        type: string
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      kind:
        type: string
      url:
        type: string
      format:
        type: string
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  Topic:
    type: object
    description: 'The subject of discussion at a Meeting. 1.0: per-field Localized.'
    additionalProperties: false
    properties:
      identifier:
        type: string
      urn:
        type: string
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      description:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      status:
        "$ref": "#/$defs/TopicStatus"
      resumption_of:
        type: string
      documents:
        type: array
        items:
          "$ref": "#/$defs/TopicDocument"
      assets:
        type: array
        items:
          "$ref": "#/$defs/TopicAsset"
      references:
        type: array
        items:
          "$ref": "#/$defs/Reference"
      motions:
        type: array
        items:
          type: string
      decisions:
        type: array
        items:
          type: string
      statements:
        type: array
        items:
          "$ref": "#/$defs/Statement"
      declarations:
        type: array
        items:
          "$ref": "#/$defs/Declaration"
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  Venue:
    type: object
    description: |
      Polymorphic place where a Meeting happens. `kind` discriminates
      physical vs virtual; all fields from both subtypes live here as
      optional siblings. 1.0: per-field Localized (name, label,
      description, address, building, floor, room, access_notes).
      Added `urn` (registry identity) and `ref` (reference-by-URN).
    additionalProperties: false
    properties:
      ref:
        type: string
      local_ref:
        type: string
      urn:
        type: string
        pattern: "^urn:edoxen:venue:[^:]+:[^:]+$"
      kind:
        "$ref": "#/$defs/VenueKind"
      name:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      label:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      description:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      capacity:
        type: integer
      url:
        type: string
      contact_methods:
        type: array
        items:
          "$ref": "#/$defs/ContactMethod"
      unlocode:
        type: string
        pattern: "^[A-Z]{2}[A-Z0-9]{3}$"
      iata_code:
        type: string
        pattern: "^[A-Z]{3}$"
      address:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      city:
        type: string
      country_code:
        type: string
        pattern: "^[A-Z]{2}$"
      lat:
        type: number
      lon:
        type: number
      building:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      floor:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      room:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      access_notes:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      uri:
        type: string
      features:
        type: array
        items:
          "$ref": "#/$defs/VirtualFeature"
      passcode:
        type: string
      meeting_id:
        type: string
      dial_in_numbers:
        type: array
        items:
          type: string
      waiting_room:
        type: boolean
      registration_required:
        type: boolean
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  RecurrenceByDay:
    type: object
    description: BYDAY part of a recurrence. `ordinal` is null for 'every', +1 for first, -1 for last.
    additionalProperties: false
    properties:
      ordinal:
        type: integer
      weekday:
        type: string
  Recurrence:
    type: object
    description: Structured ISO 8601-2 §13 recurrence.
    additionalProperties: false
    properties:
      freq:
        "$ref": "#/$defs/RecurrenceFreq"
      interval:
        type: integer
      count:
        type: integer
      until:
        type: string
        format: date-time
      by_day:
        type: array
        items:
          "$ref": "#/$defs/RecurrenceByDay"
      by_month_day:
        type: array
        items:
          type: integer
      by_month:
        type: array
        items:
          type: integer
      by_week_no:
        type: array
        items:
          type: integer
      by_year_day:
        type: array
        items:
          type: integer
      by_hour:
        type: array
        items:
          type: integer
      by_minute:
        type: array
        items:
          type: integer
      by_second:
        type: array
        items:
          type: integer
      by_set_pos:
        type: array
        items:
          type: integer
      week_start:
        type: string
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  ExtensionAttribute:
    type: object
    description: |
      One typed key/value pair within a MeetingExtension. Polymorphic on
      value type so consumers don't re-parse strings back into Int/Float/
      Bool/Date (1.0 tighten, TODO.refactor/1.0-design).
    additionalProperties: false
    properties:
      key:
        type: string
      type:
        type: string
        enum:
        - string
        - integer
        - float
        - boolean
        - date
        - datetime
      value:
        type: string
      intValue:
        type: integer
      floatValue:
        type: number
      booleanValue:
        type: boolean
      dateValue:
        type: string
        format: date
      dateTimeValue:
        type: string
        format: date-time
  MeetingExtension:
    type: object
    description: |
      Profile-specific extension. Adopters register their namespace via
      `profile` and discriminate via `kind`. Field semantics tightened
      1.0 (TODO.refactor/1.0-design): `kind` is the in-profile discriminator,
      `ref` is the URN of an external profile document, and the
      recursive `extensions[]` slot was removed (YAGNI — use dotted
      keys in `attributes[]` for nesting).
    additionalProperties: false
    properties:
      profile:
        type: string
      kind:
        type: string
      ref:
        type: string
      attributes:
        type: array
        items:
          "$ref": "#/$defs/ExtensionAttribute"
  Officer:
    type: object
    description: A person holding a structural role in a Meeting.
    additionalProperties: false
    properties:
      role:
        "$ref": "#/$defs/OfficerRole"
      person:
        "$ref": "#/$defs/Person"
      term_start:
        type: string
        format: date
      term_end:
        type: string
        format: date
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  MeetingComponent:
    type: object
    description: 'Flat sub-event of a Meeting. 1.0: per-field Localized.'
    additionalProperties: false
    properties:
      identifier:
        type: string
      urn:
        type: string
      kind:
        "$ref": "#/$defs/ComponentKind"
      body_type:
        type: string
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      description:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      starts_at:
        type: string
        format: date-time
      ends_at:
        type: string
        format: date-time
      time_label:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      venue_refs:
        type: array
        items:
          type: string
      officers:
        type: array
        items:
          "$ref": "#/$defs/Officer"
      agenda_ref:
        type: string
      minutes_ref:
        type: string
      attendance_refs:
        type: array
        items:
          type: string
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  MeetingSeries:
    type: object
    description: 'Parent of recurring Meeting instances. 1.0: per-field Localized.'
    additionalProperties: false
    properties:
      identifier:
        type: array
        items:
          "$ref": "#/$defs/StructuredIdentifier"
      urn:
        type: string
      name:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      description:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      recurrence:
        "$ref": "#/$defs/Recurrence"
      term:
        type: string
      contact:
        "$ref": "#/$defs/Contact"
      hosts:
        type: array
        items:
          "$ref": "#/$defs/HostRef"
      kind:
        type: string
      meeting_refs:
        type: array
        items:
          type: string
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
      body_type:
        type: string
  MeetingRelation:
    type: object
    description: Directed link between two meetings.
    additionalProperties: false
    required:
    - source
    - destination
    - type
    properties:
      source:
        "$ref": "#/$defs/StructuredIdentifier"
      destination:
        "$ref": "#/$defs/StructuredIdentifier"
      type:
        "$ref": "#/$defs/MeetingRelationType"
  Meeting:
    type: object
    description: 'A single Meeting (event). 1.0: per-field Localized.'
    additionalProperties: false
    required:
    - identifier
    - type
    properties:
      identifier:
        type: array
        minItems: 1
        items:
          "$ref": "#/$defs/StructuredIdentifier"
      urn:
        type: string
      ordinal:
        type: integer
      series_ref:
        type: string
      type:
        "$ref": "#/$defs/MeetingType"
      status:
        "$ref": "#/$defs/MeetingStatus"
      visibility:
        "$ref": "#/$defs/Visibility"
      body_type:
        type: string
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      scheduled_date_range:
        "$ref": "#/$defs/DateRange"
      occurred_date_range:
        "$ref": "#/$defs/DateTimeRange"
      recurrence:
        "$ref": "#/$defs/Recurrence"
      venues:
        type: array
        items:
          "$ref": "#/$defs/Venue"
      general_area:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      practical_info:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      city:
        type: string
        pattern: "^[A-Z]{2}[A-Z0-9]{3}$"
      country_code:
        type: string
        pattern: "^[A-Z]{2}$"
      committee:
        "$ref": "#/$defs/Body"
      committee_group:
        "$ref": "#/$defs/Body"
      officers:
        type: array
        items:
          "$ref": "#/$defs/Officer"
      hosts:
        type: array
        items:
          "$ref": "#/$defs/HostRef"
      source_urls:
        type: array
        items:
          "$ref": "#/$defs/SourceUrl"
      landing_url:
        type: string
      registration_url:
        type: string
      note:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      contact:
        "$ref": "#/$defs/Contact"
      contacts:
        type: array
        items:
          "$ref": "#/$defs/Contact"
      bodies:
        type: array
        items:
          "$ref": "#/$defs/Body"
      agenda:
        "$ref": "#/$defs/Agenda"
      components:
        type: array
        items:
          "$ref": "#/$defs/MeetingComponent"
      deadlines:
        type: array
        items:
          "$ref": "#/$defs/Deadline"
      attendance:
        type: array
        items:
          "$ref": "#/$defs/Attendance"
      minutes:
        type: array
        items:
          "$ref": "#/$defs/Minutes"
      declarations:
        type: array
        items:
          "$ref": "#/$defs/Declaration"
      decisions:
        type: array
        items:
          "$ref": "#/$defs/StructuredIdentifier"
      motions:
        type: array
        items:
          "$ref": "#/$defs/StructuredIdentifier"
      votings:
        type: array
        items:
          "$ref": "#/$defs/StructuredIdentifier"
      relations:
        type: array
        items:
          "$ref": "#/$defs/MeetingRelation"
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  MeetingCollectionMetadata:
    type: object
    description: 'Display-level metadata for a MeetingCollection. 1.0: per-field Localized.'
    additionalProperties: false
    properties:
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      source:
        type: string
      body_vocabulary:
        type: array
        items:
          "$ref": "#/$defs/BodyVocabularyEntry"
  BodyVocabularyEntry:
    type: object
    description: |
      One entry in a per-dataset body_vocabulary list. Maps a free-form
      body_type to a short canonical value. SSOT for body_type ->
      canonical_type resolution within the declaring collection.
    additionalProperties: false
    properties:
      body_type:
        type: string
      canonical_type:
        type: string
      definition:
        type: string
  MeetingCollection:
    type: object
    description: Top-level wrapper for many Meetings in one file.
    additionalProperties: false
    required:
    - meetings
    properties:
      metadata:
        "$ref": "#/$defs/MeetingCollectionMetadata"
      meetings:
        type: array
        items:
          "$ref": "#/$defs/Meeting"
  MeetingType:
    type: string
    description: Edoxen::Enums::MEETING_TYPE.
    enum:
    - plenary
    - working_group
    - task_group
    - ad_hoc
    - joint
    - general_assembly
    - committee
    - subcommittee
    - conference
    - workshop
    - seminar
    - webinar
    - hearing
    - markup
    - board_meeting
    - annual_general_meeting
    - other
  MeetingTypeCanonical:
    type: string
    description: |
      Edoxen::Enums::MEETING_TYPE_CANONICAL — short abstract set (1.0,
      TODO.refactor/1.0-design). No `other` escape — bodies pick the closest
      fit and use `body_type` for body-specific terminology.
    enum:
    - plenary
    - governing
    - working
    - advisory
  MeetingStatus:
    type: string
    description: Edoxen::Enums::MEETING_STATUS.
    enum:
    - upcoming
    - completed
    - cancelled
  AgendaStatus:
    type: string
    description: Edoxen::Enums::AGENDA_STATUS.
    enum:
    - draft
    - final
    - amended
    - cancelled
    - superseded
  AgendaItemKind:
    type: string
    description: Edoxen::Enums::AGENDA_ITEM_KIND.
    enum:
    - numbered
    - unnumbered
    - header
    - opening
    - closing
    - aob
  AgendaItemOutcome:
    type: string
    description: Edoxen::Enums::AGENDA_ITEM_OUTCOME.
    enum:
    - discussed
    - resolved
    - deferred
    - adopted
    - withdrawn
    - carried
    - negatived
  HostType:
    type: string
    description: Edoxen::Enums::HOST_TYPE.
    enum:
    - national_body
    - liaison
    - associate
    - organizer
  MeetingRelationType:
    type: string
    description: Edoxen::Enums::MEETING_RELATION_TYPE.
    enum:
    - continues_from
    - continues_to
    - joint_with
    - supersedes
    - superseded_by
    - rescheduled_from
    - rescheduled_to
    - parent_of
    - child_of
    - sibling_of
    - depends_on
    - finish_to_start
    - finish_to_finish
    - start_to_start
    - start_to_finish
  SourceUrlKind:
    type: string
    description: Edoxen::Enums::SOURCE_URL_KIND.
    enum:
    - agenda_pdf
    - minutes_pdf
    - decisions_pdf
    - report_pdf
    - register_url
    - landing_page
  ParticipationStatus:
    type: string
    description: Edoxen::Enums::PARTICIPATION_STATUS.
    enum:
    - present
    - absent
    - apologies
    - observer
    - excused
  AttendanceRole:
    type: string
    description: Edoxen::Enums::ATTENDANCE_ROLE.
    enum:
    - chair
    - required
    - optional
    - non_participant
  AttendanceResponse:
    type: string
    description: Edoxen::Enums::ATTENDANCE_RESPONSE.
    enum:
    - pending
    - confirmed
    - declined
    - tentative
    - delegated
  VoteType:
    type: string
    description: Edoxen::Enums::VOTE_TYPE.
    enum:
    - affirmative
    - negative
    - abstain
    - absent
    - not_applicable
  TopicStatus:
    type: string
    description: Edoxen::Enums::TOPIC_STATUS.
    enum:
    - open
    - under_discussion
    - decided
    - deferred
    - withdrawn
  VenueKind:
    type: string
    description: Edoxen::Enums::VENUE_KIND.
    enum:
    - physical
    - virtual
  VirtualFeature:
    type: string
    description: Edoxen::Enums::VIRTUAL_FEATURE.
    enum:
    - audio
    - video
    - chat
    - phone
    - screen
    - feed
  Visibility:
    type: string
    description: Edoxen::Enums::VISIBILITY.
    enum:
    - public
    - private
    - confidential
  ComponentKind:
    type: string
    description: Edoxen::Enums::COMPONENT_KIND.
    enum:
    - track
    - session
    - debate
    - breakout
    - bof
    - plenary_session
    - working_group_session
    - committee_of_the_whole
    - keynote
    - address
    - statement
    - question_time
    - opening
    - closing
    - break
    - reception
    - registration
    - networking
    - other
  OfficerRole:
    type: string
    description: Edoxen::Enums::OFFICER_ROLE.
    enum:
    - chair
    - vice_chair
    - deputy_chair
    - secretary
    - treasurer
    - parliamentarian
    - presiding_officer
    - sergeant_at_arms
    - other
  RecurrenceFreq:
    type: string
    description: Edoxen::Enums::RECURRENCE_FREQ.
    enum:
    - secondly
    - minutely
    - hourly
    - daily
    - weekly
    - monthly
    - yearly
  DateTimeRange:
    type: object
    description: |
      Start + end pair with sub-day precision. Parallel to DateRange;
      use when day granularity is insufficient (e.g. a meeting that
      ran 09:00–11:30).
    additionalProperties: false
    properties:
      start:
        type: string
        format: date-time
      end:
        type: string
        format: date-time
  StatementKind:
    type: string
    description: |
      Discriminator for the three BS 0:2006 statement types. Adding a
      new kind is a one-line enum extension; the Statement model
      itself never needs to change (OCP).
    enum:
    - statement
    - comment
    - standpoint
  DeclarationKind:
    type: string
    description: |
      Discriminator for the two BS 0:2006 declaration types
      (conflict of interest, IPR).
    enum:
    - conflict_of_interest
    - ipr
  Statement:
    type: object
    description: |
      One remark made by one or more meeting members on a topic or a
      minutes section. Per-field Localized description; party is a
      list of Person references. The `kind` discriminator separates
      the three BS 0:2006 statement types.
    additionalProperties: false
    properties:
      kind:
        "$ref": "#/$defs/StatementKind"
      description:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      party:
        type: array
        items:
          "$ref": "#/$defs/Person"
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  Declaration:
    type: object
    description: |
      A formal declaration (conflict of interest or IPR) made by one
      or more meeting members. IPR-specific fields (`ipr_subject_ref`,
      `ipr_target_ref`) are populated only when `kind == "ipr"`.
    additionalProperties: false
    properties:
      kind:
        "$ref": "#/$defs/DeclarationKind"
      description:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      party:
        type: array
        items:
          "$ref": "#/$defs/Person"
      ipr_subject_ref:
        "$ref": "#/$defs/EntityRef"
      ipr_target_ref:
        "$ref": "#/$defs/EntityRef"
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  Body:
    type: object
    description: |
      A committee, subcommittee, working group, or other organised body.
      Three-tier entity resolution (ref / local_ref / inline).
    additionalProperties: false
    properties:
      ref:
        type: string
      local_ref:
        type: string
      code:
        type: string
      name:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      kind:
        type: string
      parent_ref:
        "$ref": "#/$defs/EntityRef"
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
  BodyRegister:
    type: object
    description: |
      Authoritative register of Bodies (committees, subcommittees,
      working groups).
    additionalProperties: false
    properties:
      scope:
        type: string
      title:
        type: array
        items:
          "$ref": "#/$defs/LocalizedString"
      bodies:
        type: array
        items:
          "$ref": "#/$defs/Body"
      extensions:
        type: array
        items:
          "$ref": "#/$defs/MeetingExtension"
