openapi: 3.1.0 info: title: Tenant Lifecycle, Operability, and Context Semantics Admin Contract version: 0.1.0 summary: Contract for selector, tenant-bound, onboarding, and canonical workspace record semantics in Spec 143. description: >- This contract documents the expected HTTP-level behavior for the admin-plane routes affected by tenant lifecycle, operability, and remembered tenant context semantics. servers: - url: /admin tags: - name: Tenant Context - name: Tenant Management - name: Onboarding - name: Operations paths: /choose-tenant: get: tags: [Tenant Context] summary: Show normal tenant context choices for the current workspace. description: >- Returns the tenant chooser surface. Only tenants that are eligible for normal active operating context may be shown as selectable choices. responses: '200': description: Tenant chooser rendered. content: text/html: schema: type: string '404': description: No valid workspace context or user is not entitled to the workspace. /select-tenant: post: tags: [Tenant Context] summary: Persist the remembered tenant context for the current workspace. requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object required: [tenant_id] properties: tenant_id: type: integer responses: '302': description: Tenant context remembered and browser redirected to the tenant dashboard. '404': description: Tenant not found in current workspace, not entitled, or not eligible for normal active context. '403': description: User is unauthenticated or otherwise not allowed to execute the selection mutation. /clear-tenant-context: post: tags: [Tenant Context] summary: Clear the remembered tenant context for the current workspace. responses: '302': description: Remembered tenant context cleared and browser redirected. /tenants/{tenant}: get: tags: [Tenant Management] summary: View a tenant-bound admin page. description: >- Route legitimacy is based on the route tenant plus workspace and tenant entitlement checks, not on the currently remembered tenant context. parameters: - $ref: '#/components/parameters/TenantExternalId' responses: '200': description: Tenant detail page rendered. content: text/html: schema: type: string '404': description: User lacks workspace membership or tenant entitlement, or tenant is not in scope. '403': description: User is a member but lacks a capability for a requested mutation action on this page. /onboarding: get: tags: [Onboarding] summary: View workspace-scoped managed tenant onboarding. responses: '200': description: Onboarding landing or wizard rendered. content: text/html: schema: type: string '404': description: User lacks workspace membership. '403': description: User is a workspace member but lacks onboarding capability. /onboarding/{onboardingDraft}: get: tags: [Onboarding] summary: View or resume a specific onboarding draft. parameters: - $ref: '#/components/parameters/OnboardingDraftId' responses: '200': description: Onboarding draft rendered. content: text/html: schema: type: string '404': description: User lacks workspace membership or tenant entitlement for the linked draft context. '403': description: User is a workspace member but lacks onboarding capability. /operations: get: tags: [Operations] summary: View the workspace-scoped operations index. description: >- Workspace-scoped monitoring route. Tenant context may act as a default filter, but not as a validity requirement. responses: '200': description: Operations index rendered. content: text/html: schema: type: string '404': description: User lacks workspace membership. /operations/{run}: get: tags: [Operations] summary: View a canonical workspace-owned operation run. description: >- Canonical record viewer. If the user is entitled to the workspace and referenced tenant, the page remains valid even when the remembered active tenant differs from the run's tenant. parameters: - $ref: '#/components/parameters/OperationRunId' responses: '200': description: Operation run viewer rendered. content: text/html: schema: type: string '404': description: User lacks workspace membership, lacks referenced tenant entitlement, or the run is not in workspace scope. '403': description: User is a workspace or tenant member but lacks the capability resolved for the run type. components: parameters: TenantExternalId: name: tenant in: path required: true schema: type: string description: Tenant route key external ID. OnboardingDraftId: name: onboardingDraft in: path required: true schema: type: integer description: Workspace-scoped onboarding draft identifier. OperationRunId: name: run in: path required: true schema: type: integer description: Canonical operation run identifier. schemas: TenantLifecycleState: type: string enum: [draft, onboarding, active, archived] PageCategory: type: string enum: - workspace_scoped - tenant_bound - onboarding_workflow - canonical_workspace_record_viewer AuthorizationOutcome: type: object required: [membership_scope, capability_scope, response_behavior] properties: membership_scope: type: string enum: [workspace, tenant, onboarding_draft, canonical_record] capability_scope: type: string response_behavior: type: string enum: [allow, deny_as_not_found, forbid] TenantOperabilityDecision: type: object required: - lifecycle - can_view_tenant_surface - can_select_as_context - can_operate - can_archive - can_restore - can_resume_onboarding - can_reference_in_workspace_monitoring properties: lifecycle: $ref: '#/components/schemas/TenantLifecycleState' can_view_tenant_surface: type: boolean can_select_as_context: type: boolean can_operate: type: boolean can_archive: type: boolean can_restore: type: boolean can_resume_onboarding: type: boolean can_reference_in_workspace_monitoring: type: boolean CanonicalViewerContextMismatch: type: object required: [selected_tenant_id, referenced_tenant_id, behavior] properties: selected_tenant_id: type: integer nullable: true referenced_tenant_id: type: integer nullable: true behavior: type: string enum: [ignore_for_legitimacy, show_context_banner]