TenantAtlas/specs/157-reason-code-translation/contracts/reason-resolution.logical.openapi.yaml
ahmido 92f39d9749 feat: add shared reason translation contract (#187)
## Summary
- introduce a shared reason-translation contract with envelopes, presenter helpers, fallback handling, and provider translation support
- adopt translated operator-facing reason presentation across operation runs, notifications, provider guidance, tenant operability, and RBAC-related surfaces
- add Spec 157 design artifacts and targeted regression coverage for translation quality, diagnostics retention, and authorization-safe guidance

## Validation
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact tests/Architecture/ReasonTranslationPrimarySurfaceGuardTest.php tests/Unit/Support/ReasonTranslation/ReasonResolutionEnvelopeTest.php tests/Unit/Support/ReasonTranslation/ExecutionDenialReasonTranslationTest.php tests/Unit/Support/ReasonTranslation/TenantOperabilityReasonTranslationTest.php tests/Unit/Support/ReasonTranslation/RbacReasonTranslationTest.php tests/Unit/Support/ReasonTranslation/ProviderReasonTranslationTest.php tests/Feature/Notifications/OperationRunNotificationTest.php tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php tests/Feature/ReasonTranslation/GovernanceReasonPresentationTest.php tests/Feature/Authorization/ReasonTranslationScopeSafetyTest.php tests/Feature/Monitoring/OperationRunBlockedSpec081Test.php tests/Feature/ProviderConnections/ProviderOperationBlockedGuidanceSpec081Test.php tests/Feature/ProviderConnections/ProviderGatewayRuntimeSmokeSpec081Test.php`

## Notes
- Livewire v4.0+ compliance remains unchanged within the existing Filament v5 stack.
- No new panel was added; provider registration remains in `bootstrap/providers.php`.
- No new globally searchable resource was introduced.
- No new destructive action family was introduced.
- No new assets were added; the existing `filament:assets` deployment behavior remains unchanged.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #187
2026-03-22 20:19:43 +00:00

201 lines
5.8 KiB
YAML

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