## Summary - add the shared operator explanation layer with explanation families, trustworthiness semantics, count descriptors, and centralized badge mappings - adopt explanation-first rendering across baseline compare, governance operation run detail, baseline snapshot presentation, tenant review detail, and review register rows - extend reason translation, artifact-truth presentation, fallback ops UX messaging, and focused regression coverage for operator explanation semantics ## Testing - vendor/bin/sail bin pint --dirty --format agent - vendor/bin/sail artisan test --compact tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php - vendor/bin/sail artisan test --compact ## Notes - Livewire v4 compatible - panel provider registration remains in bootstrap/providers.php - no destructive Filament actions were added or changed in this PR - no new global-search behavior was introduced in this slice Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #191
68 lines
3.5 KiB
PHP
68 lines
3.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\Concerns;
|
|
|
|
use App\Support\ReasonTranslation\NextStepOption;
|
|
use App\Support\ReasonTranslation\ReasonResolutionEnvelope;
|
|
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthCause;
|
|
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthEnvelope;
|
|
use App\Support\Ui\OperatorExplanation\TrustworthinessLevel;
|
|
|
|
trait BuildsOperatorExplanationFixtures
|
|
{
|
|
/**
|
|
* @param array<string, mixed> $overrides
|
|
*/
|
|
protected function makeExplanationReasonEnvelope(array $overrides = []): ReasonResolutionEnvelope
|
|
{
|
|
$nextSteps = $overrides['nextSteps'] ?? [NextStepOption::instruction('Review the recorded prerequisite before retrying.')];
|
|
|
|
return new ReasonResolutionEnvelope(
|
|
internalCode: (string) ($overrides['internalCode'] ?? 'operator.explanation.test'),
|
|
operatorLabel: (string) ($overrides['operatorLabel'] ?? 'Operator attention required'),
|
|
shortExplanation: (string) ($overrides['shortExplanation'] ?? 'TenantPilot recorded a missing prerequisite for this workflow.'),
|
|
actionability: (string) ($overrides['actionability'] ?? 'prerequisite_missing'),
|
|
nextSteps: is_array($nextSteps) ? $nextSteps : [],
|
|
showNoActionNeeded: (bool) ($overrides['showNoActionNeeded'] ?? false),
|
|
diagnosticCodeLabel: $overrides['diagnosticCodeLabel'] ?? 'operator.explanation.test',
|
|
trustImpact: (string) ($overrides['trustImpact'] ?? TrustworthinessLevel::Unusable->value),
|
|
absencePattern: $overrides['absencePattern'] ?? 'blocked_prerequisite',
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $overrides
|
|
*/
|
|
protected function makeArtifactTruthEnvelope(
|
|
array $overrides = [],
|
|
?ReasonResolutionEnvelope $reason = null,
|
|
): ArtifactTruthEnvelope {
|
|
return new ArtifactTruthEnvelope(
|
|
artifactFamily: (string) ($overrides['artifactFamily'] ?? 'test_artifact'),
|
|
artifactKey: (string) ($overrides['artifactKey'] ?? 'test_artifact:1'),
|
|
workspaceId: (int) ($overrides['workspaceId'] ?? 1),
|
|
tenantId: $overrides['tenantId'] ?? 1,
|
|
executionOutcome: $overrides['executionOutcome'] ?? 'completed',
|
|
artifactExistence: (string) ($overrides['artifactExistence'] ?? 'created'),
|
|
contentState: (string) ($overrides['contentState'] ?? 'trusted'),
|
|
freshnessState: (string) ($overrides['freshnessState'] ?? 'current'),
|
|
publicationReadiness: $overrides['publicationReadiness'] ?? null,
|
|
supportState: (string) ($overrides['supportState'] ?? 'normal'),
|
|
actionability: (string) ($overrides['actionability'] ?? 'none'),
|
|
primaryLabel: (string) ($overrides['primaryLabel'] ?? 'Trustworthy artifact'),
|
|
primaryExplanation: $overrides['primaryExplanation'] ?? 'The artifact can be used for the intended operator task.',
|
|
diagnosticLabel: $overrides['diagnosticLabel'] ?? null,
|
|
nextActionLabel: $overrides['nextActionLabel'] ?? null,
|
|
nextActionUrl: $overrides['nextActionUrl'] ?? null,
|
|
relatedRunId: $overrides['relatedRunId'] ?? null,
|
|
relatedArtifactUrl: $overrides['relatedArtifactUrl'] ?? null,
|
|
dimensions: [],
|
|
reason: $reason instanceof ReasonResolutionEnvelope
|
|
? ArtifactTruthCause::fromReasonResolutionEnvelope($reason, 'test_artifact')
|
|
: null,
|
|
);
|
|
}
|
|
}
|