audit, advisories and doctors/setup work

This commit is contained in:
master
2026-01-13 18:53:39 +02:00
parent 9ca7cb183e
commit d7be6ba34b
811 changed files with 54242 additions and 4056 deletions

View File

@@ -0,0 +1,100 @@
// <copyright file="NullRemediationPlanner.cs" company="StellaOps">
// Copyright (c) StellaOps. Licensed under the AGPL-3.0-or-later.
// </copyright>
using System.Collections.Concurrent;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
namespace StellaOps.AdvisoryAI.Remediation;
/// <summary>
/// Deterministic stub planner used when remediation services are not configured.
/// </summary>
public sealed class NullRemediationPlanner : IRemediationPlanner
{
private readonly ConcurrentDictionary<string, RemediationPlan> _plans = new(StringComparer.Ordinal);
private readonly TimeProvider _timeProvider;
public NullRemediationPlanner(TimeProvider timeProvider)
{
_timeProvider = timeProvider ?? throw new ArgumentNullException(nameof(timeProvider));
}
public Task<RemediationPlan> GeneratePlanAsync(
RemediationPlanRequest request,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
var inputHash = ComputeHash(JsonSerializer.Serialize(request));
var planId = $"plan:stub:{inputHash[..12]}";
var plan = new RemediationPlan
{
PlanId = planId,
Request = request,
Steps =
[
new RemediationStep
{
Order = 1,
ActionType = "review_remediation",
FilePath = "N/A",
Description = "Remediation planner is not configured.",
Risk = RemediationRisk.Unknown
}
],
ExpectedDelta = new ExpectedSbomDelta
{
Added = Array.Empty<string>(),
Removed = Array.Empty<string>(),
Upgraded = new Dictionary<string, string>(),
NetVulnerabilityChange = 0
},
RiskAssessment = RemediationRisk.Unknown,
TestRequirements = new RemediationTestRequirements
{
TestSuites = Array.Empty<string>(),
MinCoverage = 0,
RequireAllPass = false,
Timeout = TimeSpan.Zero
},
Authority = RemediationAuthority.Suggestion,
PrReady = false,
NotReadyReason = "Remediation planner is not configured.",
ConfidenceScore = 0.0,
ModelId = "stub-remediation:v0",
GeneratedAt = _timeProvider.GetUtcNow().ToString("O", CultureInfo.InvariantCulture),
InputHashes = new[] { inputHash },
EvidenceRefs = new[] { request.ComponentPurl, request.VulnerabilityId }
};
_plans[planId] = plan;
return Task.FromResult(plan);
}
public Task<bool> ValidatePlanAsync(
string planId,
CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(planId);
return Task.FromResult(_plans.ContainsKey(planId));
}
public Task<RemediationPlan?> GetPlanAsync(
string planId,
CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(planId);
_plans.TryGetValue(planId, out var plan);
return Task.FromResult(plan);
}
private static string ComputeHash(string content)
{
var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(content));
return Convert.ToHexStringLower(bytes);
}
}