use admin_api::error::execution_test_failure_localized; use crank_community_mcp::tool_error::tool_error_contract_from_failure; use crank_core::{ CorrelationContext, ExecutionErrorCode, ExecutionFailure, ExecutionLocale, Retryability, }; #[test] fn admin_and_mcp_project_every_execution_failure_with_identical_semantics() { for locale in [ExecutionLocale::En, ExecutionLocale::Ru] { for code in ExecutionErrorCode::ALL { let failure = ExecutionFailure::new(code, CorrelationContext::generate()); let admin = execution_test_failure_localized(&failure, locale); let mcp = tool_error_contract_from_failure(&failure, locale); assert_eq!(admin["code"], mcp.error_code); assert_eq!(admin["stage"], mcp.stage); assert_eq!(admin["retryability"], mcp.retryability); assert_eq!(admin["outcome_certainty"], mcp.outcome_certainty); assert_eq!(admin["message"], mcp.message); assert_eq!( mcp.recoverable, matches!( code.retryability(), Retryability::Safe | Retryability::AfterDelay | Retryability::RequiresConfirmation ) ); } } } #[test] fn admin_and_mcp_preserve_dispatch_uncertainty_without_changing_the_code() { for locale in [ExecutionLocale::En, ExecutionLocale::Ru] { let failure = ExecutionFailure::new( ExecutionErrorCode::UpstreamTransportError, CorrelationContext::generate(), ) .with_dispatch_uncertainty(); let admin = execution_test_failure_localized(&failure, locale); let mcp = tool_error_contract_from_failure(&failure, locale); assert_eq!(admin["retryability"], "manual_reconcile"); assert_eq!(admin["outcome_certainty"], "outcome_unknown"); assert_eq!(admin["retryability"], mcp.retryability); assert_eq!(admin["outcome_certainty"], mcp.outcome_certainty); assert!(!mcp.recoverable); } }