Add property-based tests for SBOM/VEX document ordering and Unicode normalization determinism
- 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.
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
namespace StellaOps.AdvisoryAI.Remediation;
|
||||
|
||||
/// <summary>
|
||||
/// Authority level of the remediation plan.
|
||||
/// </summary>
|
||||
public enum RemediationAuthority
|
||||
{
|
||||
/// <summary>
|
||||
/// Verified: build passed, tests passed, delta verified.
|
||||
/// </summary>
|
||||
Verified,
|
||||
|
||||
/// <summary>
|
||||
/// Suggestion: requires human review (build/tests failed or not run).
|
||||
/// </summary>
|
||||
Suggestion,
|
||||
|
||||
/// <summary>
|
||||
/// Draft: initial plan not yet verified.
|
||||
/// </summary>
|
||||
Draft
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Risk level of the remediation.
|
||||
/// </summary>
|
||||
public enum RemediationRisk
|
||||
{
|
||||
/// <summary>
|
||||
/// Low risk: patch version bump.
|
||||
/// </summary>
|
||||
Low,
|
||||
|
||||
/// <summary>
|
||||
/// Medium risk: minor version bump.
|
||||
/// </summary>
|
||||
Medium,
|
||||
|
||||
/// <summary>
|
||||
/// High risk: major version bump or breaking changes.
|
||||
/// </summary>
|
||||
High,
|
||||
|
||||
/// <summary>
|
||||
/// Unknown risk: unable to determine.
|
||||
/// </summary>
|
||||
Unknown
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A single step in a remediation plan.
|
||||
/// </summary>
|
||||
public sealed record RemediationStep
|
||||
{
|
||||
/// <summary>
|
||||
/// Step number (1-based).
|
||||
/// </summary>
|
||||
public required int Order { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Type of action (update_package, update_lockfile, update_config, run_command, etc.).
|
||||
/// </summary>
|
||||
public required string ActionType { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// File path affected.
|
||||
/// </summary>
|
||||
public required string FilePath { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Description of the change.
|
||||
/// </summary>
|
||||
public required string Description { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Previous value (for diff).
|
||||
/// </summary>
|
||||
public string? PreviousValue { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// New value (for diff).
|
||||
/// </summary>
|
||||
public string? NewValue { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this step is optional.
|
||||
/// </summary>
|
||||
public bool Optional { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Risk assessment for this step.
|
||||
/// </summary>
|
||||
public RemediationRisk Risk { get; init; } = RemediationRisk.Low;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expected SBOM delta after remediation.
|
||||
/// </summary>
|
||||
public sealed record ExpectedSbomDelta
|
||||
{
|
||||
/// <summary>
|
||||
/// Components to be added.
|
||||
/// </summary>
|
||||
public required IReadOnlyList<string> Added { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Components to be removed.
|
||||
/// </summary>
|
||||
public required IReadOnlyList<string> Removed { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Components to be upgraded (old_purl → new_purl).
|
||||
/// </summary>
|
||||
public required IReadOnlyDictionary<string, string> Upgraded { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Net vulnerability change (negative = improvement).
|
||||
/// </summary>
|
||||
public required int NetVulnerabilityChange { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test requirements for verifying remediation.
|
||||
/// </summary>
|
||||
public sealed record RemediationTestRequirements
|
||||
{
|
||||
/// <summary>
|
||||
/// Required test suites to run.
|
||||
/// </summary>
|
||||
public required IReadOnlyList<string> TestSuites { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum coverage required.
|
||||
/// </summary>
|
||||
public double MinCoverage { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether all tests must pass.
|
||||
/// </summary>
|
||||
public bool RequireAllPass { get; init; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Timeout for test execution.
|
||||
/// </summary>
|
||||
public TimeSpan Timeout { get; init; } = TimeSpan.FromMinutes(30);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A complete remediation plan.
|
||||
/// Sprint: SPRINT_20251226_016_AI_remedy_autopilot
|
||||
/// Task: REMEDY-05
|
||||
/// </summary>
|
||||
public sealed record RemediationPlan
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique plan ID.
|
||||
/// </summary>
|
||||
public required string PlanId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Original request.
|
||||
/// </summary>
|
||||
public required RemediationPlanRequest Request { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Remediation steps to apply.
|
||||
/// </summary>
|
||||
public required IReadOnlyList<RemediationStep> Steps { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Expected SBOM delta.
|
||||
/// </summary>
|
||||
public required ExpectedSbomDelta ExpectedDelta { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Overall risk assessment.
|
||||
/// </summary>
|
||||
public required RemediationRisk RiskAssessment { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Test requirements.
|
||||
/// </summary>
|
||||
public required RemediationTestRequirements TestRequirements { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Authority classification.
|
||||
/// </summary>
|
||||
public required RemediationAuthority Authority { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// PR-ready flag (true if plan can be applied automatically).
|
||||
/// </summary>
|
||||
public required bool PrReady { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Reason if not PR-ready.
|
||||
/// </summary>
|
||||
public string? NotReadyReason { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Confidence score (0.0-1.0).
|
||||
/// </summary>
|
||||
public required double ConfidenceScore { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Model ID used for generation.
|
||||
/// </summary>
|
||||
public required string ModelId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Generated timestamp (UTC ISO-8601).
|
||||
/// </summary>
|
||||
public required string GeneratedAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Input hashes for replay.
|
||||
/// </summary>
|
||||
public required IReadOnlyList<string> InputHashes { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Evidence refs used in planning.
|
||||
/// </summary>
|
||||
public required IReadOnlyList<string> EvidenceRefs { get; init; }
|
||||
}
|
||||
Reference in New Issue
Block a user