operatorExplanation(); $findingsVisibleCount = (int) ($stats->findingsCount ?? 0); $highSeverityCount = (int) ($stats->severityCounts['high'] ?? 0); $reasonCode = is_string($stats->reasonCode) ? BaselineCompareReasonCode::tryFrom($stats->reasonCode) : null; $evaluationResult = $stats->state === 'failed' ? 'failed_result' : $explanation->evaluationResult; $positiveClaimAllowed = $this->positiveClaimAllowed($stats, $explanation, $reasonCode, $evaluationResult); $isStale = $this->hasStaleResult($stats, $evaluationResult); $stateFamily = $this->stateFamily($stats, $findingsVisibleCount, $positiveClaimAllowed, $isStale); return new BaselineCompareSummaryAssessment( stateFamily: $stateFamily, headline: $this->headline($stats, $stateFamily, $findingsVisibleCount, $highSeverityCount, $evaluationResult), supportingMessage: $this->supportingMessage($stats, $stateFamily, $findingsVisibleCount, $evaluationResult), tone: $this->tone($stats, $stateFamily), positiveClaimAllowed: $positiveClaimAllowed, trustworthinessLevel: $explanation->trustworthinessLevel->value, evaluationResult: $evaluationResult, evidenceImpact: $this->evidenceImpact($stats, $evaluationResult, $isStale), findingsVisibleCount: $findingsVisibleCount, highSeverityCount: $highSeverityCount, nextAction: $this->nextAction($stats, $stateFamily, $findingsVisibleCount, $evaluationResult), lastComparedLabel: $stats->lastComparedHuman, reasonCode: $stats->reasonCode, ); } private function positiveClaimAllowed( BaselineCompareStats $stats, OperatorExplanationPattern $explanation, ?BaselineCompareReasonCode $reasonCode, string $evaluationResult, ): bool { if ($stats->state !== 'ready') { return false; } if ((int) ($stats->findingsCount ?? 0) > 0) { return false; } if ($evaluationResult !== 'no_result') { return false; } if ($explanation->trustworthinessLevel !== TrustworthinessLevel::Trustworthy) { return false; } if (in_array($stats->coverageStatus, ['warning', 'unproven'], true)) { return false; } if ((int) ($stats->evidenceGapsCount ?? 0) > 0) { return false; } if ($this->hasStaleResult($stats, $evaluationResult)) { return false; } if ($stats->reasonCode === null) { return true; } return $reasonCode?->supportsPositiveClaim() ?? false; } private function stateFamily( BaselineCompareStats $stats, int $findingsVisibleCount, bool $positiveClaimAllowed, bool $isStale, ): string { return match (true) { $stats->state === 'comparing' => BaselineCompareSummaryAssessment::STATE_IN_PROGRESS, $stats->state === 'failed', $findingsVisibleCount > 0 => BaselineCompareSummaryAssessment::STATE_ACTION_REQUIRED, in_array($stats->state, ['no_tenant', 'no_assignment', 'no_snapshot', 'idle'], true) => BaselineCompareSummaryAssessment::STATE_UNAVAILABLE, $isStale => BaselineCompareSummaryAssessment::STATE_STALE, $positiveClaimAllowed => BaselineCompareSummaryAssessment::STATE_POSITIVE, default => BaselineCompareSummaryAssessment::STATE_CAUTION, }; } private function evidenceImpact(BaselineCompareStats $stats, string $evaluationResult, bool $isStale): string { if (in_array($stats->state, ['no_tenant', 'no_assignment', 'no_snapshot', 'idle', 'failed'], true)) { return BaselineCompareSummaryAssessment::EVIDENCE_UNAVAILABLE; } if ($isStale) { return BaselineCompareSummaryAssessment::EVIDENCE_STALE_RESULT; } if ($evaluationResult === 'suppressed_result') { return BaselineCompareSummaryAssessment::EVIDENCE_SUPPRESSED_OUTPUT; } if ((int) ($stats->evidenceGapsCount ?? 0) > 0) { return BaselineCompareSummaryAssessment::EVIDENCE_EVIDENCE_GAP; } if (in_array($stats->coverageStatus, ['warning', 'unproven'], true)) { return BaselineCompareSummaryAssessment::EVIDENCE_COVERAGE_WARNING; } return BaselineCompareSummaryAssessment::EVIDENCE_NONE; } private function headline( BaselineCompareStats $stats, string $stateFamily, int $findingsVisibleCount, int $highSeverityCount, string $evaluationResult, ): string { return match ($stateFamily) { BaselineCompareSummaryAssessment::STATE_POSITIVE => 'No confirmed drift in the latest baseline compare.', BaselineCompareSummaryAssessment::STATE_CAUTION => match (true) { $evaluationResult === 'suppressed_result' => 'The last compare finished, but normal result output was suppressed.', (int) ($stats->evidenceGapsCount ?? 0) > 0 => 'No confirmed drift is visible, but evidence gaps still limit this result.', in_array($stats->coverageStatus, ['warning', 'unproven'], true) => 'No confirmed drift is visible, but coverage limits this compare.', default => 'The latest compare result needs caution before you treat it as an all-clear.', }, BaselineCompareSummaryAssessment::STATE_STALE => 'The latest baseline compare result is stale.', BaselineCompareSummaryAssessment::STATE_ACTION_REQUIRED => match (true) { $stats->state === 'failed' || $evaluationResult === 'failed_result' => 'The latest baseline compare failed before it produced a usable result.', $highSeverityCount > 0 => sprintf('%d high-severity drift finding%s need review.', $highSeverityCount, $highSeverityCount === 1 ? '' : 's'), default => sprintf('%d open drift finding%s need review.', $findingsVisibleCount, $findingsVisibleCount === 1 ? '' : 's'), }, BaselineCompareSummaryAssessment::STATE_IN_PROGRESS => 'Baseline compare is in progress.', default => match ($stats->state) { 'no_assignment' => 'This tenant does not have an assigned baseline yet.', 'no_snapshot' => 'The current baseline snapshot is not available for compare.', 'idle' => 'A current baseline compare result is not available yet.', default => 'A usable baseline compare result is not currently available.', }, }; } private function supportingMessage( BaselineCompareStats $stats, string $stateFamily, int $findingsVisibleCount, string $evaluationResult, ): ?string { return match ($stateFamily) { BaselineCompareSummaryAssessment::STATE_POSITIVE => $stats->lastComparedHuman !== null ? 'Last compared '.$stats->lastComparedHuman.'.' : 'The latest compare result is trustworthy enough to treat zero findings as current.', BaselineCompareSummaryAssessment::STATE_CAUTION => match (true) { $evaluationResult === 'suppressed_result' => 'Review the run detail before treating zero visible findings as complete.', (int) ($stats->evidenceGapsCount ?? 0) > 0 => 'Review the compare detail to see which evidence gaps still limit trust.', in_array($stats->coverageStatus, ['warning', 'unproven'], true) => 'Coverage warnings mean zero visible findings are not an all-clear on their own.', default => $stats->reasonMessage ?? $stats->message, }, BaselineCompareSummaryAssessment::STATE_STALE => $stats->lastComparedHuman !== null ? 'Last compared '.$stats->lastComparedHuman.'. Refresh compare before relying on this posture.' : 'Refresh compare before relying on this posture.', BaselineCompareSummaryAssessment::STATE_ACTION_REQUIRED => match (true) { $stats->state === 'failed' => $stats->failureReason, $findingsVisibleCount > 0 => 'Open findings remain on this tenant and need review.', default => $stats->message, }, BaselineCompareSummaryAssessment::STATE_IN_PROGRESS => 'Current counts are diagnostic only until the compare run finishes.', default => $stats->message, }; } private function tone(BaselineCompareStats $stats, string $stateFamily): string { return match ($stateFamily) { BaselineCompareSummaryAssessment::STATE_POSITIVE => 'success', BaselineCompareSummaryAssessment::STATE_ACTION_REQUIRED => 'danger', BaselineCompareSummaryAssessment::STATE_IN_PROGRESS => 'info', BaselineCompareSummaryAssessment::STATE_UNAVAILABLE => $stats->state === 'no_snapshot' ? 'warning' : 'gray', default => 'warning', }; } /** * @return array{label: string, target: string} */ private function nextAction( BaselineCompareStats $stats, string $stateFamily, int $findingsVisibleCount, string $evaluationResult, ): array { if ($findingsVisibleCount > 0) { return [ 'label' => 'Open findings', 'target' => BaselineCompareSummaryAssessment::NEXT_TARGET_FINDINGS, ]; } return match ($stateFamily) { BaselineCompareSummaryAssessment::STATE_ACTION_REQUIRED => [ 'label' => $evaluationResult === 'failed_result' ? 'Review the failed run' : 'Review compare detail', 'target' => $stats->operationRunId !== null ? BaselineCompareSummaryAssessment::NEXT_TARGET_RUN : BaselineCompareSummaryAssessment::NEXT_TARGET_LANDING, ], BaselineCompareSummaryAssessment::STATE_CAUTION => [ 'label' => 'Review compare detail', 'target' => $stats->operationRunId !== null ? BaselineCompareSummaryAssessment::NEXT_TARGET_RUN : BaselineCompareSummaryAssessment::NEXT_TARGET_LANDING, ], BaselineCompareSummaryAssessment::STATE_STALE => [ 'label' => 'Open Baseline Compare', 'target' => BaselineCompareSummaryAssessment::NEXT_TARGET_LANDING, ], BaselineCompareSummaryAssessment::STATE_IN_PROGRESS => [ 'label' => $stats->operationRunId !== null ? 'View run' : 'Open Baseline Compare', 'target' => $stats->operationRunId !== null ? BaselineCompareSummaryAssessment::NEXT_TARGET_RUN : BaselineCompareSummaryAssessment::NEXT_TARGET_LANDING, ], BaselineCompareSummaryAssessment::STATE_UNAVAILABLE => match ($stats->state) { 'no_assignment' => [ 'label' => 'Assign a baseline first', 'target' => BaselineCompareSummaryAssessment::NEXT_TARGET_NONE, ], 'no_snapshot' => [ 'label' => 'Review baseline prerequisites', 'target' => BaselineCompareSummaryAssessment::NEXT_TARGET_LANDING, ], 'idle' => [ 'label' => 'Open Baseline Compare', 'target' => BaselineCompareSummaryAssessment::NEXT_TARGET_LANDING, ], default => [ 'label' => 'Review compare availability', 'target' => BaselineCompareSummaryAssessment::NEXT_TARGET_NONE, ], }, default => [ 'label' => 'No action needed', 'target' => BaselineCompareSummaryAssessment::NEXT_TARGET_NONE, ], }; } private function hasStaleResult(BaselineCompareStats $stats, string $evaluationResult): bool { if ($stats->state !== 'ready') { return false; } if ($stats->lastComparedIso === null) { return false; } if (! in_array($evaluationResult, ['full_result', 'no_result', 'incomplete_result', 'suppressed_result'], true)) { return false; } try { $lastComparedAt = CarbonImmutable::parse($stats->lastComparedIso); } catch (\Throwable) { return false; } return $lastComparedAt->lt(now()->subDays(self::STALE_AFTER_DAYS)); } }