// ----------------------------------------------------------------------------- // DriftExitCodes.cs // Sprint: SPRINT_3600_0005_0001_policy_ci_gate_integration // Description: Exit codes for stella scan drift command for CI/CD integration. // ----------------------------------------------------------------------------- namespace StellaOps.Cli.Commands; /// /// Exit codes for the drift detection command. /// Designed for CI/CD pipeline integration. /// public static class DriftExitCodes { // Success codes (0-9) /// /// No material reachability changes detected. /// public const int Success = 0; /// /// New paths detected but not to affected sinks (informational drift). /// public const int SuccessWithInfoDrift = 1; /// /// Hardening detected - previously reachable paths now unreachable. /// public const int SuccessHardening = 2; /// /// Previously mitigated paths now reachable again (regression). /// public const int HardeningRegression = 2; /// /// Known Exploited Vulnerability now reachable. /// public const int KevReachable = 3; /// /// Affected vulnerability now reachable. /// public const int AffectedReachable = 4; /// /// Policy gate blocked the drift. /// public const int PolicyBlocked = 5; // Error codes (10-19) /// /// Input error - invalid scan ID, missing parameters. /// public const int InputError = 10; /// /// Analysis error - call graph extraction failed. /// public const int AnalysisError = 11; /// /// Storage error - database/cache unavailable. /// public const int StorageError = 12; /// /// Policy error - gate evaluation failed. /// public const int PolicyError = 13; /// /// Network error - unable to reach required services. /// public const int NetworkError = 14; /// /// Unknown error. /// public const int UnknownError = 99; /// /// Gets the exit code name for display purposes. /// public static string GetName(int exitCode) => exitCode switch { Success => "SUCCESS", SuccessWithInfoDrift => "SUCCESS_INFO_DRIFT", SuccessHardening => "SUCCESS_HARDENING", KevReachable => "KEV_REACHABLE", AffectedReachable => "AFFECTED_REACHABLE", PolicyBlocked => "POLICY_BLOCKED", InputError => "INPUT_ERROR", AnalysisError => "ANALYSIS_ERROR", StorageError => "STORAGE_ERROR", PolicyError => "POLICY_ERROR", NetworkError => "NETWORK_ERROR", _ => "UNKNOWN_ERROR" }; /// /// Gets a description for the exit code. /// public static string GetDescription(int exitCode) => exitCode switch { Success => "No material reachability changes detected", SuccessWithInfoDrift => "New paths detected but not to affected sinks", SuccessHardening => "Hardening detected - previously reachable paths now unreachable", KevReachable => "Known Exploited Vulnerability now reachable", AffectedReachable => "Affected vulnerability now reachable", PolicyBlocked => "Policy gate blocked the drift", InputError => "Input error - invalid scan ID or missing parameters", AnalysisError => "Analysis error - call graph extraction failed", StorageError => "Storage error - database or cache unavailable", PolicyError => "Policy error - gate evaluation failed", NetworkError => "Network error - unable to reach required services", _ => "Unknown error occurred" }; /// /// Determines if the exit code represents a success condition. /// public static bool IsSuccess(int exitCode) => exitCode >= 0 && exitCode < 10; /// /// Determines if the exit code represents an error condition. /// public static bool IsError(int exitCode) => exitCode >= 10; /// /// Determines if the exit code represents a blocking condition. /// public static bool IsBlocking(int exitCode) => exitCode is KevReachable or AffectedReachable or PolicyBlocked; } /// /// Result of drift analysis for CLI output. /// public sealed record DriftCommandResult { /// /// Exit code for the command. /// public required int ExitCode { get; init; } /// /// Human-readable message. /// public required string Message { get; init; } /// /// Number of newly reachable paths. /// public int DeltaReachable { get; init; } /// /// Number of newly unreachable paths. /// public int DeltaUnreachable { get; init; } /// /// Whether a KEV is now reachable. /// public bool HasKevReachable { get; init; } /// /// Policy gate that blocked (if any). /// public string? BlockedBy { get; init; } /// /// Suggestion for resolving the block. /// public string? Suggestion { get; init; } /// /// SARIF output path (if generated). /// public string? SarifOutputPath { get; init; } }