# FILE: part-04-services/task_source_contract.yaml
# Task Source Contract — Rocom v0.2
# Defines the interface any task-generating system must implement
# to feed work requests into the orchestrator allocation engine.
#
# Coordinated with Part 2 revision (control-plane service levels).
# L0-L3 conformance aligned to SERVICE-LEVELS v1.0 §3.4 Task plane.
# zone extended with namespace/identifier (Part 3 amendment).
#
# Implementations:
#   - Management system allocation engine receives tasks via POST /tasks (Sup-001)
#   - Enterprise ERP systems (SAP, columna) as task sources
#   - BMS-generated maintenance tasks
#   - Manual task entry via cockpit interface

contract:
  name: "Task Source Interface"
  version: "1.0.0"
  description: >-
    Source-agnostic contract for feeding task requests into the orchestrator
    allocation engine. Any enterprise system (ERP, BMS, turnus, manual entry)
    implements this contract to become a task source. The orchestrator normalizes
    all sources to the unified Task model (Part 3).

  required_fields:
    # --- Identity ---
    - name: task_id
      type: "String (UUID)"
      description: "Unique identifier for the task. Generated by the task source or orchestrator."
      example: '"task-4a8b2c1d-..."'

    - name: description
      type: "String"
      description: "Human-readable task description."
      example: '"Transport medication from pharmacy to Ward 3B"'

    - name: required_capability
      type: "String"
      description: "Capability key matching the capability registry (Part 5)."
      example: '"transport.medication"'

    - name: priority
      type: "Enum { immediate, expedited, routine, deferred }"
      description: "Priority level per Part 3 (CP-009). 'immediate' for life-safety. 'expedited' for time-critical. 'routine' is the default. 'deferred' for scheduled/background work."
      example: "routine"

    - name: source_id
      type: "String"
      description: "Identifier of the task source system generating this request."
      example: '"sap-erp-rigshospitalet" eller "bms-maintenance"'

    # --- Execution ---
    - name: status
      type: "Enum { pending, assigned, in_progress, completed, cancelled }"
      description: "Current task status. Task sources create tasks as pending."
      example: "pending"

    - name: assigned_agent_id
      type: "Optional[String]"
      description: "Agent assigned to this task by the orchestrator. Null for pending tasks."
      example: '"robot-EVE-001"'

    - name: zone
      type: "Optional[String]"
      description: "Target ward/zone (Part 3 Location model)."
      example: '"Ward 3B"'

    - name: constraints
      type: "Optional[Array[String]]"
      description: "Operational constraints (e.g., 'restricted_zones: true', 'chain_of_custody: required')."
      example: '["chain_of_custody: required", "temperature_range: 2-8C"]'

    - name: deadline
      type: "Optional[DateTime]"
      description: "Latest completion time (ISO 8601)."
      example: '"2026-09-15T14:00:00+02:00"'

    - name: chain_of_custody
      type: "Optional[Boolean]"
      description: "Whether chain-of-custody tracking is required. Healthcare profile requirement at any level (not L3-only)."
      example: "true"

    # --- Compliance ---
    - name: compliance_flags
      type: "Optional[Array[String]]"
      description: "Regulatory flags affecting task execution."
      example: '["gdpr_chain_of_custody", "eu_cra_class_b"]'

  events:
    # Push model: task source emits these events to the orchestrator
    - name: task.created
      description: "New task submitted to the orchestrator."
      payload: "All required_fields"

    - name: task.updated
      description: "Task modified (priority change, deadline extension, constraints added)."
      payload:
        - task_id
        - description
        - priority
        - constraints
        - deadline
        - timestamp

    - name: task.cancelled
      description: "Task cancelled by the originating source before assignment."
      payload:
        - task_id
        - reason
        - timestamp

  polling_alternative:
    description: "Task sources that cannot push may use the orchestrator REST API."
    endpoint: "POST /tasks"
    request_body: "All required_fields"
    response: "task_id, status: accepted, assigned_agent_id (if auto-assigned)"
    rate_limit: "50 req/min per source"

  conformance_levels:
    # Aligned to Part 2 control-plane service levels (cpl-req-401, 402, 403)
    - level: "L1"
      name: "Static integration"
      requirement: >-
        Source provides task_id, description, required_capability, priority
        (CP-009 values with authorised origin), origin/destination location
        references (namespace declared per cpl-req-801). Standardised task
        submissions with lifecycle outcomes. Predefined assignment rules may
        be used. Sufficient for on-demand allocation.
      example_implementations: ["Manual cockpit entry", "Simple script"]

    - level: "L2"
      name: "State-aware coordination"
      requirement: >-
        L1 + deadline, constraints, zone (extended location type), task
        progress, authorised amendments, cancellations and exceptions within
        service-quality bounds. Predefined responses account for deadlines,
        readiness, dependencies and evidence requirements. Acceptance,
        execution and completion remain distinct states. Enables planned
        allocation with zone-restricted and chain-of-custody tasks.
      example_implementations: ["SAP ERP production orders", "Columna Flow task management"]

    - level: "L3"
      name: "Fully dynamic coordination"
      requirement: >-
        L2 + chain_of_custody, compliance_flags, real-time push events,
        event-driven reevaluation and coordinated reassignment/replanning
        when needs or dependencies change. Preserves CP-009 priority origin
        and preemption restrictions, CP-008 resource authority and applicable
        chain-of-custody. Enables fully automated allocation with compliance
        verification.
      example_implementations: ["SAP + Rocom adapter", "BMS maintenance integration"]

# ============================================================
# AsyncAPI Skisse — Event-driven task source interface
# ============================================================
  asyncapi_sketch: |
    asyncapi: 3.0.0
    info:
    title: Rocom Task Source Interface
    version: 0.1.0
    description: >-
      Event-driven contract for submitting tasks to the orchestrator
      allocation engine. Any enterprise system implements this to become
      a task source.

    channels:
    tasks.events:
      description: "Task events — push model"
      messages:
        TaskCreated:
          name: TaskCreated
          payload:
            type: object
            required: [event_type, task_id, description, required_capability, priority, source_id]
            properties:
              event_type:
                type: string
                const: task.created
              task_id:
                type: string
                format: uuid
              description:
                type: string
              required_capability:
                type: string
              priority:
                type: string
                enum: [immediate, expedited, routine, deferred]
                default: routine
              source_id:
                type: string
              status:
                type: string
                enum: [pending, assigned, in_progress, completed, cancelled]
                default: pending
              zone:
                type: string
              constraints:
                type: array
                items: { type: string }
              deadline:
                type: string
                format: date-time
              chain_of_custody:
                type: boolean
              compliance_flags:
                type: array
                items: { type: string }
              timestamp:
                type: string
                format: date-time

        TaskUpdated:
          name: TaskUpdated
          payload:
            type: object
            required: [event_type, task_id, timestamp]
            properties:
              event_type:
                type: string
                const: task.updated
              task_id: { type: string, format: uuid }
              description: { type: string }
              priority:
                type: string
                enum: [immediate, expedited, routine, deferred]
              constraints:
                type: array
                items: { type: string }
              deadline:
                type: string
                format: date-time
              timestamp: { type: string, format: date-time }

        TaskCancelled:
          name: TaskCancelled
          payload:
            type: object
            required: [event_type, task_id, reason, timestamp]
            properties:
              event_type:
                type: string
                const: task.cancelled
              task_id: { type: string, format: uuid }
              reason: { type: string }
              timestamp: { type: string, format: date-time }

    operations:
    publishTask:
      action: send
      channel:
        $ref: '#/channels/tasks.events'
      messages:
        - $ref: '#/channels/tasks.events/messages/TaskCreated'
        - $ref: '#/channels/tasks.events/messages/TaskUpdated'
        - $ref: '#/channels/tasks.events/messages/TaskCancelled'
