- Implement `SbomVexOrderingDeterminismProperties` for testing component list and vulnerability metadata hash consistency. - Create `UnicodeNormalizationDeterminismProperties` to validate NFC normalization and Unicode string handling. - Add project file for `StellaOps.Testing.Determinism.Properties` with necessary dependencies. - Introduce CI/CD template validation tests including YAML syntax checks and documentation content verification. - Create validation script for CI/CD templates ensuring all required files and structures are present.
230 lines
8.2 KiB
C#
230 lines
8.2 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
using StellaOps.AdvisoryAI.Remediation;
|
|
|
|
namespace StellaOps.AdvisoryAI.WebService.Contracts;
|
|
|
|
/// <summary>
|
|
/// API request for generating a remediation plan.
|
|
/// Sprint: SPRINT_20251226_016_AI_remedy_autopilot
|
|
/// Task: REMEDY-19
|
|
/// </summary>
|
|
public sealed record RemediationPlanApiRequest
|
|
{
|
|
[Required]
|
|
public required string FindingId { get; init; }
|
|
|
|
[Required]
|
|
public required string ArtifactDigest { get; init; }
|
|
|
|
[Required]
|
|
public required string VulnerabilityId { get; init; }
|
|
|
|
[Required]
|
|
public required string ComponentPurl { get; init; }
|
|
|
|
public string RemediationType { get; init; } = "auto";
|
|
|
|
public string? RepositoryUrl { get; init; }
|
|
|
|
public string TargetBranch { get; init; } = "main";
|
|
|
|
public bool AutoCreatePr { get; init; }
|
|
|
|
public string? CorrelationId { get; init; }
|
|
|
|
public RemediationPlanRequest ToDomain()
|
|
{
|
|
if (!Enum.TryParse<RemediationType>(RemediationType, ignoreCase: true, out var type))
|
|
{
|
|
type = Remediation.RemediationType.Auto;
|
|
}
|
|
|
|
return new RemediationPlanRequest
|
|
{
|
|
FindingId = FindingId,
|
|
ArtifactDigest = ArtifactDigest,
|
|
VulnerabilityId = VulnerabilityId,
|
|
ComponentPurl = ComponentPurl,
|
|
RemediationType = type,
|
|
RepositoryUrl = RepositoryUrl,
|
|
TargetBranch = TargetBranch,
|
|
AutoCreatePr = AutoCreatePr,
|
|
CorrelationId = CorrelationId
|
|
};
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// API response for remediation plan.
|
|
/// </summary>
|
|
public sealed record RemediationPlanApiResponse
|
|
{
|
|
public required string PlanId { get; init; }
|
|
public required IReadOnlyList<RemediationStepResponse> Steps { get; init; }
|
|
public required ExpectedDeltaResponse ExpectedDelta { get; init; }
|
|
public required string RiskAssessment { get; init; }
|
|
public required string Authority { get; init; }
|
|
public required bool PrReady { get; init; }
|
|
public string? NotReadyReason { get; init; }
|
|
public required double ConfidenceScore { get; init; }
|
|
public required string ModelId { get; init; }
|
|
public required string GeneratedAt { get; init; }
|
|
|
|
public static RemediationPlanApiResponse FromDomain(RemediationPlan plan)
|
|
{
|
|
return new RemediationPlanApiResponse
|
|
{
|
|
PlanId = plan.PlanId,
|
|
Steps = plan.Steps.Select(s => new RemediationStepResponse
|
|
{
|
|
Order = s.Order,
|
|
ActionType = s.ActionType,
|
|
FilePath = s.FilePath,
|
|
Description = s.Description,
|
|
PreviousValue = s.PreviousValue,
|
|
NewValue = s.NewValue,
|
|
Optional = s.Optional,
|
|
Risk = s.Risk.ToString()
|
|
}).ToList(),
|
|
ExpectedDelta = new ExpectedDeltaResponse
|
|
{
|
|
Added = plan.ExpectedDelta.Added,
|
|
Removed = plan.ExpectedDelta.Removed,
|
|
Upgraded = plan.ExpectedDelta.Upgraded,
|
|
NetVulnerabilityChange = plan.ExpectedDelta.NetVulnerabilityChange
|
|
},
|
|
RiskAssessment = plan.RiskAssessment.ToString(),
|
|
Authority = plan.Authority.ToString(),
|
|
PrReady = plan.PrReady,
|
|
NotReadyReason = plan.NotReadyReason,
|
|
ConfidenceScore = plan.ConfidenceScore,
|
|
ModelId = plan.ModelId,
|
|
GeneratedAt = plan.GeneratedAt
|
|
};
|
|
}
|
|
}
|
|
|
|
public sealed record RemediationStepResponse
|
|
{
|
|
public required int Order { get; init; }
|
|
public required string ActionType { get; init; }
|
|
public required string FilePath { get; init; }
|
|
public required string Description { get; init; }
|
|
public string? PreviousValue { get; init; }
|
|
public string? NewValue { get; init; }
|
|
public bool Optional { get; init; }
|
|
public required string Risk { get; init; }
|
|
}
|
|
|
|
public sealed record ExpectedDeltaResponse
|
|
{
|
|
public required IReadOnlyList<string> Added { get; init; }
|
|
public required IReadOnlyList<string> Removed { get; init; }
|
|
public required IReadOnlyDictionary<string, string> Upgraded { get; init; }
|
|
public required int NetVulnerabilityChange { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// API request for applying remediation (creating PR).
|
|
/// Task: REMEDY-20
|
|
/// </summary>
|
|
public sealed record ApplyRemediationRequest
|
|
{
|
|
[Required]
|
|
public required string PlanId { get; init; }
|
|
|
|
public string ScmType { get; init; } = "github";
|
|
}
|
|
|
|
/// <summary>
|
|
/// API response for PR creation.
|
|
/// </summary>
|
|
public sealed record PullRequestApiResponse
|
|
{
|
|
public required string PrId { get; init; }
|
|
public required int PrNumber { get; init; }
|
|
public required string Url { get; init; }
|
|
public required string BranchName { get; init; }
|
|
public required string Status { get; init; }
|
|
public string? StatusMessage { get; init; }
|
|
public BuildResultResponse? BuildResult { get; init; }
|
|
public TestResultResponse? TestResult { get; init; }
|
|
public DeltaVerdictResponse? DeltaVerdict { get; init; }
|
|
public required string CreatedAt { get; init; }
|
|
public required string UpdatedAt { get; init; }
|
|
|
|
public static PullRequestApiResponse FromDomain(PullRequestResult result)
|
|
{
|
|
return new PullRequestApiResponse
|
|
{
|
|
PrId = result.PrId,
|
|
PrNumber = result.PrNumber,
|
|
Url = result.Url,
|
|
BranchName = result.BranchName,
|
|
Status = result.Status.ToString(),
|
|
StatusMessage = result.StatusMessage,
|
|
BuildResult = result.BuildResult != null ? new BuildResultResponse
|
|
{
|
|
Success = result.BuildResult.Success,
|
|
BuildId = result.BuildResult.BuildId,
|
|
BuildUrl = result.BuildResult.BuildUrl,
|
|
ErrorMessage = result.BuildResult.ErrorMessage,
|
|
CompletedAt = result.BuildResult.CompletedAt
|
|
} : null,
|
|
TestResult = result.TestResult != null ? new TestResultResponse
|
|
{
|
|
AllPassed = result.TestResult.AllPassed,
|
|
TotalTests = result.TestResult.TotalTests,
|
|
PassedTests = result.TestResult.PassedTests,
|
|
FailedTests = result.TestResult.FailedTests,
|
|
SkippedTests = result.TestResult.SkippedTests,
|
|
Coverage = result.TestResult.Coverage,
|
|
FailedTestNames = result.TestResult.FailedTestNames,
|
|
CompletedAt = result.TestResult.CompletedAt
|
|
} : null,
|
|
DeltaVerdict = result.DeltaVerdict != null ? new DeltaVerdictResponse
|
|
{
|
|
Improved = result.DeltaVerdict.Improved,
|
|
VulnerabilitiesFixed = result.DeltaVerdict.VulnerabilitiesFixed,
|
|
VulnerabilitiesIntroduced = result.DeltaVerdict.VulnerabilitiesIntroduced,
|
|
VerdictId = result.DeltaVerdict.VerdictId,
|
|
SignatureId = result.DeltaVerdict.SignatureId,
|
|
ComputedAt = result.DeltaVerdict.ComputedAt
|
|
} : null,
|
|
CreatedAt = result.CreatedAt,
|
|
UpdatedAt = result.UpdatedAt
|
|
};
|
|
}
|
|
}
|
|
|
|
public sealed record BuildResultResponse
|
|
{
|
|
public required bool Success { get; init; }
|
|
public required string BuildId { get; init; }
|
|
public string? BuildUrl { get; init; }
|
|
public string? ErrorMessage { get; init; }
|
|
public required string CompletedAt { get; init; }
|
|
}
|
|
|
|
public sealed record TestResultResponse
|
|
{
|
|
public required bool AllPassed { get; init; }
|
|
public required int TotalTests { get; init; }
|
|
public required int PassedTests { get; init; }
|
|
public required int FailedTests { get; init; }
|
|
public required int SkippedTests { get; init; }
|
|
public double Coverage { get; init; }
|
|
public IReadOnlyList<string> FailedTestNames { get; init; } = Array.Empty<string>();
|
|
public required string CompletedAt { get; init; }
|
|
}
|
|
|
|
public sealed record DeltaVerdictResponse
|
|
{
|
|
public required bool Improved { get; init; }
|
|
public required int VulnerabilitiesFixed { get; init; }
|
|
public required int VulnerabilitiesIntroduced { get; init; }
|
|
public required string VerdictId { get; init; }
|
|
public string? SignatureId { get; init; }
|
|
public required string ComputedAt { get; init; }
|
|
}
|