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