openapi: 3.1.0
info:
  title: Record Page Header Discipline Internal Surface Contract
  version: 0.1.0
  summary: Internal logical contract for Spec 192 record-page header discipline
  description: |
    This contract is an internal planning artifact for Spec 192. The affected
    surfaces continue to render HTML through Filament and Livewire. The schemas
    below define the bounded render contract and regression expectations for
    standard record/detail/edit headers, grouped secondary actions, contextual
    navigation outside the header, and the explicit workflow-heavy exception.
servers:
  - url: /internal
x-record-header-discipline-consumers:
  - surface: standard-record-pages
    sourceFiles:
      - apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php
      - apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php
      - apps/platform/app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php
      - apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php
      - apps/platform/app/Filament/Resources/TenantResource/Pages/EditTenant.php
    mustRender:
      - at_most_one_primary_header_action
      - grouped_secondary_actions
      - contextual_navigation_or_related_context_outside_header
      - separated_danger_actions_when_present
    mustNotRender:
      - flat_navigation_mutation_strip
      - multiple_competing_primary_actions
      - empty_action_group_placeholders
  - surface: workflow-heavy-special-type
    sourceFiles:
      - apps/platform/app/Filament/Resources/TenantResource/Pages/ViewTenant.php
    mustRender:
      - explicit_exception_reason
      - grouped_and_ordered_actions
      - optional_single_primary_only_when_dominant
    mustNotRender:
      - silent_exception
      - flat_multi_button_primary_strip
  - surface: regression-guards
    sourceFiles:
      - apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php
      - apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php
      - apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php
      - apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php
paths:
  /internal/action-surfaces/record-pages/{surface}:
    get:
      summary: Return the logical header-discipline contract for an in-scope record page
      operationId: getRecordPageHeaderDisciplineContract
      parameters:
        - name: surface
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/SurfaceKey'
      responses:
        '200':
          description: Logical render contract and regression expectations for the requested surface
          content:
            application/vnd.tenantpilot.record-header-discipline+json:
              schema:
                $ref: '#/components/schemas/RecordHeaderSurfaceContract'
        '404':
          description: Requested surface is not in the Spec 192 inventory
components:
  schemas:
    SurfaceKey:
      type: string
      enum:
        - baseline_profile_view
        - evidence_snapshot_view
        - finding_exception_view
        - tenant_review_view
        - tenant_edit
        - tenant_view
        - provider_connection_view
        - finding_view
        - review_pack_view
        - alert_destination_view
        - policy_version_view
        - workspace_view
        - baseline_snapshot_view
        - backup_set_view
    SurfaceClassification:
      type: string
      enum:
        - remediation_required
        - minor_alignment_only
        - compliant_reference
        - workflow_heavy_special_type
    ActionKind:
      type: string
      enum:
        - navigation
        - mutation
        - external_link
        - lifecycle
        - danger
    Placement:
      type: string
      enum:
        - primary_visible
        - secondary_grouped
        - contextual
        - danger_grouped
    OperationScope:
      type: string
      enum:
        - TenantPilot only
        - Microsoft tenant
        - simulation only
        - read-only
    HeaderActionDescriptor:
      type: object
      additionalProperties: false
      required:
        - actionKey
        - label
        - actionKind
        - placement
        - requiresConfirmation
        - usesUiEnforcement
        - operationScope
      properties:
        actionKey:
          type: string
        label:
          type: string
        actionKind:
          $ref: '#/components/schemas/ActionKind'
        placement:
          $ref: '#/components/schemas/Placement'
        requiresConfirmation:
          type: boolean
        usesUiEnforcement:
          type: boolean
        capabilityKey:
          type:
            - string
            - 'null'
        writesAuditLog:
          type: boolean
        operationScope:
          $ref: '#/components/schemas/OperationScope'
    ContextualNavigationEntry:
      type: object
      additionalProperties: false
      required:
        - label
        - sourceSection
        - isAvailable
      properties:
        label:
          type: string
        targetUrl:
          type:
            - string
            - 'null'
        sourceSection:
          type: string
          enum:
            - summary
            - related_context
            - field_context
            - status_context
        isAvailable:
          type: boolean
    SecondaryActionGroup:
      type: object
      additionalProperties: false
      required:
        - label
        - orderedBuckets
        - actions
      properties:
        label:
          type: string
        orderedBuckets:
          type: array
          items:
            type: string
        actions:
          type: array
          items:
            $ref: '#/components/schemas/HeaderActionDescriptor'
    HeaderRegressionExpectation:
      type: object
      additionalProperties: false
      required:
        - maxVisiblePrimaryActions
        - requiresGroupedSecondaryActions
        - allowsPrimaryNavigation
        - requiresExplicitExceptionReason
      properties:
        maxVisiblePrimaryActions:
          type: integer
          minimum: 0
          maximum: 1
        requiresGroupedSecondaryActions:
          type: boolean
        allowsPrimaryNavigation:
          type: boolean
        requiresDangerSeparation:
          type: boolean
        requiresExplicitExceptionReason:
          type: boolean
        browserSmokeRequired:
          type: boolean
    RecordHeaderSurfaceContract:
      type: object
      additionalProperties: false
      required:
        - surfaceKey
        - classification
        - canonicalNoun
        - primaryQuestion
        - actions
        - contextualNavigation
        - regressionExpectation
      properties:
        surfaceKey:
          $ref: '#/components/schemas/SurfaceKey'
        classification:
          $ref: '#/components/schemas/SurfaceClassification'
        canonicalNoun:
          type: string
        primaryQuestion:
          type: string
        primaryAction:
          anyOf:
            - $ref: '#/components/schemas/HeaderActionDescriptor'
            - type: 'null'
        secondaryActionGroup:
          anyOf:
            - $ref: '#/components/schemas/SecondaryActionGroup'
            - type: 'null'
        dangerActions:
          type: array
          items:
            $ref: '#/components/schemas/HeaderActionDescriptor'
        contextualNavigation:
          type: array
          items:
            $ref: '#/components/schemas/ContextualNavigationEntry'
        explicitExceptionReason:
          type:
            - string
            - 'null'
        regressionExpectation:
          $ref: '#/components/schemas/HeaderRegressionExpectation'