// -----------------------------------------------------------------------------
// 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; }
}