TenantAtlas/apps/platform/app/Support/Baselines/CompareSemantics/CompareResultReason.php
ahmido ea77c8c718 feat(baselines): implement baseline compare result semantics (#454)
Implemented deterministic Baseline Result Semantics (Spec 383), introducing CompareSubjectResult and CompareEvidenceResult. Replaced generic arrays with strict Data Transfer Objects for Baseline engine output.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #454
2026-06-16 20:20:27 +00:00

154 lines
7.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Support\Baselines\CompareSemantics;
enum CompareResultReason: string
{
case VerifiedNoDrift = 'verified_no_drift';
case VerifiedDriftDetected = 'verified_drift_detected';
case ResolvedActiveBinding = 'resolved_active_binding';
case ResolvedCanonicalIdentity = 'resolved_canonical_identity';
case ResolvedProviderIdentity = 'resolved_provider_identity';
case IdentityRequired = 'identity_required';
case UnresolvedDuplicateCandidates = 'unresolved_duplicate_candidates';
case UnresolvedLowTrustMatch = 'unresolved_low_trust_match';
case UnresolvedAmbiguousIdentity = 'unresolved_ambiguous_identity';
case MissingLocalEvidence = 'missing_local_evidence';
case MissingProviderResource = 'missing_provider_resource';
case UnsupportedResourceClass = 'unsupported_resource_class';
case FoundationInventoryOnly = 'foundation_inventory_only';
case FoundationIdentityOnly = 'foundation_identity_only';
case FoundationCanonicalOnly = 'foundation_canonical_only';
case AcceptedLimitation = 'accepted_limitation';
case ExcludedNonGoverned = 'excluded_non_governed';
case CompareNotSupported = 'compare_not_supported';
case CompareFailed = 'compare_failed';
public function category(): CompareResultCategory
{
return match ($this) {
self::VerifiedNoDrift => CompareResultCategory::Verified,
self::VerifiedDriftDetected => CompareResultCategory::DriftDetected,
self::IdentityRequired,
self::UnresolvedDuplicateCandidates,
self::UnresolvedLowTrustMatch,
self::UnresolvedAmbiguousIdentity => CompareResultCategory::ActionRequired,
self::MissingLocalEvidence => CompareResultCategory::MissingEvidence,
self::MissingProviderResource => CompareResultCategory::MissingProviderResource,
self::UnsupportedResourceClass,
self::CompareNotSupported => CompareResultCategory::Unsupported,
self::FoundationInventoryOnly,
self::FoundationIdentityOnly,
self::FoundationCanonicalOnly,
self::AcceptedLimitation => CompareResultCategory::Limitation,
self::ExcludedNonGoverned => CompareResultCategory::Excluded,
self::CompareFailed => CompareResultCategory::Failed,
self::ResolvedActiveBinding,
self::ResolvedCanonicalIdentity,
self::ResolvedProviderIdentity => CompareResultCategory::Verified,
};
}
public function actionability(): CompareResultActionability
{
return match ($this) {
self::VerifiedNoDrift,
self::VerifiedDriftDetected,
self::ResolvedActiveBinding,
self::ResolvedCanonicalIdentity,
self::ResolvedProviderIdentity => CompareResultActionability::None,
self::IdentityRequired,
self::UnresolvedDuplicateCandidates,
self::UnresolvedLowTrustMatch,
self::UnresolvedAmbiguousIdentity => CompareResultActionability::BindingRequired,
self::MissingLocalEvidence => CompareResultActionability::ProviderDataRefreshRequired,
self::MissingProviderResource => CompareResultActionability::OperatorActionRequired,
self::UnsupportedResourceClass,
self::CompareNotSupported => CompareResultActionability::ImplementationGap,
self::FoundationInventoryOnly,
self::FoundationIdentityOnly,
self::FoundationCanonicalOnly,
self::AcceptedLimitation => CompareResultActionability::Accepted,
self::ExcludedNonGoverned => CompareResultActionability::Excluded,
self::CompareFailed => CompareResultActionability::ImplementationGap,
};
}
public function readinessImpact(): CompareResultReadinessImpact
{
return match ($this) {
self::VerifiedNoDrift,
self::VerifiedDriftDetected,
self::ResolvedActiveBinding,
self::ResolvedCanonicalIdentity,
self::ResolvedProviderIdentity,
self::ExcludedNonGoverned => CompareResultReadinessImpact::NoImpact,
self::FoundationInventoryOnly,
self::FoundationIdentityOnly,
self::FoundationCanonicalOnly,
self::AcceptedLimitation => CompareResultReadinessImpact::CustomerLimitation,
self::IdentityRequired,
self::UnresolvedDuplicateCandidates,
self::UnresolvedLowTrustMatch,
self::UnresolvedAmbiguousIdentity,
self::MissingLocalEvidence,
self::MissingProviderResource => CompareResultReadinessImpact::CustomerBlocker,
self::UnsupportedResourceClass,
self::CompareNotSupported => CompareResultReadinessImpact::InternalLimitation,
self::CompareFailed => CompareResultReadinessImpact::InternalBlocker,
};
}
public function coverageStatus(): CompareResultCoverageStatus
{
return match ($this) {
self::VerifiedNoDrift,
self::VerifiedDriftDetected,
self::ResolvedActiveBinding,
self::ResolvedCanonicalIdentity,
self::ResolvedProviderIdentity => CompareResultCoverageStatus::FullyVerified,
self::MissingLocalEvidence,
self::IdentityRequired,
self::UnresolvedDuplicateCandidates,
self::UnresolvedLowTrustMatch,
self::UnresolvedAmbiguousIdentity,
self::CompareFailed => CompareResultCoverageStatus::MissingLocalEvidence,
self::MissingProviderResource => CompareResultCoverageStatus::MissingProviderResource,
self::UnsupportedResourceClass,
self::CompareNotSupported => CompareResultCoverageStatus::Unsupported,
self::FoundationInventoryOnly => CompareResultCoverageStatus::InventoryOnly,
self::FoundationIdentityOnly => CompareResultCoverageStatus::IdentityOnly,
self::FoundationCanonicalOnly => CompareResultCoverageStatus::CanonicalOnly,
self::AcceptedLimitation => CompareResultCoverageStatus::AcceptedLimitation,
self::ExcludedNonGoverned => CompareResultCoverageStatus::Excluded,
};
}
public function defaultTrustLevel(): CompareResultTrustLevel
{
return match ($this) {
self::VerifiedNoDrift,
self::VerifiedDriftDetected,
self::ResolvedActiveBinding => CompareResultTrustLevel::High,
self::ResolvedCanonicalIdentity,
self::ResolvedProviderIdentity,
self::FoundationInventoryOnly,
self::FoundationIdentityOnly,
self::FoundationCanonicalOnly,
self::AcceptedLimitation => CompareResultTrustLevel::Medium,
self::IdentityRequired,
self::UnresolvedDuplicateCandidates,
self::UnresolvedLowTrustMatch,
self::UnresolvedAmbiguousIdentity,
self::MissingLocalEvidence,
self::MissingProviderResource,
self::UnsupportedResourceClass,
self::CompareNotSupported => CompareResultTrustLevel::Untrusted,
self::ExcludedNonGoverned => CompareResultTrustLevel::NotApplicable,
self::CompareFailed => CompareResultTrustLevel::Failed,
};
}
}