Files
git.stella-ops.org/src/Scanner/__Libraries/StellaOps.Scanner.Gate/VexGateResult.cs
2026-01-07 09:43:12 +02:00

145 lines
4.4 KiB
C#

// -----------------------------------------------------------------------------
// VexGateResult.cs
// Sprint: SPRINT_20260106_003_002_SCANNER_vex_gate_service
// Description: VEX gate evaluation result with evidence.
// -----------------------------------------------------------------------------
using System.Collections.Immutable;
using System.Text.Json.Serialization;
namespace StellaOps.Scanner.Gate;
/// <summary>
/// Result of VEX gate evaluation for a single finding.
/// Contains the decision, rationale, and supporting evidence.
/// </summary>
public sealed record VexGateResult
{
/// <summary>
/// Gate decision: Pass, Warn, or Block.
/// </summary>
[JsonPropertyName("decision")]
public required VexGateDecision Decision { get; init; }
/// <summary>
/// Human-readable explanation of why this decision was made.
/// </summary>
[JsonPropertyName("rationale")]
public required string Rationale { get; init; }
/// <summary>
/// ID of the policy rule that matched and produced this decision.
/// </summary>
[JsonPropertyName("policyRuleMatched")]
public required string PolicyRuleMatched { get; init; }
/// <summary>
/// VEX statements that contributed to this decision.
/// </summary>
[JsonPropertyName("contributingStatements")]
public required ImmutableArray<VexStatementRef> ContributingStatements { get; init; }
/// <summary>
/// Detailed evidence supporting the decision.
/// </summary>
[JsonPropertyName("evidence")]
public required VexGateEvidence Evidence { get; init; }
/// <summary>
/// When this evaluation was performed (UTC ISO-8601).
/// </summary>
[JsonPropertyName("evaluatedAt")]
public required DateTimeOffset EvaluatedAt { get; init; }
}
/// <summary>
/// Evidence collected during VEX gate evaluation.
/// </summary>
public sealed record VexGateEvidence
{
/// <summary>
/// VEX status from vendor or authoritative source.
/// Null if no VEX statement found.
/// </summary>
[JsonPropertyName("vendorStatus")]
public VexStatus? VendorStatus { get; init; }
/// <summary>
/// Justification type from VEX statement.
/// </summary>
[JsonPropertyName("justification")]
public VexJustification? Justification { get; init; }
/// <summary>
/// Whether the vulnerable code is reachable from entrypoints.
/// </summary>
[JsonPropertyName("isReachable")]
public bool IsReachable { get; init; }
/// <summary>
/// Whether compensating controls mitigate the vulnerability.
/// </summary>
[JsonPropertyName("hasCompensatingControl")]
public bool HasCompensatingControl { get; init; }
/// <summary>
/// Confidence score in the gate decision (0.0 to 1.0).
/// </summary>
[JsonPropertyName("confidenceScore")]
public double ConfidenceScore { get; init; }
/// <summary>
/// Hints about backport fixes detected.
/// </summary>
[JsonPropertyName("backportHints")]
public ImmutableArray<string> BackportHints { get; init; } = ImmutableArray<string>.Empty;
/// <summary>
/// Whether the vulnerability is exploitable based on available intelligence.
/// </summary>
[JsonPropertyName("isExploitable")]
public bool IsExploitable { get; init; }
/// <summary>
/// Severity level from the advisory.
/// </summary>
[JsonPropertyName("severityLevel")]
public string? SeverityLevel { get; init; }
}
/// <summary>
/// Reference to a VEX statement that contributed to a gate decision.
/// </summary>
public sealed record VexStatementRef
{
/// <summary>
/// Unique identifier for the VEX statement.
/// </summary>
[JsonPropertyName("statementId")]
public required string StatementId { get; init; }
/// <summary>
/// Issuer of the VEX statement.
/// </summary>
[JsonPropertyName("issuerId")]
public required string IssuerId { get; init; }
/// <summary>
/// VEX status declared in the statement.
/// </summary>
[JsonPropertyName("status")]
public required VexStatus Status { get; init; }
/// <summary>
/// When the statement was issued.
/// </summary>
[JsonPropertyName("timestamp")]
public required DateTimeOffset Timestamp { get; init; }
/// <summary>
/// Trust weight of this statement in consensus (0.0 to 1.0).
/// </summary>
[JsonPropertyName("trustWeight")]
public double TrustWeight { get; init; }
}