forArtifactTruth($reasonCode, 'artifact_truth'); expect($envelope)->not->toBeNull() ->and($envelope?->trustImpact)->toBe($expectedTrustImpact) ->and($envelope?->absencePattern)->toBe($expectedAbsencePattern) ->and(app(ReasonPresenter::class)->dominantCauseExplanation($envelope))->not->toBe(''); })->with([ 'trustworthy no-drift compare result' => [ BaselineCompareReasonCode::NoDriftDetected->value, TrustworthinessLevel::Trustworthy->value, 'true_no_result', ], 'suppressed compare result' => [ BaselineCompareReasonCode::CoverageUnproven->value, TrustworthinessLevel::LimitedConfidence->value, 'suppressed_output', ], 'missing baseline input' => [ BaselineReasonCodes::SNAPSHOT_CAPTURE_FAILED, TrustworthinessLevel::LimitedConfidence->value, 'unavailable', ], 'fallback review blocker' => [ 'review_missing_sections', TrustworthinessLevel::Unusable->value, 'missing_input', ], ]); it('keeps governance reason ownership and family semantics explicit', function (): void { $presenter = app(ReasonPresenter::class); $semantics = $presenter->semantics( $presenter->forArtifactTruth(BaselineCompareReasonCode::CoverageUnproven->value, 'artifact_truth'), ); expect($semantics)->not->toBeNull() ->and($semantics['owner_label'] ?? null)->toBe('Governance detail') ->and($semantics['family_label'] ?? null)->toBe('Coverage') ->and($semantics['boundary_classification'] ?? null)->toBe(PlatformVocabularyGlossary::BOUNDARY_CROSS_DOMAIN_GOVERNANCE); });