# FILE: spec/part-03-information-model/INFORMATION-MODEL.yaml
# =====================================================================
# Rocom — Part 3: Information Model
# Status: ADOPTED 1.0, Edition 2026a
# License: CC-BY 4.0 (see LICENSE-SPEC)
# Scope: Core data types referenced by Parts 4, 5, 6, 7.
#        Contracts and profiles MUST use these types verbatim.
#
# Correction proposals incorporated:
#   CP-007 — Agent Identity Model (issuer-agnostic, UDI-aligned)
#     Status: MERGED. See spec/cp-007-agent-identity.md
#   CP-008 — Resource Authority Model
#     Status: MERGED. See spec/cp-008-resource-authority.md
#   CP-009 — Priority and Preemption Model
#     Status: MERGED. See spec/cp-009-priority-preemption.md
#
# Coordinated amendments (Part 2 revision, control-plane service levels):
#   Location model extended with namespace/identifier (cpl-req-801).
#   See spec/part-02-conformance/SERVICE-LEVELS.md §14.1
# =====================================================================

module: information-model
part: 3
version: 1.0
edition: 2026a

# ====================================================================
# Agent — the canonical agent record (Part 4, Part 5)
# CP-007 incorporated: agent_identity replaces flat agent_id/hr_ref model
# ====================================================================
agent:
  description: >
    Any entity allocatable to tasks: human staff, robot, or
    human-in-the-loop operator station.
  required_fields:
    - agent_identity
    - agent_type
    - availability_status
  fields:
    agent_id:
      type: string
      description: >
        Deprecated (CP-007). Use agent_identity instead.
        Retained for backward compatibility; must be derived from
        agent_identity.production_identifier.serial_number when present,
        to ensure unique individual identification. Deriving from
        access_key alone is insufficient — access_key identifies the
        agent type, not the individual unit.
      example: "robot-EVE-001"
    agent_identity:
      description: >
        Three-layer identity model (CP-007). access_key identifies
        the agent type (stable across versions and units).
        device_identifier identifies the configuration/version.
        production_identifier identifies the individual unit.
        Each layer declares its issuing_entity; implementations
        MUST NOT require all layers to share the same issuer.
      type: object
      required_fields:
        - access_key
        - device_identifier
        - production_identifier
      fields:
        access_key:
          type: object
          description: >
            Canonical lookup key for the agent type. Stable across
            software versions, configuration changes, and individual
            units of the same model. Used for type-level addressing.
          required_fields:
            - issuing_entity
            - value
          fields:
            issuing_entity:
              type: string
              enum: [gs1, hibcc, iccbba, ifa, vda5050, internal]
              description: >
                Entity that issued this identifier. gs1, hibcc, iccbba,
                and ifa are the EU-designated UDI issuers (Decision 2019/939).
                vda5050 denotes identity from VDA 5050 factsheet.
                internal denotes operating-organisation assignment.
                Implementations MUST treat this enumeration as extensible.
              example: "internal"
            value:
              type: string
              description: >
                Basic UDI-DI where regulated; otherwise a stable
                manufacturer+model key.
              example: "EVE-transport-2026"
        device_identifier:
          type: object
          description: >
            Identifies the specific device configuration. Changes
            when software version or capabilities change.
          required_fields:
            - issuing_entity
            - value
          fields:
            issuing_entity:
              type: string
              enum: [gs1, hibcc, iccbba, ifa, vda5050, internal]
              description: Entity that issued this identifier.
              example: "gs1"
            value:
              type: string
              description: Configuration/version-bearing identifier.
              example: "SN-2026-EVE-00142"
            software_version:
              type: string
              description: Optional, informative version string.
              required: false
              example: "2.1.0"
        production_identifier:
          type: object
          description: >
            Identifies the individual unit. When the agent
            communicates over VDA 5050, serial_number carries
            the VDA 5050 serialNumber value verbatim.
          required_fields:
            - serial_number
          fields:
            serial_number:
              type: string
              description: VDA 5050 serialNumber verbatim.
              example: "EVE-00142"
            manufacture_date:
              type: string
              format: date
              description: Optional manufacture date.
              required: false
        regulatory:
          type: object
          description: >
            Present only when the agent is a regulated medical
            device under MDR (EU) 2017/745 or IVDR (EU) 2017/746.
            Absence of this block MUST NOT be interpreted as a
            claim of regulatory status.
          required: false
          fields:
            basic_udi_di:
              type: string
              description: Basic UDI-DI per MDR/IVDR.
            udi_di:
              type: string
              description: UDI-DI for the specific device configuration.
            eudamed_registered:
              type: boolean
              description: Whether the device is registered in EUDAMED.
    agent_type:
      type: string
      enum: [human, robot, cockpit]
      description: Agent category. Determines applicable allocation rules.
    hr_ref:
      type: string
      description: >
        Deprecated (CP-007). Reference to HR system record
        (employee ID or serial number). For robots, use
        agent_identity.production_identifier.serial_number (individual
        unit). For humans, use production_identifier from workforce
        system. device_identifier is for configuration/version — not
        for individual identification.
      required: false
    provider_id:
      type: string
      description: Source provider that registered this agent.
      example: "columna-flow-rigshospitalet"
    availability_status:
      type: string
      enum: [available, busy, unavailable, scheduled_absent]
    current_location:
      type: location
      required: false

# ====================================================================
# Capability (Part 5)
# ====================================================================
capability:
  description: A structured declaration of what an agent can do.
  fields:
    capability_id:
      type: string
      description: Key matching an entry in the capability registry (Part 5).
      example: "transport.meal"
    name:
      type: string
      example: "Meal transport between wards"
    level:
      type: string
      enum: [basic, intermediate, expert]
      description: >
        Proficiency level. 'basic' covers standard operation.
        'intermediate' adds contextual adaptation. 'expert'
        covers supervised autonomous operation in complex
        environments. Note: Part 5 capability registry uses
        the same values; 'advanced' and 'certified' are not
        standard capability levels.
    certified:
      type: boolean
      description: Whether the capability has passed certification testing.
      default: false
    constraints:
      type: array
      items: string
      required: false

# ====================================================================
# Time Window (Part 4)
# ====================================================================
time_window:
  description: A scheduled availability period.
  fields:
    start:
      type: string
      format: date-time
    end:
      type: string
      format: date-time
    status:
      type: string
      enum: [available, unavailable]
    recurrence:
      type: string
      description: "RRULE or 'none'"
      required: false

# ====================================================================
# Location (Part 4, Part 5)
# Extended: namespace/identity model per cpl-req-801, 803
# Backward compat: ward_or_zone retained as deprecated
# ====================================================================
location:
  description: >
    Physical place within a deployment. The namespace/identifier pair
    provides stable identity (cpl-req-801, 803). Name, hierarchy, and
    coordinates are informational. State is carried separately.
  required_fields:
    - namespace
    - identifier
  fields:
    namespace:
      type: string
      description: >
        The identification system or registry that defines the
        identifier format and scope. Examples: GS1, internal,
        vda5050, uniclass, operator-defined.
      example: "GS1"
    identifier:
      type: string
      description: >
        The value unique within its namespace. Does not change
        with state or occupancy (cpl-req-803).
      example: "701234567890123"
    name:
      type: string
      description: >
        Human-readable label. Locale-dependent. SHALL NOT serve
        as the sole basis for automated identification (cpl-req-804).
      required: false
      example: "Pharmacy receiving area"
    parent:
      type: string
      description: >
        Reference to the containing location (format: namespace:identifier).
        Supports hierarchy: building → floor → ward → room.
      required: false
      example: "internal:urn:facility:pharmacy"
    ward_or_zone:
      type: string
      description: >
        DEPRECATED. Preserved for backward compatibility with
        existing Part 4 contracts. New implementations SHALL use
        namespace and identifier.
      required: false
      example: "Ward 3B"
    coordinates:
      type: object
      required: false
      description: Position within a spatial reference frame.
      properties:
        x: { type: number }
        y: { type: number }
        map_id: { type: string }

# ====================================================================
# Resource Authority — shared resource access (CP-008)
# ====================================================================
resource_authority:
  description: >
    Explicit model of shared resources agents compete for:
    space, doors, lifts, docks, and tasks. Grants are
    time-bound with explicit release and capacity modeling.
    Agents that lose contact have defined obligations.
  required_fields:
    - resource_id
    - resource_type
    - grant_holders
  fields:
    resource_id:
      type: string
      description: Unique identifier for the shared resource.
      example: "door-3B-01"
    resource_type:
      type: string
      enum: [door, lift, dock, zone, task]
      description: Type of shared resource.
    capacity:
      type: integer
      description: >
        Maximum concurrent holders. 1 for exclusive resources
        (doors). >1 for shared resources (lifts).
      default: 1
    grant_holders:
      type: array
      items: object
      description: >
        Current agents holding access grants. Each grant has
        an explicit lifetime with expiry.
      properties:
        agent_id:
          type: string
          description: Agent holding this grant.
        granted_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
          description: >
            Grant expiry. Grants MUST expire — no indefinite
            grants. Agent must explicitly release or request
            renewal before expiry.
    communication_loss_policy:
      type: string
      enum: [auto_release, hold_until_timeout, escalate]
      description: >
        Behavior when grant holder loses contact.
        'auto_release' releases immediately.
        'hold_until_timeout' holds for a configurable period.
        'escalate' notifies orchestrator for manual resolution.
      default: hold_until_timeout

# ====================================================================
# Cost Model (Part 4)
# ====================================================================
cost_model:
  description: How the orchestrator prices using an agent for a task.
  fields:
    base_cost_per_minute:
      type: number
      description: "Cost in EUR, normalized."
    min_engagement_minutes:
      type: number
    cost_factors:
      type: array
      items: object
      required: false
      description: >
        Arbitrary cost modifiers (e.g., time-of-day,
        location-based, regulatory). Structure is
        implementation-defined.
      properties:
        factor_id:
          type: string
          description: Identifier for this factor.
        weight:
          type: number
          description: Multiplicative weight.
        applies_when:
          type: string
          description: Human-readable condition.

# ====================================================================
# Task (Part 4)
# ====================================================================
task:
  description: A unit of work to be allocated to an agent.
  required_fields:
    - task_id
    - description
    - required_capability
    - priority
  fields:
    task_id:
      type: string
      format: uuid
    description:
      type: string
    required_capability:
      type: string
      description: Capability key matching the capability registry.
    priority:
      type: string
      enum: [immediate, expedited, routine, deferred]
      description: >
        Priority level (CP-009). 'immediate' for life-safety
        tasks. 'expedited' for time-critical but non-emergency.
        'routine' for standard operations. 'deferred' for
        background work. Replaces numeric 0–9 scale; numeric
        values are implementation-specific and must map to
        these levels.
      default: routine
    priority_origin:
      type: string
      description: >
        Entity authorized to set this priority (CP-009).
        Only the clinical lead, BMS (fire/evacuation), or
        orchestrator (system policy) may set 'immediate'.
      required: false
    status:
      type: string
      enum: [pending, assigned, in_progress, completed, cancelled]
      default: pending
    assigned_agent_id:
      type: string
      required: false
    zone:
      type: string
      required: false
    constraints:
      type: array
      items: string
      required: false

# ====================================================================
# Data Profile (Part 7)
# ====================================================================
data_profile:
  description: >
    What data classes an agent delivers, where, and on what basis.
    Required for robots; optional for human agents.
  required_fields:
    - data_classes_delivered
    - declared_destinations
  fields:
    data_classes_delivered:
      type: array
      items: string
      description: "From data class taxonomy (Part 7): operational_telemetry, diagnostic, sensor_payload, personal_data"
    declared_destinations:
      type: array
      items: destination
    gdpr_article:
      type: string
      enum: [6_1_f, 6_1_a, 9_2_h, 9_2_a, none]
      description: "Processing basis for Art. 9 data."
      default: none

# ====================================================================
# Declared Destination (Part 7)
# ====================================================================
destination:
  description: Where data is transferred and under what basis.
  required_fields:
    - destination_id
    - system_name
    - location
    - lawful_basis
  fields:
    destination_id:
      type: string
    system_name:
      type: string
    location:
      type: string
      example: "hospital-internal"
    lawful_basis:
      type: string
      enum: [adequacy, sccs, bcrs, explicit_consent, legal_obligation, none]
    description:
      type: string
      required: false

# ====================================================================
# Compliance Event (Part 5, Healthcare profile)
# ====================================================================
compliance_event:
  description: Published on zone transitions (Part 5, rocom/v0/compliance/event).
  required_fields:
    - event_id
    - task_id
    - agent_id
    - zone
    - event_type
    - compliance_status
    - audit_correlation_id
  fields:
    event_id:
      type: string
      format: uuid
    task_id:
      type: string
      format: uuid
    agent_id:
      type: string
      format: uuid
    zone:
      type: string
    event_type:
      type: string
      enum: [zone_entry, zone_exit, restricted_zone_check, chain_of_custody]
    compliance_status:
      type: string
      enum: [passed, failed, exception]
      description: REQUIRED per Part 5 (P-2.2.4).
    audit_correlation_id:
      type: string
      format: uuid
      description: REQUIRED per Part 5 (P-2.2.2). Links to orchestrator audit trail.

# ====================================================================
# Chain of Custody Event (Part 5, Healthcare profile — any level)
# ====================================================================
chain_of_custody_event:
  description: >
    Published on rocom/v0/chainOfCustody/event for tasks
    requiring chain-of-custody tracking. Healthcare profile
    requirement (any level, not L3-only).
  required_fields:
    - event_id
    - task_id
    - item_type
    - agent_id
    - action
    - timestamp
    - audit_correlation_id
  fields:
    event_id:
      type: string
      format: uuid
    task_id:
      type: string
      format: uuid
    item_type:
      type: string
      enum: [medication, sample, meal, waste, linen]
    agent_id:
      type: string
      format: uuid
    action:
      type: string
      enum: [picked_up, in_transit, delivered, handed_off]
    custody_signature:
      type: string
      description: Cryptographic hash of custody state.
      required: false
    timestamp:
      type: string
      format: date-time
    audit_correlation_id:
      type: string
      format: uuid
      description: >
        REQUIRED per Part 5. Links to orchestrator audit trail
        for end-to-end chain-of-custody traceability.
