openapi: 3.1.0
info:
  title: Baseline Subject Resolution Semantics Contract
  version: 0.1.0
  description: >-
    Read-model and validation contracts for baseline compare and capture subject-resolution
    semantics. This contract documents the payloads existing operator surfaces consume after
    the foundation upgrade and the capability matrix used to keep baseline support truthful
    at runtime.
servers:
  - url: https://tenantpilot.local
paths:
  /admin/api/operations/{operationRun}/baseline-gap-semantics:
    get:
      summary: Get structured baseline gap semantics for an operation run
      operationId: getBaselineGapSemanticsForRun
      parameters:
        - name: operationRun
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Structured baseline gap semantics for the run
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BaselineGapSemanticsResponse'
        '404':
          description: Run not found or not visible in current workspace or tenant scope
        '403':
          description: Caller is a member but lacks permission to inspect the run

  /admin/api/tenants/{tenant}/baseline-compare/latest-gap-semantics:
    get:
      summary: Get latest baseline compare gap semantics for a tenant and profile
      operationId: getLatestTenantBaselineCompareGapSemantics
      parameters:
        - name: tenant
          in: path
          required: true
          schema:
            type: integer
        - name: baseline_profile_id
          in: query
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Latest tenant baseline compare semantics projection
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BaselineGapSemanticsResponse'
        '404':
          description: Tenant or run not found for current entitled scope
        '403':
          description: Caller lacks compare or review visibility within the established tenant scope

  /admin/api/baseline-support/resolution-capabilities:
    get:
      summary: Get runtime baseline support and resolution capability matrix
      operationId: getBaselineResolutionCapabilities
      responses:
        '200':
          description: Capability matrix used to validate truthful compare and capture support
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/SupportCapabilityRecord'

components:
  schemas:
    BaselineGapSemanticsResponse:
      type: object
      required:
        - summary
        - buckets
      properties:
        summary:
          $ref: '#/components/schemas/BaselineGapSummary'
        buckets:
          type: array
          items:
            $ref: '#/components/schemas/BaselineGapBucket'

    BaselineGapSummary:
      type: object
      required:
        - count
        - by_reason
        - detail_state
        - recorded_subjects_total
        - missing_detail_count
        - structural_count
        - operational_count
        - transient_count
        - legacy_mode
        - requires_regeneration
      properties:
        count:
          type: integer
          minimum: 0
        by_reason:
          type: object
          additionalProperties:
            type: integer
            minimum: 0
        detail_state:
          type: string
          enum:
            - no_gaps
            - structured_details_recorded
            - details_not_recorded
            - legacy_broad_reason
        recorded_subjects_total:
          type: integer
          minimum: 0
        missing_detail_count:
          type: integer
          minimum: 0
        structural_count:
          type: integer
          minimum: 0
        operational_count:
          type: integer
          minimum: 0
        transient_count:
          type: integer
          minimum: 0
        legacy_mode:
          type: boolean
        requires_regeneration:
          type: boolean

    BaselineGapBucket:
      type: object
      required:
        - reason_code
        - reason_label
        - count
        - recorded_count
        - missing_detail_count
        - structural_count
        - operational_count
        - transient_count
        - detail_state
        - search_text
        - rows
      properties:
        reason_code:
          type: string
        reason_label:
          type: string
        count:
          type: integer
          minimum: 0
        recorded_count:
          type: integer
          minimum: 0
        missing_detail_count:
          type: integer
          minimum: 0
        structural_count:
          type: integer
          minimum: 0
        operational_count:
          type: integer
          minimum: 0
        transient_count:
          type: integer
          minimum: 0
        detail_state:
          type: string
          enum:
            - structured_details_recorded
            - details_not_recorded
            - legacy_broad_reason
        search_text:
          type: string
        rows:
          type: array
          items:
            $ref: '#/components/schemas/EvidenceGapDetailRecord'

    EvidenceGapDetailRecord:
      type: object
      required:
        - policy_type
        - subject_key
        - subject_class
        - resolution_path
        - resolution_outcome
        - reason_code
        - operator_action_category
        - structural
        - retryable
      properties:
        policy_type:
          type: string
        subject_external_id:
          type:
            - string
            - 'null'
        subject_key:
          type: string
        subject_class:
          $ref: '#/components/schemas/SubjectClass'
        resolution_path:
          $ref: '#/components/schemas/ResolutionPath'
        resolution_outcome:
          $ref: '#/components/schemas/ResolutionOutcome'
        reason_code:
          type: string
        operator_action_category:
          $ref: '#/components/schemas/OperatorActionCategory'
        structural:
          type: boolean
        retryable:
          type: boolean
        source_model_expected:
          type:
            - string
            - 'null'
          enum:
            - policy
            - inventory
            - derived
            - 'null'
        source_model_found:
          type:
            - string
            - 'null'
          enum:
            - policy
            - inventory
            - derived
            - 'null'
        legacy_reason_code:
          type:
            - string
            - 'null'

    SupportCapabilityRecord:
      type: object
      required:
        - policy_type
        - subject_class
        - compare_capability
        - capture_capability
        - resolution_path
        - config_supported
        - runtime_valid
      properties:
        policy_type:
          type: string
        subject_class:
          $ref: '#/components/schemas/SubjectClass'
        compare_capability:
          type: string
          enum:
            - supported
            - limited
            - unsupported
        capture_capability:
          type: string
          enum:
            - supported
            - limited
            - unsupported
        resolution_path:
          $ref: '#/components/schemas/ResolutionPath'
        config_supported:
          type: boolean
        runtime_valid:
          type: boolean

    SubjectClass:
      type: string
      enum:
        - policy_backed
        - inventory_backed
        - foundation_backed
        - derived

    ResolutionPath:
      type: string
      enum:
        - policy
        - inventory
        - foundation_policy
        - foundation_inventory
        - derived
        - unsupported

    ResolutionOutcome:
      type: string
      enum:
        - resolved_policy
        - resolved_inventory
        - policy_record_missing
        - inventory_record_missing
        - foundation_inventory_only
        - resolution_type_mismatch
        - unresolvable_subject
        - permission_or_scope_blocked
        - retryable_capture_failure
        - capture_failed
        - throttled
        - budget_exhausted
        - ambiguous_match
        - invalid_subject
        - duplicate_subject
        - invalid_support_config

    OperatorActionCategory:
      type: string
      enum:
        - none
        - retry
        - run_inventory_sync
        - run_policy_sync_or_backup
        - review_permissions
        - inspect_subject_mapping
        - product_follow_up
