openapi: 3.1.0
info:
  title: Action Surface Governance Internal Contract
  version: 0.1.0
  summary: Internal logical contract for declaration, discovery, and validation behavior in Spec 169
  description: |
    This contract is an internal planning artifact for Spec 169. It documents the
    declaration shape, discovery scope, and validation behavior required to keep
    the Action Surface Contract behavior-aware. It does not add a public HTTP API.
servers:
  - url: /internal
x-governed-surface-families:
  - family: clickable_row_reference
    classes:
      - app/Filament/Pages/Monitoring/Operations.php
      - app/Filament/Resources/OperationRunResource.php
    guardTests:
      - tests/Feature/Guards/ActionSurfaceContractTest.php
  - family: explicit_inspect_history_reference
    classes:
      - app/Filament/Pages/Monitoring/AuditLog.php
      - app/Filament/System/Pages/Security/AccessLogs.php
    guardTests:
      - tests/Feature/Guards/ActionSurfaceContractTest.php
  - family: explicit_inspect_queue_reference
    classes:
      - app/Filament/Pages/Monitoring/FindingExceptionsQueue.php
    guardTests:
      - tests/Feature/Guards/ActionSurfaceContractTest.php
  - family: reporting_registry_reference
    classes:
      - app/Filament/Pages/Monitoring/EvidenceOverview.php
      - app/Filament/Pages/Reviews/ReviewRegister.php
    guardTests:
      - tests/Feature/Guards/ActionSurfaceContractTest.php
  - family: destructive_last_reference
    classes:
      - app/Filament/Resources/BackupScheduleResource.php
      - app/Filament/Resources/TenantResource.php
    guardTests:
      - tests/Feature/Guards/ActionSurfaceContractTest.php
      - tests/Feature/Rbac/TenantActionSurfaceConsistencyTest.php
  - family: system_discovery_reference
    classes:
      - app/Filament/System/Pages/Ops/Runs.php
      - app/Filament/System/Pages/Ops/Failures.php
      - app/Filament/System/Pages/Ops/Stuck.php
      - app/Filament/System/Pages/Directory/Tenants.php
      - app/Filament/System/Pages/Directory/Workspaces.php
      - app/Filament/System/Pages/Security/AccessLogs.php
    guardTests:
      - tests/Feature/Guards/ActionSurfaceContractTest.php
paths:
  /action-surfaces/discovered:
    get:
      summary: Discover the repository-wide action-surface validation scope
      operationId: discoverActionSurfaces
      responses:
        '200':
          description: Current discovery snapshot for validator coverage
          content:
            application/vnd.tenantatlas.action-surface-discovery+json:
              schema:
                $ref: '#/components/schemas/DiscoverySnapshot'
  /action-surfaces/components/{className}:
    get:
      summary: Resolve the declaration contract for one discovered component
      operationId: resolveActionSurfaceDeclaration
      parameters:
        - name: className
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Declaration contract for the requested component
          content:
            application/vnd.tenantatlas.action-surface-declaration+json:
              schema:
                $ref: '#/components/schemas/ActionSurfaceDeclarationV11'
        '404':
          description: Component is not in the primary discovery scope
  /action-surfaces/validate:
    post:
      summary: Validate discovered declarations against behavior-aware contract rules
      operationId: validateActionSurfaces
      requestBody:
        required: true
        content:
          application/vnd.tenantatlas.action-surface-validation-request+json:
            schema:
              $ref: '#/components/schemas/ValidationRequest'
      responses:
        '200':
          description: Validation completed
          content:
            application/vnd.tenantatlas.action-surface-validation-result+json:
              schema:
                $ref: '#/components/schemas/ValidationResult'
components:
  schemas:
    ActionSurfaceComponentType:
      type: string
      enum:
        - resource
        - page
        - relation_manager
    ActionSurfaceProfile:
      type: string
      enum:
        - crud_list_and_edit
        - crud_list_and_view
        - list_only_read_only
        - run_log
        - relation_manager
    ActionSurfaceType:
      type: string
      enum:
        - crud_list_first_resource
        - read_only_registry_report
        - queue_review
        - history_audit
        - config_lite
    ActionSurfaceInspectAffordance:
      type: string
      enum:
        - clickable_row
        - view_action
        - primary_link_column
    ActionSurfaceSlot:
      type: string
      enum:
        - list_header
        - inspect_affordance
        - list_row_more_menu
        - list_bulk_more_group
        - list_empty_state
        - detail_header
    ActionSurfaceDefaults:
      type: object
      additionalProperties: false
      required:
        - moreGroupLabel
        - exportIsDefaultBulkActionForReadOnly
      properties:
        moreGroupLabel:
          type: string
          const: More
        exportIsDefaultBulkActionForReadOnly:
          type: boolean
    SlotRequirement:
      type: object
      additionalProperties: false
      required:
        - state
      properties:
        state:
          type: string
          enum:
            - satisfied
            - exempt
        details:
          type:
            - string
            - 'null'
        requiresTypedConfirmation:
          type: boolean
    SlotExemption:
      type: object
      additionalProperties: false
      required:
        - slot
        - reason
      properties:
        slot:
          $ref: '#/components/schemas/ActionSurfaceSlot'
        reason:
          type: string
        trackingRef:
          type:
            - string
            - 'null'
    ActionSurfaceDeclarationV11:
      type: object
      additionalProperties: false
      required:
        - version
        - componentType
        - profile
        - surfaceType
        - defaults
        - slots
      properties:
        version:
          type: integer
          minimum: 1
        componentType:
          $ref: '#/components/schemas/ActionSurfaceComponentType'
        profile:
          $ref: '#/components/schemas/ActionSurfaceProfile'
        surfaceType:
          $ref: '#/components/schemas/ActionSurfaceType'
        defaults:
          $ref: '#/components/schemas/ActionSurfaceDefaults'
        slots:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/SlotRequirement'
        exemptions:
          type: array
          items:
            $ref: '#/components/schemas/SlotExemption'
        listRowPrimaryActionLimit:
          type:
            - integer
            - 'null'
          minimum: 0
        primaryLinkColumnReason:
          type:
            - string
            - 'null'
    DiscoveredComponent:
      type: object
      additionalProperties: false
      required:
        - className
        - componentType
      properties:
        className:
          type: string
        componentType:
          $ref: '#/components/schemas/ActionSurfaceComponentType'
        discoveryFamily:
          type: string
          enum:
            - resource
            - page
            - relation_manager
            - system_table_page
    DiscoverySnapshot:
      type: object
      additionalProperties: false
      required:
        - components
        - excludedFamilies
      properties:
        components:
          type: array
          items:
            $ref: '#/components/schemas/DiscoveredComponent'
        excludedFamilies:
          type: array
          items:
            type: string
          example:
            - widgets
            - auth_pages
            - dashboards
            - chooser_pages
            - onboarding_wizards
            - deferred_system_pages
    InspectDecisionRule:
      type: object
      additionalProperties: false
      required:
        - surfaceType
        - allowedAffordances
        - redundantViewForbidden
      properties:
        surfaceType:
          $ref: '#/components/schemas/ActionSurfaceType'
        allowedAffordances:
          type: array
          items:
            $ref: '#/components/schemas/ActionSurfaceInspectAffordance'
        redundantViewForbidden:
          type: boolean
        primaryLinkReasonRequired:
          type: boolean
    OrderingRule:
      type: object
      additionalProperties: false
      required:
        - moreGroupLabel
        - inspectionHelpersFirst
        - workflowAfterNavigation
        - destructiveLast
        - emptyGroupsForbidden
      properties:
        moreGroupLabel:
          type: string
          const: More
        inspectionHelpersFirst:
          type: boolean
        workflowAfterNavigation:
          type: boolean
        destructiveLast:
          type: boolean
        emptyGroupsForbidden:
          type: boolean
    ValidationRequest:
      type: object
      additionalProperties: false
      required:
        - enforceSystemPanelDiscovery
        - enforceBehaviorRules
      properties:
        enforceSystemPanelDiscovery:
          type: boolean
          const: true
        enforceBehaviorRules:
          type: boolean
          const: true
    ValidationIssue:
      type: object
      additionalProperties: false
      required:
        - className
        - message
      properties:
        className:
          type: string
        slot:
          anyOf:
            - $ref: '#/components/schemas/ActionSurfaceSlot'
            - type: 'null'
        message:
          type: string
        hint:
          type:
            - string
            - 'null'
    ValidationResult:
      type: object
      additionalProperties: false
      required:
        - componentCount
        - issues
      properties:
        componentCount:
          type: integer
          minimum: 0
        issues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'