use crank_core::{ AgentId, CorrelationContext, ExecutionErrorCode, ExecutionFailure, ExecutionOrigin, ExecutionStage, OutcomeCertainty, Retryability, }; #[test] fn frozen_execution_taxonomy_is_closed_and_consistent() { let cases = [ ( ExecutionErrorCode::AuthorizationDenied, ExecutionStage::Authorization, Retryability::Never, OutcomeCertainty::Certain, ), ( ExecutionErrorCode::InputSchemaInvalid, ExecutionStage::InputSchema, Retryability::Never, OutcomeCertainty::Certain, ), ( ExecutionErrorCode::ExecutionOverloaded, ExecutionStage::Admission, Retryability::AfterDelay, OutcomeCertainty::Certain, ), ( ExecutionErrorCode::ConfirmationRequired, ExecutionStage::Admission, Retryability::RequiresConfirmation, OutcomeCertainty::Certain, ), ( ExecutionErrorCode::IdempotencyOutcomeUnknown, ExecutionStage::Admission, Retryability::ManualReconcile, OutcomeCertainty::OutcomeUnknown, ), ( ExecutionErrorCode::RuntimeInternal, ExecutionStage::Runtime, Retryability::Never, OutcomeCertainty::Certain, ), ]; for (code, stage, retryability, certainty) in cases { let descriptor = ExecutionFailure::new(code, CorrelationContext::generate()); assert_eq!(descriptor.stage(), stage); assert_eq!(descriptor.retryability(), retryability); assert_eq!(descriptor.outcome_certainty(), certainty); assert_eq!(descriptor.error_code(), code); } } #[test] fn execution_origin_enforces_agent_scope() { let agent_id = AgentId::new("agent_01"); assert!(ExecutionOrigin::AdminDraft.validate_agent(None).is_ok()); assert!( ExecutionOrigin::AdminDraft .validate_agent(Some(&agent_id)) .is_err() ); assert!( ExecutionOrigin::AgentSnapshot .validate_agent(Some(&agent_id)) .is_ok() ); assert!(ExecutionOrigin::AgentSnapshot.validate_agent(None).is_err()); } #[test] fn dispatch_uncertainty_is_allowed_only_for_ambiguous_codes() { let correlation = CorrelationContext::generate(); let timeout = ExecutionFailure::new(ExecutionErrorCode::UpstreamTimeout, correlation.clone()) .with_dispatch_uncertainty(); assert_eq!(timeout.retryability(), Retryability::ManualReconcile); assert_eq!( timeout.outcome_certainty(), OutcomeCertainty::OutcomeUnknown ); let validation = ExecutionFailure::new(ExecutionErrorCode::InputSchemaInvalid, correlation) .with_dispatch_uncertainty(); assert_eq!(validation.retryability(), Retryability::Never); assert_eq!(validation.outcome_certainty(), OutcomeCertainty::Certain); } #[test] fn failure_metadata_is_code_specific_and_bounded() { let correlation = CorrelationContext::generate(); assert!( ExecutionFailure::new(ExecutionErrorCode::InputSchemaInvalid, correlation.clone()) .try_with_retry_after_ms(1) .is_err() ); assert!( ExecutionFailure::new(ExecutionErrorCode::UpstreamRateLimited, correlation.clone()) .try_with_retry_after_ms(3_600_001) .is_err() ); assert!( ExecutionFailure::new(ExecutionErrorCode::RuntimeInternal, correlation.clone()) .try_with_confirmation("token", 1) .is_err() ); assert!( ExecutionFailure::new( ExecutionErrorCode::ConfirmationRequired, correlation.clone() ) .try_with_confirmation("x".repeat(4_097), 1) .is_err() ); let challenge = ExecutionFailure::new(ExecutionErrorCode::ConfirmationRequired, correlation) .try_with_confirmation("secret-canary", 1_000) .expect("bounded confirmation"); assert!(!format!("{challenge:?}").contains("secret-canary")); } #[test] fn unknown_taxonomy_values_are_rejected_by_serde() { assert!(serde_json::from_str::("\"unknown\"").is_err()); assert!(serde_json::from_str::("\"unknown\"").is_err()); assert!(serde_json::from_str::("\"automatic\"").is_err()); } #[test] fn every_published_code_has_stable_wire_value_stage_and_localized_messages() { let mut wire_values = std::collections::BTreeSet::new(); for code in ExecutionErrorCode::ALL { assert!(wire_values.insert(code.as_str())); assert_eq!(serde_json::to_value(code).unwrap(), code.as_str()); assert!(!code.message(crank_core::ExecutionLocale::Ru).is_empty()); assert!(!code.message(crank_core::ExecutionLocale::En).is_empty()); assert!(!code.stage().as_str().is_empty()); assert!(!code.retryability().as_str().is_empty()); assert!(!code.outcome_certainty().as_str().is_empty()); } assert_eq!(wire_values.len(), ExecutionErrorCode::ALL.len()); }