openapi: 3.1.0 info: title: Tenant Context Enforcement Contract version: 0.1.0 description: >- Internal route and state contract for Spec 147. This feature does not introduce new public APIs; the contract documents the expected behavior of the existing workspace and tenant context routes plus the shared context-resolution object. paths: /admin/choose-tenant: get: summary: Render the standard active-lane tenant selector operationId: showChooseTenant responses: '200': description: Choose-tenant page rendered for the current workspace content: application/json: schema: $ref: '#/components/schemas/ChooseTenantSurfaceContract' /admin/select-tenant: post: summary: Persist active-lane tenant context for the current workspace operationId: selectTenantContext requestBody: required: true content: application/json: schema: type: object additionalProperties: false required: - tenant_id properties: tenant_id: type: integer responses: '302': description: 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-lane selection /admin/clear-tenant-context: post: summary: Clear remembered tenant context for the current workspace operationId: clearTenantContext responses: '302': description: Tenant context cleared and redirect issued to a workspace-safe destination /admin/switch-workspace: post: summary: Switch the current workspace and re-evaluate tenant context operationId: switchWorkspace requestBody: required: true content: application/json: schema: type: object additionalProperties: false required: - workspace_id properties: workspace_id: type: integer responses: '302': description: Workspace switched and tenant context cleared or re-evaluated for the new workspace '404': description: Workspace missing, archived, or actor is not a member /admin/tenants/{tenant}: get: summary: Resolve tenant-bound route subject independently from selected tenant context operationId: viewTenantRouteSubject parameters: - in: path name: tenant required: true schema: type: string responses: '200': description: Authorized tenant-bound page renders from route subject authority '404': description: Tenant missing or actor not entitled to tenant scope '403': description: Actor is a tenant member but lacks a required capability for the page or action /admin/operations/{run}: get: summary: Resolve canonical workspace record viewer independently from selected tenant context operationId: viewCanonicalOperationRun parameters: - in: path name: run required: true schema: type: string responses: '200': description: Authorized canonical run viewer renders even when selected tenant differs or is absent '404': description: Run missing, workspace membership missing, or tenant entitlement missing for a referenced tenant '403': description: Actor is otherwise in scope but lacks the required capability for the run type components: schemas: ActiveSelectorOption: type: object additionalProperties: false required: - tenantId - workspaceId - lifecycle - isEligible properties: tenantId: type: integer workspaceId: type: integer lifecycle: type: string enum: - draft - onboarding - active - archived isEligible: type: boolean description: Must be true only for tenants eligible for standard active-lane selection. selectorLabel: type: - string - 'null' 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: type: - string - 'null' enum: - workspace_mismatch - tenant_missing - tenant_not_entitled - tenant_not_selector_eligible - explicit_clear - null ChooseTenantSurfaceContract: type: object additionalProperties: false required: - workspaceId - selectorMeaning - options properties: workspaceId: type: integer selectorMeaning: type: string const: normal_active_operating_context options: type: array items: $ref: '#/components/schemas/ActiveSelectorOption' emptyStateBehavior: type: string enum: - no_active_tenants_available - workspace_selection_required RouteLegitimacyContract: type: object additionalProperties: false required: - routeType - authority - selectedTenantInfluence properties: routeType: type: string enum: - workspace_level - tenant_bound - canonical_workspace_record authority: type: string enum: - workspace - route_tenant - route_record selectedTenantInfluence: type: string enum: - none - informational_only - filter_only