feat: Implement IsolatedReplayContext for deterministic audit replay

- Added IsolatedReplayContext class to provide an isolated environment for replaying audit bundles without external calls.
- Introduced methods for initializing the context, verifying input digests, and extracting inputs for policy evaluation.
- Created supporting interfaces and options for context configuration.

feat: Create ReplayExecutor for executing policy re-evaluation and verdict comparison

- Developed ReplayExecutor class to handle the execution of replay processes, including input verification and verdict comparison.
- Implemented detailed drift detection and error handling during replay execution.
- Added interfaces for policy evaluation and replay execution options.

feat: Add ScanSnapshotFetcher for fetching scan data and snapshots

- Introduced ScanSnapshotFetcher class to retrieve necessary scan data and snapshots for audit bundle creation.
- Implemented methods to fetch scan metadata, advisory feeds, policy snapshots, and VEX statements.
- Created supporting interfaces for scan data, feed snapshots, and policy snapshots.
This commit is contained in:
StellaOps Bot
2025-12-23 07:46:34 +02:00
parent e47627cfff
commit 7e384ab610
77 changed files with 153346 additions and 209 deletions

View File

@@ -11,6 +11,7 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using StellaOps.Cli.Extensions;
using StellaOps.Policy.Unknowns.Models;
namespace StellaOps.Cli.Commands;
@@ -66,23 +67,23 @@ public static class UnknownsCommandGroup
Option<bool> verboseOption,
CancellationToken cancellationToken)
{
var scanIdOption = new Option<string?>("--scan-id", "-s")
var scanIdOption = new Option<string?>("--scan-id", new[] { "-s" })
{
Description = "Scan ID to check budget against"
};
var verdictPathOption = new Option<string?>("--verdict", "-v")
var verdictPathOption = new Option<string?>("--verdict", new[] { "-v" })
{
Description = "Path to verdict JSON file"
};
var environmentOption = new Option<string>("--environment", "-e")
var environmentOption = new Option<string>("--environment", new[] { "-e" })
{
Description = "Environment budget to use (prod, stage, dev)"
};
environmentOption.SetDefaultValue("prod");
var configOption = new Option<string?>("--config", "-c")
var configOption = new Option<string?>("--config", new[] { "-c" })
{
Description = "Path to budget configuration file"
};
@@ -93,7 +94,7 @@ public static class UnknownsCommandGroup
};
failOnExceedOption.SetDefaultValue(true);
var outputOption = new Option<string>("--output", "-o")
var outputOption = new Option<string>("--output", new[] { "-o" })
{
Description = "Output format: text, json, sarif"
};
@@ -138,13 +139,13 @@ public static class UnknownsCommandGroup
Option<bool> verboseOption,
CancellationToken cancellationToken)
{
var environmentOption = new Option<string>("--environment", "-e")
var environmentOption = new Option<string>("--environment", new[] { "-e" })
{
Description = "Environment to show budget status for"
};
environmentOption.SetDefaultValue("prod");
var outputOption = new Option<string>("--output", "-o")
var outputOption = new Option<string>("--output", new[] { "-o" })
{
Description = "Output format: text, json"
};
@@ -177,12 +178,12 @@ public static class UnknownsCommandGroup
Option<bool> verboseOption,
CancellationToken cancellationToken)
{
var bandOption = new Option<string?>("--band", "-b")
var bandOption = new Option<string?>("--band", new[] { "-b" })
{
Description = "Filter by band: HOT, WARM, COLD"
};
var limitOption = new Option<int>("--limit", "-l")
var limitOption = new Option<int>("--limit", new[] { "-l" })
{
Description = "Maximum number of results to return"
};
@@ -192,12 +193,12 @@ public static class UnknownsCommandGroup
Description = "Number of results to skip"
};
var formatOption = new Option<string>("--format", "-f")
var formatOption = new Option<string>("--format", new[] { "-f" })
{
Description = "Output format: table, json"
};
var sortOption = new Option<string>("--sort", "-s")
var sortOption = new Option<string>("--sort", new[] { "-s" })
{
Description = "Sort by: age, band, cve, package"
};
@@ -240,13 +241,13 @@ public static class UnknownsCommandGroup
Option<bool> verboseOption,
CancellationToken cancellationToken)
{
var idOption = new Option<string>("--id", "-i")
var idOption = new Option<string>("--id", new[] { "-i" })
{
Description = "Unknown ID to escalate",
Required = true
};
var reasonOption = new Option<string?>("--reason", "-r")
var reasonOption = new Option<string?>("--reason", new[] { "-r" })
{
Description = "Reason for escalation"
};
@@ -278,19 +279,19 @@ public static class UnknownsCommandGroup
Option<bool> verboseOption,
CancellationToken cancellationToken)
{
var idOption = new Option<string>("--id", "-i")
var idOption = new Option<string>("--id", new[] { "-i" })
{
Description = "Unknown ID to resolve",
Required = true
};
var resolutionOption = new Option<string>("--resolution", "-r")
var resolutionOption = new Option<string>("--resolution", new[] { "-r" })
{
Description = "Resolution type: matched, not_applicable, deferred",
Required = true
};
var noteOption = new Option<string?>("--note", "-n")
var noteOption = new Option<string?>("--note", new[] { "-n" })
{
Description = "Resolution note"
};