openapi: 3.1.0
info:
  title: Tenant Operability Policy Internal Admin Contract
  version: 0.1.0
  summary: Internal planning contract for centralized tenant operability resolution
  description: |
    This is an internal design artifact for Spec 148. It documents the intended
    route and support-layer semantics for selector eligibility, remembered-context
    validation, tenant-bound viewability, canonical linked-record viewability,
    and lifecycle-safe action eligibility. It does not require a new public HTTP API.
servers:
  - url: /internal/admin
tags:
  - name: Operability Policy
  - name: Context Management
  - name: Route Semantics
paths:
  /tenants/{tenant}/operability:
    get:
      tags: [Operability Policy]
      summary: Resolve one tenant-semantic decision for a specific lane and actor context
      operationId: resolveTenantOperability
      parameters:
        - $ref: '#/components/parameters/TenantId'
        - name: lane
          in: query
          required: true
          schema:
            $ref: '#/components/schemas/TenantInteractionLane'
        - name: question
          in: query
          required: true
          schema:
            $ref: '#/components/schemas/TenantOperabilityQuestion'
      responses:
        '200':
          description: Operability decision resolved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TenantOperabilityOutcome'
        '403':
          description: Actor is in scope but lacks the required capability for the requested action semantics
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Tenant is outside workspace or tenant entitlement scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /admin/select-tenant:
    post:
      tags: [Context Management]
      summary: Persist remembered tenant context only when selector-lane operability allows it
      operationId: selectTenantContext
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - tenant_id
              properties:
                tenant_id:
                  type: integer
      responses:
        '302':
          description: Remembered tenant context accepted and redirect issued to the tenant-lane destination
        '404':
          description: Tenant missing, outside workspace, not entitled, or not eligible for standard active selection
  /admin/clear-tenant-context:
    post:
      tags: [Context Management]
      summary: Clear remembered tenant context for the current workspace
      operationId: clearTenantContext
      responses:
        '302':
          description: Remembered tenant context cleared and workspace-safe redirect issued
  /admin/tenants/{tenant}:
    get:
      tags: [Route Semantics]
      summary: Resolve tenant-bound route legitimacy from route tenant plus operability and authorization
      operationId: viewTenantBoundPage
      parameters:
        - $ref: '#/components/parameters/TenantRouteKey'
      responses:
        '200':
          description: Tenant-bound page rendered for an authorized actor
        '403':
          description: Actor is in scope but lacks a required capability for the page or follow-up action
        '404':
          description: Tenant missing or actor not entitled to tenant scope
  /admin/operations/{run}:
    get:
      tags: [Route Semantics]
      summary: Resolve canonical workspace record viewer without requiring selected tenant equality
      operationId: viewCanonicalOperationRun
      parameters:
        - name: run
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Authorized canonical run viewer rendered
        '403':
          description: Actor is in scope but lacks capability for the run type or follow-up action
        '404':
          description: Run missing, workspace missing, or tenant entitlement missing for the referenced tenant
components:
  parameters:
    TenantId:
      name: tenant
      in: path
      required: true
      schema:
        type: integer
      description: Canonical tenant primary key used for internal policy resolution.
    TenantRouteKey:
      name: tenant
      in: path
      required: true
      schema:
        type: string
      description: External tenant route key used by tenant-bound admin routes.
  schemas:
    TenantInteractionLane:
      type: string
      enum:
        - standard_active_operating
        - onboarding_workflow
        - administrative_management
        - canonical_workspace_record
    TenantOperabilityQuestion:
      type: string
      enum:
        - selector_eligibility
        - remembered_context_validity
        - tenant_bound_viewability
        - canonical_linked_record_viewability
        - archive_eligibility
        - restore_eligibility
        - resume_onboarding_eligibility
        - onboarding_completion_eligibility
        - verification_readiness_eligibility
        - administrative_discoverability
    TenantOperabilityReasonCode:
      type:
        - string
        - 'null'
      enum:
        - workspace_mismatch
        - tenant_not_entitled
        - missing_capability
        - wrong_lane
        - selector_ineligible_lifecycle
        - tenant_not_archived
        - tenant_already_archived
        - onboarding_not_resumable
        - remembered_context_stale
        - canonical_view_followup_only
        - null
    TenantOperabilityOutcome:
      type: object
      additionalProperties: false
      required:
        - tenantId
        - lifecycle
        - lane
        - question
        - allowed
        - discoverable
      properties:
        tenantId:
          type: integer
        lifecycle:
          type: string
          enum:
            - draft
            - onboarding
            - active
            - archived
        lane:
          $ref: '#/components/schemas/TenantInteractionLane'
        question:
          $ref: '#/components/schemas/TenantOperabilityQuestion'
        allowed:
          type: boolean
        discoverable:
          type: boolean
        requiredCapability:
          type:
            - string
            - 'null'
        reasonCode:
          $ref: '#/components/schemas/TenantOperabilityReasonCode'
        informationalMessageKey:
          type:
            - string
            - 'null'
        metadata:
          type: object
          additionalProperties: true
    RememberedTenantContextState:
      type: object
      additionalProperties: false
      required:
        - workspaceId
        - status
      properties:
        workspaceId:
          type: integer
        tenantId:
          type:
            - integer
            - 'null'
        status:
          type: string
          enum:
            - no_selected_tenant
            - remembered_active
            - route_authoritative_tenant
            - stale_context_cleared
        invalidationReason:
          $ref: '#/components/schemas/TenantOperabilityReasonCode'
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      properties:
        code:
          type: string
        message:
          type: string