openapi: 3.1.0
info:
  title: Platform Core Vocabulary Hardening Internal Contract
  version: 0.1.0
  summary: Internal logical contract for canonical platform vocabulary, operation type resolution, reason ownership translation, registry ownership lookup, and platform subject normalization
  description: |
    This contract is an internal planning artifact for Spec 204. The affected
    surfaces continue to render through existing Laravel services, jobs,
    presenters, Filament resources, pages, and widgets. The paths below are
    logical boundary identifiers only; they do not imply new HTTP routes or
    controllers. The consumer inventory below is an implementation-consumer
    traceability list, not a second operator-surface declaration table. The
    authoritative operator-facing route and surface inventory lives in
    spec.md.
x-logical-artifact: true
x-platform-core-vocabulary-consumers:
  - surface: governance.platform_vocabulary
    sourceFiles:
      - apps/platform/app/Support/Governance/GovernanceDomainKey.php
      - apps/platform/app/Support/Governance/GovernanceSubjectClass.php
      - apps/platform/app/Support/Governance/GovernanceSubjectTaxonomyRegistry.php
      - apps/platform/app/Support/Baselines/BaselineScope.php
    mustConsume:
      - canonical_platform_terms
      - explicit_ownership_boundaries
      - forbidden_false_universal_aliases
  - surface: operations.rendering
    sourceFiles:
      - apps/platform/app/Support/OperationCatalog.php
      - apps/platform/app/Support/OperationRunType.php
      - apps/platform/app/Filament/Resources/OperationRunResource.php
      - apps/platform/app/Filament/System/Pages/Ops/Runs.php
    mustConsume:
      - canonical_operation_resolution
      - legacy_alias_compatibility
      - stable_filter_labels
  - surface: operations.dashboard_widgets
    sourceFiles:
      - apps/platform/app/Filament/Pages/TenantDashboard.php
      - apps/platform/app/Filament/Widgets/Dashboard/RecentOperations.php
      - apps/platform/app/Filament/System/Pages/Dashboard.php
      - apps/platform/app/Filament/System/Widgets/ControlTowerRecentFailures.php
      - apps/platform/app/Filament/System/Widgets/ControlTowerTopOffenders.php
    mustConsume:
      - canonical_operation_resolution
      - legacy_alias_compatibility
      - stable_filter_labels
  - surface: reasons.translation
    sourceFiles:
      - apps/platform/app/Support/ReasonTranslation/ReasonTranslator.php
      - apps/platform/app/Support/ReasonTranslation/ReasonResolutionEnvelope.php
      - apps/platform/app/Support/Providers/ProviderReasonTranslator.php
      - apps/platform/app/Filament/Pages/BaselineCompareLanding.php
      - apps/platform/app/Filament/Pages/BaselineCompareMatrix.php
      - apps/platform/app/Filament/Resources/OperationRunResource.php
    mustConsume:
      - explicit_reason_owner
      - platform_reason_family
      - existing_operator_explanation_fields
  - surface: baselines.platform_subjects
    sourceFiles:
      - apps/platform/app/Jobs/CompareBaselineToTenantJob.php
      - apps/platform/app/Services/Baselines/SnapshotRendering/BaselineSnapshotPresenter.php
      - apps/platform/app/Support/Baselines/Compare/CompareSubjectResult.php
      - apps/platform/app/Support/Filament/FilterOptionCatalog.php
    mustConsume:
      - platform_subject_descriptor
      - legacy_policy_type_fallback_only
      - governed_subject_fields_first
  - surface: evidence.rendering
    sourceFiles:
      - apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php
    mustConsume:
      - platform_subject_descriptor
      - legacy_policy_type_fallback_only
      - governed_subject_fields_first
  - surface: registry.ownership
    sourceFiles:
      - apps/platform/app/Support/Governance/GovernanceSubjectTaxonomyRegistry.php
      - apps/platform/app/Support/OperationCatalog.php
      - apps/platform/app/Support/Providers/ProviderReasonCodes.php
      - apps/platform/config/tenantpilot.php
    mustConsume:
      - registry_owner_layer
      - canonical_noun_authority
      - compatibility_only_markers
  - surface: reporting.summaries
    sourceFiles:
      - apps/platform/app/Services/ReviewPackService.php
      - apps/platform/app/Services/TenantReviews/TenantReviewService.php
      - apps/platform/app/Filament/Resources/TenantReviewResource.php
      - apps/platform/app/Filament/Widgets/Tenant/TenantReviewPackCard.php
    mustConsume:
      - canonical_operation_resolution
      - explicit_reason_owner
      - platform_subject_descriptor
  - surface: operations.launch_surfaces
    sourceFiles:
      - apps/platform/app/Filament/Resources/ProviderConnectionResource.php
      - apps/platform/app/Filament/Resources/InventoryItemResource/Pages/ListInventoryItems.php
      - apps/platform/app/Filament/Resources/BackupScheduleResource.php
      - apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php
    mustConsume:
      - canonical_operation_resolution
      - legacy_alias_compatibility
      - stable_filter_labels
paths:
  /internal/governance/platform-vocabulary/terms/{termKey}:
    get:
      summary: Resolve one canonical platform term and its ownership boundary
      operationId: getPlatformVocabularyTerm
      parameters:
        - name: termKey
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Canonical platform term definition resolved successfully
          content:
            application/vnd.tenantatlas.platform-vocabulary-term+json:
              schema:
                $ref: '#/components/schemas/PlatformVocabularyTerm'
        '404':
          description: The term is unknown to the maintained platform glossary
  /internal/governance/registries/{registryKey}/ownership:
    get:
      summary: Resolve ownership and canonical vocabulary authority for a registry or catalog
      operationId: getRegistryOwnershipDescriptor
      parameters:
        - name: registryKey
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Ownership and canonical usage rules for the registry
          content:
            application/vnd.tenantatlas.registry-ownership-descriptor+json:
              schema:
                $ref: '#/components/schemas/RegistryOwnershipDescriptor'
        '404':
          description: Unknown registry key
  /internal/operations/types/resolve:
    post:
      summary: Resolve a raw stored operation type into one canonical operation vocabulary record
      operationId: resolveCanonicalOperationType
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OperationTypeResolutionRequest'
      responses:
        '200':
          description: Canonical operation type resolved successfully
          content:
            application/vnd.tenantatlas.operation-type-resolution+json:
              schema:
                $ref: '#/components/schemas/OperationTypeResolution'
        '422':
          description: Raw operation type is unknown or ambiguous
  /internal/reasons/translate:
    post:
      summary: Translate a reason code into an operator-safe envelope with explicit ownership and platform family metadata
      operationId: translateReasonWithOwnership
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReasonTranslationRequest'
      responses:
        '200':
          description: Reason translated successfully
          content:
            application/vnd.tenantatlas.translated-reason+json:
              schema:
                $ref: '#/components/schemas/TranslatedReasonEnvelope'
        '422':
          description: Reason owner or code is unknown to the translation boundary
  /internal/platform-subjects/normalize:
    post:
      summary: Normalize a platform-near payload into a governed subject descriptor without assuming universal Intune nouns
      operationId: normalizePlatformSubjectDescriptor
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlatformSubjectNormalizationRequest'
      responses:
        '200':
          description: Platform subject descriptor resolved successfully
          content:
            application/vnd.tenantatlas.platform-subject-descriptor+json:
              schema:
                $ref: '#/components/schemas/SubjectDescriptorNormalizationResult'
        '422':
          description: The payload cannot be normalized into a governed subject descriptor
components:
  schemas:
    PlatformVocabularyTermOwnerLayer:
      type: string
      enum:
        - platform_core
        - domain_owned
        - provider_owned
        - compatibility_alias
    RegistryOwnershipOwnerLayer:
      type: string
      enum:
        - platform_core
        - domain_owned
        - provider_owned
        - compatibility_only
    VocabularyBoundaryClassification:
      type: string
      enum:
        - platform_core
        - cross_domain_governance
        - intune_specific
    PlatformReasonFamily:
      type: string
      enum:
        - authorization
        - prerequisite
        - compatibility
        - coverage
        - availability
        - execution
    PlatformVocabularyTerm:
      type: object
      additionalProperties: false
      required:
        - term_key
        - canonical_label
        - canonical_description
        - boundary_classification
        - owner_layer
        - allowed_contexts
        - legacy_aliases
        - alias_retirement_path
        - forbidden_platform_aliases
      properties:
        term_key:
          type: string
        canonical_label:
          type: string
        canonical_description:
          type: string
        boundary_classification:
          $ref: '#/components/schemas/VocabularyBoundaryClassification'
        owner_layer:
          $ref: '#/components/schemas/PlatformVocabularyTermOwnerLayer'
        allowed_contexts:
          type: array
          items:
            type: string
        legacy_aliases:
          type: array
          items:
            type: string
        alias_retirement_path:
          type:
            - string
            - 'null'
        forbidden_platform_aliases:
          type: array
          items:
            type: string
    RegistryOwnershipDescriptor:
      type: object
      additionalProperties: false
      required:
        - registry_key
        - boundary_classification
        - owner_layer
        - source_class_or_file
        - canonical_nouns
        - allowed_consumers
      properties:
        registry_key:
          type: string
        boundary_classification:
          $ref: '#/components/schemas/VocabularyBoundaryClassification'
        owner_layer:
          $ref: '#/components/schemas/RegistryOwnershipOwnerLayer'
        source_class_or_file:
          type: string
        canonical_nouns:
          type: array
          items:
            type: string
        allowed_consumers:
          type: array
          items:
            type: string
        compatibility_notes:
          type:
            - string
            - 'null'
    CanonicalOperationType:
      type: object
      additionalProperties: false
      required:
        - canonical_code
        - artifact_family
        - display_label
        - supports_operator_explanation
      properties:
        canonical_code:
          type: string
        domain_key:
          type:
            - string
            - 'null'
        artifact_family:
          type: string
        display_label:
          type: string
        supports_operator_explanation:
          type: boolean
        expected_duration_seconds:
          type:
            - integer
            - 'null'
    OperationTypeAlias:
      type: object
      additionalProperties: false
      required:
        - raw_value
        - canonical_code
        - alias_status
        - write_allowed
      properties:
        raw_value:
          type: string
        canonical_code:
          type: string
        alias_status:
          type: string
          enum:
            - canonical
            - legacy_alias
            - deprecated_alias
        write_allowed:
          type: boolean
        deprecation_note:
          type:
            - string
            - 'null'
        retirement_path:
          type:
            - string
            - 'null'
    OperationTypeResolutionRequest:
      type: object
      additionalProperties: false
      required:
        - raw_value
        - source_surface
      properties:
        raw_value:
          type: string
        source_surface:
          type: string
        context:
          type: object
          additionalProperties: true
    OperationTypeResolution:
      type: object
      additionalProperties: false
      required:
        - raw_value
        - canonical
        - aliases_considered
        - alias_status
        - was_legacy_alias
      properties:
        raw_value:
          type: string
        canonical:
          $ref: '#/components/schemas/CanonicalOperationType'
        aliases_considered:
          type: array
          items:
            $ref: '#/components/schemas/OperationTypeAlias'
        alias_status:
          type: string
          enum:
            - canonical
            - legacy_alias
            - deprecated_alias
        was_legacy_alias:
          type: boolean
    ReasonOwnershipDescriptor:
      type: object
      additionalProperties: false
      required:
        - owner_layer
        - owner_namespace
        - reason_code
        - platform_reason_family
      properties:
        owner_layer:
          type: string
          enum:
            - platform_core
            - domain_owned
            - provider_owned
        owner_namespace:
          type: string
        reason_code:
          type: string
        platform_reason_family:
          $ref: '#/components/schemas/PlatformReasonFamily'
    ReasonTranslationRequest:
      type: object
      additionalProperties: false
      required:
        - owner_namespace
        - reason_code
      properties:
        owner_namespace:
          type: string
        reason_code:
          type: string
        operator_context:
          type: object
          additionalProperties: true
        diagnostics_context:
          type: object
          additionalProperties: true
    TranslatedReasonEnvelope:
      type: object
      additionalProperties: false
      required:
        - reason_owner
        - operator_label
        - explanation
        - actionability
        - next_steps
      properties:
        reason_owner:
          $ref: '#/components/schemas/ReasonOwnershipDescriptor'
        operator_label:
          type: string
        explanation:
          type: string
        actionability:
          type: string
        next_steps:
          type: array
          items:
            type: string
        diagnostic_label:
          type:
            - string
            - 'null'
        trust_impact:
          type:
            - string
            - 'null'
        absence_pattern:
          type:
            - string
            - 'null'
    PlatformSubjectDescriptor:
      type: object
      additionalProperties: false
      required:
        - domain_key
        - subject_class
        - subject_type_key
        - subject_type_label
        - platform_noun
        - display_label
        - owner_layer
      properties:
        domain_key:
          type: string
        subject_class:
          type: string
        subject_type_key:
          type: string
        subject_type_label:
          type: string
        platform_noun:
          type: string
        display_label:
          type: string
        legacy_policy_type:
          type:
            - string
            - 'null'
        owner_layer:
          type: string
          enum:
            - platform_core
            - domain_owned
            - provider_owned
    PlatformSubjectNormalizationRequest:
      type: object
      additionalProperties: false
      required:
        - source_surface
        - raw_payload
      properties:
        source_surface:
          type: string
        raw_payload:
          type: object
          additionalProperties: true
    SubjectDescriptorNormalizationResult:
      type: object
      additionalProperties: false
      required:
        - descriptor
        - source_surface
        - used_legacy_alias
        - warnings
      properties:
        descriptor:
          $ref: '#/components/schemas/PlatformSubjectDescriptor'
        source_surface:
          type: string
        used_legacy_alias:
          type: boolean
        warnings:
          type: array
          description: Array of string warning messages emitted during normalization.
          items:
            type: string