openapi: 3.1.0
info:
  title: Kiduna Coherence API
  version: 1.0.0-rc.1
  description: Versioned runtime contract for resolving, observing, assessing, preflighting, and intervening.
servers:
  - url: https://api.kiduna.example/v1
security:
  - bearerAuth: []
paths:
  /coherence/effective-profile:resolve:
    post:
      operationId: resolveEffectiveCoherenceProfile
      parameters:
        - $ref: '#/components/parameters/RealmId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [subject, scope, profileRefs, policyRefs, asOf]
              properties:
                subject: { $ref: '../schemas/coherence-common.schema.json#/$defs/EntityRef' }
                scope: { $ref: '../schemas/coherence-common.schema.json#/$defs/ScopeRef' }
                profileRefs: { type: array, minItems: 1, items: { type: string } }
                policyRefs: { type: array, minItems: 1, items: { type: string } }
                asOf: { type: string, format: date-time }
      responses:
        '200':
          description: Effective immutable profile plus field resolution trace.
          content:
            application/json:
              schema:
                type: object
                required: [profile, policyRefs, resolutionTrace, status]
                properties:
                  profile: { $ref: '../schemas/coherence-profile.schema.json' }
                  policyRefs: { type: array, items: { type: string } }
                  resolutionTrace: { type: array, items: { type: object } }
                  status: { enum: [resolved, resolution-required] }
        '409': { $ref: '#/components/responses/Conflict' }
  /coherence/observations:
    post:
      operationId: recordCoherenceObservation
      parameters: [{ $ref: '#/components/parameters/RealmId' }, { $ref: '#/components/parameters/IdempotencyKey' }]
      requestBody:
        required: true
        content: { application/json: { schema: { $ref: '../schemas/coherence-observation.schema.json' } } }
      responses:
        '201': { description: Observation accepted after Authority, Consent, purpose, and visibility checks, content: { application/json: { schema: { $ref: '../schemas/coherence-observation.schema.json' } } } }
        '403': { $ref: '#/components/responses/Forbidden' }
  /coherence/state:aggregate:
    post:
      operationId: aggregateCoherenceState
      parameters: [{ $ref: '#/components/parameters/RealmId' }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [subject, scope, observationRefs, dimensionRefs, asOf]
              properties:
                subject: { $ref: '../schemas/coherence-common.schema.json#/$defs/EntityRef' }
                scope: { $ref: '../schemas/coherence-common.schema.json#/$defs/ScopeRef' }
                observationRefs: { type: array, items: { type: string } }
                dimensionRefs: { type: array, items: { type: string } }
                asOf: { type: string, format: date-time }
      responses:
        '200': { description: Recomputable state snapshot, content: { application/json: { schema: { $ref: '../schemas/coherence-state.schema.json' } } } }
  /coherence/assessments:
    post:
      operationId: createCoherenceAssessment
      parameters: [{ $ref: '#/components/parameters/RealmId' }, { $ref: '#/components/parameters/IdempotencyKey' }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [stateRef, profileRef, policyRefs, expectedProfileVersion]
              properties:
                stateRef: { type: string }
                profileRef: { type: string }
                policyRefs: { type: array, minItems: 1, items: { type: string } }
                expectedProfileVersion: { type: string }
      responses:
        '201': { description: Immutable comparison and eligible response, content: { application/json: { schema: { $ref: '../schemas/coherence-assessment.schema.json' } } } }
        '409': { $ref: '#/components/responses/Conflict' }
  /coherence/preflight:
    post:
      operationId: preflightCoherentAction
      parameters: [{ $ref: '#/components/parameters/RealmId' }, { $ref: '#/components/parameters/IdempotencyKey' }]
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/PreflightRequest' }
      responses:
        '200': { description: Deterministic release decision, content: { application/json: { schema: { $ref: '#/components/schemas/PreflightResponse' } } } }
  /coherence/interventions:
    post:
      operationId: proposeOrExecuteCoherenceIntervention
      parameters: [{ $ref: '#/components/parameters/RealmId' }, { $ref: '#/components/parameters/IdempotencyKey' }]
      requestBody:
        required: true
        content: { application/json: { schema: { $ref: '../schemas/coherence-intervention.schema.json' } } }
      responses:
        '201': { description: Version-pinned intervention Record, content: { application/json: { schema: { $ref: '../schemas/coherence-intervention.schema.json' } } } }
        '403': { $ref: '#/components/responses/Forbidden' }
  /coherence/mediation-sessions:
    post:
      operationId: createCoherenceMediationSession
      parameters: [{ $ref: '#/components/parameters/RealmId' }, { $ref: '#/components/parameters/IdempotencyKey' }]
      requestBody:
        required: true
        content: { application/json: { schema: { $ref: '../schemas/mediation-session.schema.json' } } }
      responses:
        '201': { description: Participant-consented temporary interaction compact, content: { application/json: { schema: { $ref: '../schemas/mediation-session.schema.json' } } } }
components:
  securitySchemes:
    bearerAuth: { type: http, scheme: bearer }
  parameters:
    RealmId:
      name: X-Kiduna-Realm
      in: header
      required: true
      schema: { type: string }
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      schema: { type: string, minLength: 8 }
  responses:
    Forbidden: { description: Authority, Permission, Consent, purpose, or visibility does not permit the request. }
    Conflict: { description: Expected object version is stale or equal-priority configuration requires resolution. }
  schemas:
    PreflightRequest:
      type: object
      additionalProperties: false
      required: [subject, scope, action, profileRef, policyRefs, authorityRef, auditAvailable]
      properties:
        subject: { $ref: '../schemas/coherence-common.schema.json#/$defs/EntityRef' }
        scope: { $ref: '../schemas/coherence-common.schema.json#/$defs/ScopeRef' }
        action:
          type: object
          required: [type, version, target, purpose, dataScope, resourceEffect, reversibility]
          properties:
            type: { type: string }
            version: { type: string }
            target: { type: string }
            purpose: { type: string }
            dataScope: { type: array, items: { type: string } }
            resourceEffect: { type: object }
            reversibility: { enum: [reversible, partial, irreversible] }
        profileRef: { type: string }
        policyRefs: { type: array, items: { type: string } }
        authorityRef: { type: string }
        auditAvailable: { type: boolean }
    PreflightResponse:
      type: object
      additionalProperties: false
      required: [decision, assessmentRef, directives, deniedEffects, requiredEscalations, policyVersions, expiresAt]
      properties:
        decision: { enum: [allow, allow-with-modulation, deny, escalate] }
        assessmentRef: { type: [string, 'null'] }
        directives: { type: array, items: { type: string } }
        deniedEffects: { type: array, items: { type: string } }
        requiredEscalations: { type: array, items: { type: object } }
        policyVersions: { type: array, items: { type: string } }
        expiresAt: { type: string, format: date-time }
