up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-26 07:47:08 +02:00
parent 56e2f64d07
commit 1c782897f7
184 changed files with 8991 additions and 649 deletions

View File

@@ -0,0 +1,48 @@
using System.Collections.Immutable;
namespace StellaOps.Policy;
/// <summary>
/// Structured explanation describing how a policy decision was reached.
/// </summary>
/// <param name="FindingId">Identifier of the evaluated finding.</param>
/// <param name="Decision">Final verdict status (e.g., Allow, Block, Warned).</param>
/// <param name="RuleName">Name of the rule that matched, if any.</param>
/// <param name="Reason">Human-readable summary.</param>
/// <param name="Nodes">Tree of evaluated nodes (rule, match, action, penalties, quieting, unknown confidence).</param>
public sealed record PolicyExplanation(
string FindingId,
PolicyVerdictStatus Decision,
string? RuleName,
string Reason,
ImmutableArray<PolicyExplanationNode> Nodes)
{
public static PolicyExplanation Allow(string findingId, string? ruleName, string reason, params PolicyExplanationNode[] nodes) =>
new(findingId, PolicyVerdictStatus.Allowed, ruleName, reason, nodes.ToImmutableArray());
public static PolicyExplanation Block(string findingId, string? ruleName, string reason, params PolicyExplanationNode[] nodes) =>
new(findingId, PolicyVerdictStatus.Blocked, ruleName, reason, nodes.ToImmutableArray());
public static PolicyExplanation Warn(string findingId, string? ruleName, string reason, params PolicyExplanationNode[] nodes) =>
new(findingId, PolicyVerdictStatus.Warned, ruleName, reason, nodes.ToImmutableArray());
}
/// <summary>
/// A single explanation node with optional children to capture evaluation breadcrumbs.
/// </summary>
/// <param name="Kind">Short classifier (e.g., "rule", "match", "penalty", "quiet", "unknown").</param>
/// <param name="Label">Human-readable label.</param>
/// <param name="Detail">Optional detail (numeric or string rendered as text).</param>
/// <param name="Children">Nested explanation nodes.</param>
public sealed record PolicyExplanationNode(
string Kind,
string Label,
string? Detail,
ImmutableArray<PolicyExplanationNode> Children)
{
public static PolicyExplanationNode Leaf(string kind, string label, string? detail = null) =>
new(kind, label, detail, ImmutableArray<PolicyExplanationNode>.Empty);
public static PolicyExplanationNode Branch(string kind, string label, string? detail = null, params PolicyExplanationNode[] children) =>
new(kind, label, detail, children.ToImmutableArray());
}