Fix build and code structure improvements. New but essential UI functionality. CI improvements. Documentation improvements. AI module improvements.
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// ReplayVerificationModels.cs
|
||||
// Sprint: SPRINT_20251228_007_BE_sbom_lineage_graph_ii (LIN-BE-033)
|
||||
// Task: Create replay verification API models
|
||||
// Description: Request/response models for the replay verification endpoints.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace StellaOps.SbomService.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Request model for replay hash verification.
|
||||
/// </summary>
|
||||
public sealed record ReplayVerifyRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// The replay hash to verify.
|
||||
/// </summary>
|
||||
public required string ReplayHash { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Tenant identifier.
|
||||
/// </summary>
|
||||
public required string TenantId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional: SBOM digest to use for verification.
|
||||
/// </summary>
|
||||
public string? SbomDigest { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional: Feeds snapshot digest to use.
|
||||
/// </summary>
|
||||
public string? FeedsSnapshotDigest { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional: Policy version to use.
|
||||
/// </summary>
|
||||
public string? PolicyVersion { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional: VEX verdicts digest to use.
|
||||
/// </summary>
|
||||
public string? VexVerdictsDigest { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional: Timestamp to use for verification.
|
||||
/// </summary>
|
||||
public DateTimeOffset? Timestamp { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to freeze time to the original evaluation timestamp.
|
||||
/// Default: true.
|
||||
/// </summary>
|
||||
public bool? FreezeTime { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to re-evaluate policy with frozen feeds.
|
||||
/// Default: false.
|
||||
/// </summary>
|
||||
public bool? ReEvaluatePolicy { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request model for comparing drift between two replay hashes.
|
||||
/// </summary>
|
||||
public sealed record CompareDriftRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// First replay hash.
|
||||
/// </summary>
|
||||
public required string HashA { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Second replay hash.
|
||||
/// </summary>
|
||||
public required string HashB { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Tenant identifier.
|
||||
/// </summary>
|
||||
public required string TenantId { get; init; }
|
||||
}
|
||||
@@ -21,6 +21,16 @@ public sealed record SbomUploadRequest
|
||||
|
||||
[JsonPropertyName("source")]
|
||||
public SbomUploadSource? Source { get; init; }
|
||||
|
||||
// LIN-BE-003: Lineage ancestry fields
|
||||
[JsonPropertyName("parentArtifactDigest")]
|
||||
public string? ParentArtifactDigest { get; init; }
|
||||
|
||||
[JsonPropertyName("baseImageRef")]
|
||||
public string? BaseImageRef { get; init; }
|
||||
|
||||
[JsonPropertyName("baseImageDigest")]
|
||||
public string? BaseImageDigest { get; init; }
|
||||
}
|
||||
|
||||
public sealed record SbomUploadSource
|
||||
@@ -101,7 +111,12 @@ public sealed record SbomLedgerSubmission(
|
||||
string Source,
|
||||
SbomUploadSource? Provenance,
|
||||
IReadOnlyList<SbomNormalizedComponent> Components,
|
||||
Guid? ParentVersionId);
|
||||
Guid? ParentVersionId,
|
||||
// LIN-BE-003: Lineage ancestry fields
|
||||
string? ParentArtifactDigest = null,
|
||||
string? BaseImageRef = null,
|
||||
string? BaseImageDigest = null,
|
||||
string? BuildId = null);
|
||||
|
||||
public sealed record SbomLedgerVersion
|
||||
{
|
||||
@@ -117,7 +132,29 @@ public sealed record SbomLedgerVersion
|
||||
public SbomUploadSource? Provenance { get; init; }
|
||||
public Guid? ParentVersionId { get; init; }
|
||||
public string? ParentDigest { get; init; }
|
||||
// LIN-BE-003: Lineage ancestry fields
|
||||
public string? ParentArtifactDigest { get; init; }
|
||||
public string? BaseImageRef { get; init; }
|
||||
public string? BaseImageDigest { get; init; }
|
||||
public string? BuildId { get; init; }
|
||||
public IReadOnlyList<SbomNormalizedComponent> Components { get; init; } = Array.Empty<SbomNormalizedComponent>();
|
||||
// LIN-BE-023: Replay hash for reproducibility verification
|
||||
public string? ReplayHash { get; init; }
|
||||
public ReplayHashInputSnapshot? ReplayHashInputs { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Snapshot of inputs used to compute a replay hash.
|
||||
/// Stored alongside the version for audit and reproducibility.
|
||||
/// Sprint: LIN-BE-023
|
||||
/// </summary>
|
||||
public sealed record ReplayHashInputSnapshot
|
||||
{
|
||||
public required string SbomDigest { get; init; }
|
||||
public required string FeedsSnapshotDigest { get; init; }
|
||||
public required string PolicyVersion { get; init; }
|
||||
public required string VexVerdictsDigest { get; init; }
|
||||
public required DateTimeOffset ComputedAt { get; init; }
|
||||
}
|
||||
|
||||
public sealed record SbomVersionHistoryItem(
|
||||
@@ -196,6 +233,7 @@ public static class SbomLineageRelationships
|
||||
{
|
||||
public const string Parent = "parent";
|
||||
public const string Build = "build";
|
||||
public const string Base = "base";
|
||||
}
|
||||
|
||||
public sealed record SbomLineageResult(
|
||||
@@ -204,6 +242,140 @@ public sealed record SbomLineageResult(
|
||||
IReadOnlyList<SbomLineageNode> Nodes,
|
||||
IReadOnlyList<SbomLineageEdge> Edges);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Extended Lineage Models for SBOM Lineage Graph
|
||||
// Sprint: SPRINT_20251228_005_BE_sbom_lineage_graph_i (LIN-BE-004/005)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Persistent lineage edge stored in database.
|
||||
/// Uses artifact digests as stable identifiers across systems.
|
||||
/// </summary>
|
||||
public sealed record SbomLineageEdgeEntity
|
||||
{
|
||||
public required Guid Id { get; init; }
|
||||
public required string ParentDigest { get; init; }
|
||||
public required string ChildDigest { get; init; }
|
||||
public required LineageRelationship Relationship { get; init; }
|
||||
public required Guid TenantId { get; init; }
|
||||
public required DateTimeOffset CreatedAt { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lineage relationship type.
|
||||
/// </summary>
|
||||
public enum LineageRelationship
|
||||
{
|
||||
/// <summary>
|
||||
/// Direct version succession (v1.0 → v1.1).
|
||||
/// </summary>
|
||||
Parent,
|
||||
|
||||
/// <summary>
|
||||
/// Same CI build produced multiple artifacts (multi-arch).
|
||||
/// </summary>
|
||||
Build,
|
||||
|
||||
/// <summary>
|
||||
/// Derived from base image (FROM instruction).
|
||||
/// </summary>
|
||||
Base
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extended lineage node with badge information for UI.
|
||||
/// </summary>
|
||||
public sealed record SbomLineageNodeExtended
|
||||
{
|
||||
public required Guid Id { get; init; }
|
||||
public required string Digest { get; init; }
|
||||
public required string ArtifactRef { get; init; }
|
||||
public required int SequenceNumber { get; init; }
|
||||
public required DateTimeOffset CreatedAt { get; init; }
|
||||
public required string Source { get; init; }
|
||||
public SbomLineageBadges? Badges { get; init; }
|
||||
public string? ReplayHash { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Badge information for lineage node.
|
||||
/// </summary>
|
||||
public sealed record SbomLineageBadges
|
||||
{
|
||||
public int NewVulns { get; init; }
|
||||
public int ResolvedVulns { get; init; }
|
||||
public string SignatureStatus { get; init; } = "unknown";
|
||||
public int ComponentCount { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extended lineage edge with digest-based endpoints.
|
||||
/// </summary>
|
||||
public sealed record SbomLineageEdgeExtended
|
||||
{
|
||||
public required string From { get; init; }
|
||||
public required string To { get; init; }
|
||||
public required string Relationship { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Complete lineage graph response.
|
||||
/// </summary>
|
||||
public sealed record SbomLineageGraphResponse
|
||||
{
|
||||
public required string Artifact { get; init; }
|
||||
public required IReadOnlyList<SbomLineageNodeExtended> Nodes { get; init; }
|
||||
public required IReadOnlyList<SbomLineageEdgeExtended> Edges { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lineage diff response with component and VEX deltas.
|
||||
/// </summary>
|
||||
public sealed record SbomLineageDiffResponse
|
||||
{
|
||||
public required SbomDiffResult SbomDiff { get; init; }
|
||||
public required IReadOnlyList<VexDeltaSummary> VexDiff { get; init; }
|
||||
public IReadOnlyList<ReachabilityDeltaSummary>? ReachabilityDiff { get; init; }
|
||||
public required string ReplayHash { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// VEX status change between versions.
|
||||
/// </summary>
|
||||
public sealed record VexDeltaSummary
|
||||
{
|
||||
public required string Cve { get; init; }
|
||||
public required string FromStatus { get; init; }
|
||||
public required string ToStatus { get; init; }
|
||||
public string? Reason { get; init; }
|
||||
public string? EvidenceLink { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reachability change between versions.
|
||||
/// </summary>
|
||||
public sealed record ReachabilityDeltaSummary
|
||||
{
|
||||
public required string Cve { get; init; }
|
||||
public required string FromStatus { get; init; }
|
||||
public required string ToStatus { get; init; }
|
||||
public int PathsAdded { get; init; }
|
||||
public int PathsRemoved { get; init; }
|
||||
public IReadOnlyList<string>? GatesAdded { get; init; }
|
||||
public IReadOnlyList<string>? GatesRemoved { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Query options for lineage graph.
|
||||
/// </summary>
|
||||
public sealed record SbomLineageQueryOptions
|
||||
{
|
||||
public int MaxDepth { get; init; } = 10;
|
||||
public bool IncludeVerdicts { get; init; } = true;
|
||||
public bool IncludeBadges { get; init; } = true;
|
||||
public bool IncludeReplayHash { get; init; }
|
||||
}
|
||||
|
||||
public sealed record SbomRetentionResult(
|
||||
int VersionsPruned,
|
||||
int ChainsTouched,
|
||||
|
||||
Reference in New Issue
Block a user