82 lines
3.8 KiB
C#
82 lines
3.8 KiB
C#
using System.Text.Json.Serialization;
|
|
|
|
namespace StellaOps.Policy.Engine.Domain;
|
|
|
|
/// <summary>
|
|
/// Request for a policy decision with source evidence summaries (POLICY-ENGINE-40-003).
|
|
/// </summary>
|
|
public sealed record PolicyDecisionRequest(
|
|
[property: JsonPropertyName("snapshot_id")] string SnapshotId,
|
|
[property: JsonPropertyName("tenant_id")] string? TenantId = null,
|
|
[property: JsonPropertyName("component_purl")] string? ComponentPurl = null,
|
|
[property: JsonPropertyName("advisory_id")] string? AdvisoryId = null,
|
|
[property: JsonPropertyName("include_evidence")] bool IncludeEvidence = true,
|
|
[property: JsonPropertyName("max_sources")] int MaxSources = 5);
|
|
|
|
/// <summary>
|
|
/// Response containing policy decisions with source evidence summaries.
|
|
/// </summary>
|
|
public sealed record PolicyDecisionResponse(
|
|
[property: JsonPropertyName("snapshot_id")] string SnapshotId,
|
|
[property: JsonPropertyName("decisions")] IReadOnlyList<PolicyDecisionItem> Decisions,
|
|
[property: JsonPropertyName("summary")] PolicyDecisionSummary Summary);
|
|
|
|
/// <summary>
|
|
/// A single policy decision with associated evidence.
|
|
/// </summary>
|
|
public sealed record PolicyDecisionItem(
|
|
[property: JsonPropertyName("tenant_id")] string TenantId,
|
|
[property: JsonPropertyName("component_purl")] string ComponentPurl,
|
|
[property: JsonPropertyName("advisory_id")] string AdvisoryId,
|
|
[property: JsonPropertyName("severity_fused")] string SeverityFused,
|
|
[property: JsonPropertyName("score")] decimal Score,
|
|
[property: JsonPropertyName("status")] string Status,
|
|
[property: JsonPropertyName("top_sources")] IReadOnlyList<PolicyDecisionSource> TopSources,
|
|
[property: JsonPropertyName("evidence")] PolicyDecisionEvidence? Evidence,
|
|
[property: JsonPropertyName("conflict_count")] int ConflictCount,
|
|
[property: JsonPropertyName("reason_codes")] IReadOnlyList<string> ReasonCodes);
|
|
|
|
/// <summary>
|
|
/// Top severity source information for a decision.
|
|
/// </summary>
|
|
public sealed record PolicyDecisionSource(
|
|
[property: JsonPropertyName("source")] string Source,
|
|
[property: JsonPropertyName("weight")] decimal Weight,
|
|
[property: JsonPropertyName("severity")] string Severity,
|
|
[property: JsonPropertyName("score")] decimal Score,
|
|
[property: JsonPropertyName("rank")] int Rank);
|
|
|
|
/// <summary>
|
|
/// Evidence summary for a policy decision.
|
|
/// </summary>
|
|
public sealed record PolicyDecisionEvidence(
|
|
[property: JsonPropertyName("headline")] string Headline,
|
|
[property: JsonPropertyName("severity")] string Severity,
|
|
[property: JsonPropertyName("locator")] PolicyDecisionLocator Locator,
|
|
[property: JsonPropertyName("signals")] IReadOnlyList<string> Signals);
|
|
|
|
/// <summary>
|
|
/// Evidence locator information.
|
|
/// </summary>
|
|
public sealed record PolicyDecisionLocator(
|
|
[property: JsonPropertyName("file_path")] string FilePath,
|
|
[property: JsonPropertyName("digest")] string? Digest);
|
|
|
|
/// <summary>
|
|
/// Summary statistics for the decision response.
|
|
/// </summary>
|
|
public sealed record PolicyDecisionSummary(
|
|
[property: JsonPropertyName("total_decisions")] int TotalDecisions,
|
|
[property: JsonPropertyName("total_conflicts")] int TotalConflicts,
|
|
[property: JsonPropertyName("severity_counts")] IReadOnlyDictionary<string, int> SeverityCounts,
|
|
[property: JsonPropertyName("top_severity_sources")] IReadOnlyList<PolicyDecisionSourceRank> TopSeveritySources);
|
|
|
|
/// <summary>
|
|
/// Aggregated source rank across all decisions.
|
|
/// </summary>
|
|
public sealed record PolicyDecisionSourceRank(
|
|
[property: JsonPropertyName("source")] string Source,
|
|
[property: JsonPropertyName("total_weight")] decimal TotalWeight,
|
|
[property: JsonPropertyName("decision_count")] int DecisionCount,
|
|
[property: JsonPropertyName("average_score")] decimal AverageScore);
|