openapi: 3.1.0
info:
  title: Action Surface Closure Logical Contract
  version: 0.1.0
  description: >-
    Logical design contract for Spec 195 residual action-surface closure.
    This is a planning artifact that defines the required reviewable shape for
    residual pages that sit outside or alongside the primary action-surface
    discovery path.
servers:
  - url: https://logical-spec.local
    description: Non-runtime planning contract
paths:
  /internal/action-surfaces/residual:
    get:
      summary: List Spec 195 residual action-surface closure entries
      operationId: listResidualActionSurfaceClosures
      responses:
        '200':
          description: Residual closure entries in validator order
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ResidualActionSurfaceClosure'
  /internal/action-surfaces/residual/{surfaceKey}:
    get:
      summary: Read one Spec 195 residual action-surface closure entry
      operationId: getResidualActionSurfaceClosure
      parameters:
        - name: surfaceKey
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/SurfaceKey'
      responses:
        '200':
          description: Residual closure entry
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    $ref: '#/components/schemas/ResidualActionSurfaceClosure'
components:
  schemas:
    SurfaceKey:
      type: string
      pattern: '^[a-z0-9_]+$'
      description: Stable machine-readable key for one residual surface. The initial seed list is recorded in x-spec-195-notes.seedSurfaceKeys and may be extended by audit.
    DiscoveryState:
      type: string
      enum:
        - primary_discovered
        - primary_discovered_baseline_exempt
        - outside_primary_discovery
    ClosureDecision:
      type: string
      enum:
        - generic_contract_enrollment
        - intentional_exemption
        - separately_governed
        - retired_no_longer_relevant
        - harmless_special_case
    ReasonCategory:
      type: string
      enum:
        - system_triage_surface
        - workflow_specific_governance
        - break_glass_repair_utility
        - read_mostly_context_detail
        - disabled_or_actionless_surface
        - selector_routing_only
        - registration_form_with_dedicated_rbac
        - landing_routing_surface
        - dashboard_shell_widget_owned
        - security_flow_exception
    FollowUpAction:
      type: string
      enum:
        - none
        - tighten_reason
        - add_guard_only
        - add_focused_test
        - consider_enrollment
    EvidenceDescriptor:
      type: object
      required:
        - reference
        - proves
      properties:
        reference:
          type: string
        proves:
          type: string
        kind:
          type: string
          enum:
            - guard_test
            - feature_livewire_test
            - authorization_test
            - workflow_spec
            - audit_test
            - db_only_surface_test
    ResidualActionSurfaceClosureBase:
      type: object
      required:
        - surfaceKey
        - surfaceName
        - pageClass
        - panelPlane
        - surfaceKind
        - discoveryState
        - closureDecision
        - explicitReason
        - evidence
        - followUpAction
        - mustRemainBaselineExempt
        - mustNotRemainBaselineExempt
      properties:
        surfaceKey:
          $ref: '#/components/schemas/SurfaceKey'
        surfaceName:
          type: string
          description: Human-readable review name for the residual surface
        pageClass:
          type: string
        panelPlane:
          type: string
          enum:
            - admin
            - tenant
            - system
        surfaceKind:
          type: string
          enum:
            - system_detail
            - system_utility
            - selector
            - wizard
            - landing
            - dashboard_shell
            - recovery_flow
            - read_mostly_context
        discoveryState:
          $ref: '#/components/schemas/DiscoveryState'
        closureDecision:
          $ref: '#/components/schemas/ClosureDecision'
        reasonCategory:
          anyOf:
            - $ref: '#/components/schemas/ReasonCategory'
            - type: 'null'
        explicitReason:
          type: string
        evidence:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/EvidenceDescriptor'
        followUpAction:
          $ref: '#/components/schemas/FollowUpAction'
        mustRemainBaselineExempt:
          type: boolean
        mustNotRemainBaselineExempt:
          type: boolean
    ResidualActionSurfaceClosure:
      allOf:
        - $ref: '#/components/schemas/ResidualActionSurfaceClosureBase'
        - oneOf:
            - properties:
                closureDecision:
                  const: generic_contract_enrollment
            - required:
                - reasonCategory
              properties:
                closureDecision:
                  type: string
                  enum:
                    - intentional_exemption
                    - separately_governed
                    - retired_no_longer_relevant
                    - harmless_special_case
                reasonCategory:
                  $ref: '#/components/schemas/ReasonCategory'
x-spec-195-notes:
  seedSurfaceKeys:
    - system_dashboard
    - system_ops_view_run
    - system_ops_runbooks
    - repair_workspace_owners
    - system_directory_view_tenant
    - system_directory_view_workspace
    - break_glass_recovery
    - choose_workspace
    - choose_tenant
    - register_tenant
    - managed_tenant_onboarding_wizard
    - managed_tenants_landing
    - tenant_dashboard
  consumers:
    - apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php
    - apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php
    - apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php
    - apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php
    - apps/platform/tests/Feature/Guards/Spec195ResidualActionSurfaceClosureGuardTest.php
  nonGoals:
    - runtime API exposure
    - new persistence
    - new provider or routing structure
    - widening primary action-surface discovery to every Filament page class
