openapi: 3.1.0 info: title: Reason Resolution Logical Contract version: 0.1.0 summary: Logical contract for resolving stable internal reason codes into operator-facing explanation envelopes. description: | This contract is logical rather than transport-prescriptive. It describes the expected behavior of existing presenters, notifications, banners, summaries, and Filament surfaces that consume translated reason state. servers: - url: https://tenantpilot.local paths: /contracts/reasons/resolve: post: summary: Resolve one internal reason code into an operator-facing explanation envelope operationId: resolveReason requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReasonResolutionRequest' responses: '200': description: Operator-facing reason resolved content: application/json: schema: $ref: '#/components/schemas/ReasonResolutionEnvelope' examples: providerConsentMissing: value: internalCode: provider_consent_missing operatorLabel: Admin consent required shortExplanation: The provider connection cannot continue until admin consent is granted. actionability: prerequisite_missing showNoActionNeeded: false nextSteps: - label: Grant admin consent kind: link destination: admin-consent-url authorizationRequired: true scope: tenant diagnosticCodeLabel: provider_consent_missing /contracts/reasons/validate-adoption: post: summary: Validate an adopted surface's translated reason payloads operationId: validateReasonAdoption requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReasonAdoptionValidationRequest' responses: '200': description: Validation result for an adopted reason surface content: application/json: schema: $ref: '#/components/schemas/ReasonAdoptionValidationResponse' components: schemas: ReasonResolutionRequest: type: object additionalProperties: false required: - artifactKey - internalCode - surfaceType properties: artifactKey: type: string example: provider_reason_codes internalCode: type: string example: provider_consent_missing surfaceType: type: string enum: - notification - run_detail - banner - summary_line - table - helper_copy includeDiagnostics: type: boolean default: false actorIsEntitled: type: boolean default: true ReasonResolutionEnvelope: type: object additionalProperties: false required: - internalCode - operatorLabel - shortExplanation - actionability - showNoActionNeeded - nextSteps properties: internalCode: type: string example: provider_consent_missing operatorLabel: type: string example: Admin consent required shortExplanation: type: string example: The provider connection cannot continue until admin consent is granted. actionability: type: string enum: - retryable_transient - permanent_configuration - prerequisite_missing - non_actionable showNoActionNeeded: type: boolean nextSteps: type: array items: $ref: '#/components/schemas/NextStepOption' diagnosticCodeLabel: type: - string - 'null' NextStepOption: type: object additionalProperties: false required: - label - kind - authorizationRequired - scope properties: label: type: string kind: type: string enum: - link - instruction - diagnostic_only destination: type: - string - 'null' authorizationRequired: type: boolean scope: type: string enum: - tenant - workspace - system - none ReasonAdoptionValidationRequest: type: object additionalProperties: false required: - target - envelopes properties: target: type: string example: operations_notifications envelopes: type: array items: $ref: '#/components/schemas/ReasonResolutionEnvelope' ReasonAdoptionValidationResponse: type: object additionalProperties: false required: - valid - violations properties: valid: type: boolean violations: type: array items: type: object additionalProperties: false required: - code - message properties: code: type: string enum: - raw_code_primary_exposure - missing_actionability_class - missing_required_next_step - unauthorized_next_step_exposure - fallback_overuse message: type: string