'Blocked', RestoreSafetyAssessment::STATE_RISKY => 'Risky', RestoreSafetyAssessment::STATE_READY_WITH_CAUTION => 'Ready with caution', RestoreSafetyAssessment::STATE_READY => 'Ready', default => self::headline($state, 'Unknown state'), }; } public static function primaryNextAction(?string $action): string { return match ($action) { 'resolve_blockers' => 'Resolve the technical blockers before real execution.', 'generate_preview' => 'Generate a preview for the current scope.', 'regenerate_preview' => 'Regenerate the preview for the current scope.', 'rerun_checks' => 'Run the safety checks again for the current scope.', 'review_warnings' => 'Review the warnings before real execution.', 'execute' => 'Queue the real restore execution.', 'review_preview' => 'Review the preview evidence before claiming recovery or queueing execution.', 'review_failures' => 'Review failed items and provider errors before retrying.', 'review_partial_items' => 'Review partial items and incomplete assignments before retrying.', 'review_skipped_items' => 'Review skipped or non-applied items before closing the run.', 'review_result' => 'Review the completed restore details.', 'adjust_scope' => 'Adjust the restore scope, then refresh preview and checks.', 'review_scope' => 'Review the current scope and safety evidence.', default => self::sentence($action, 'Review the current scope and safety evidence.'), }; } public static function primaryCauseFamily(?string $family): string { return match ($family) { 'none' => 'No dominant cause recorded', 'execution_failure' => 'Execution failure', 'write_gate_or_rbac' => 'RBAC or write gate', 'provider_operability' => 'Provider operability', 'missing_dependency_or_mapping' => 'Missing dependency or mapping', 'payload_quality' => 'Payload quality', 'scope_mismatch' => 'Scope mismatch', 'item_level_failure' => 'Item-level failure', default => self::headline($family, 'Unknown cause'), }; } public static function recoveryBoundary(?string $boundary): string { return match ($boundary) { 'preview_only_no_execution_proven' => 'No execution was performed from this record.', 'execution_failed_no_recovery_claim' => 'Tenant recovery is not proven.', 'run_completed_not_recovery_proven' => 'Tenant-wide recovery is not proven.', default => 'Tenant-wide recovery is not proven.', }; } private static function headline(?string $value, string $fallback): string { if (! is_string($value) || trim($value) === '') { return $fallback; } return Str::headline(trim($value)); } private static function sentence(?string $value, string $fallback): string { if (! is_string($value) || trim($value) === '') { return $fallback; } $sentence = Str::headline(trim($value)); return str_ends_with($sentence, '.') ? $sentence : $sentence.'.'; } }