// -----------------------------------------------------------------------------
// UnifiedEvidenceContracts.cs
// Sprint: SPRINT_9200_0001_0002_SCANNER_unified_evidence_endpoint
// Description: DTOs for unified evidence endpoint that returns all evidence
// tabs for a finding in one API call.
// -----------------------------------------------------------------------------
namespace StellaOps.Scanner.WebService.Contracts;
///
/// Complete evidence package for a finding - all tabs in one response.
///
public sealed record UnifiedEvidenceResponseDto
{
/// Finding this evidence applies to.
public required string FindingId { get; init; }
/// CVE identifier.
public required string CveId { get; init; }
/// Affected component PURL.
public required string ComponentPurl { get; init; }
// === Evidence Tabs ===
/// SBOM evidence - component metadata and linkage.
public SbomEvidenceDto? Sbom { get; init; }
/// Reachability evidence - call paths to vulnerable code.
public ReachabilityEvidenceDto? Reachability { get; init; }
/// VEX claims from all sources with trust scores.
public IReadOnlyList? VexClaims { get; init; }
/// Attestations (in-toto/DSSE) for this artifact.
public IReadOnlyList? Attestations { get; init; }
/// Delta comparison since last scan.
public DeltaEvidenceDto? Deltas { get; init; }
/// Policy evaluation evidence.
public PolicyEvidenceDto? Policy { get; init; }
// Sprint: SPRINT_20260112_009_SCANNER_binary_diff_bundle_export (BINDIFF-SCAN-001)
/// Binary diff evidence with semantic and structural changes.
public BinaryDiffEvidenceDto? BinaryDiff { get; init; }
// === Manifest Hashes ===
/// Content-addressed hashes for determinism verification.
public required ManifestHashesDto Manifests { get; init; }
// === Verification Status ===
/// Overall verification status of evidence chain.
public required VerificationStatusDto Verification { get; init; }
// === Replay Command ===
/// Copy-ready CLI command to replay this verdict.
public string? ReplayCommand { get; init; }
/// Shortened replay command using snapshot ID.
public string? ShortReplayCommand { get; init; }
/// URL to download complete evidence bundle.
public string? EvidenceBundleUrl { get; init; }
// === Metadata ===
/// When this evidence was assembled.
public required DateTimeOffset GeneratedAt { get; init; }
/// Cache key for this response (content-addressed).
public string? CacheKey { get; init; }
}
///
/// SBOM evidence for evidence panel.
///
public sealed record SbomEvidenceDto
{
/// SBOM format (spdx, cyclonedx).
public required string Format { get; init; }
/// SBOM version.
public required string Version { get; init; }
/// Link to full SBOM document.
public required string DocumentUri { get; init; }
/// SBOM content digest.
public required string Digest { get; init; }
/// Component entry from SBOM.
public SbomComponentDto? Component { get; init; }
/// Dependencies of this component.
public IReadOnlyList? Dependencies { get; init; }
/// Dependents (things that depend on this component).
public IReadOnlyList? Dependents { get; init; }
}
///
/// Component information from SBOM.
///
public sealed record SbomComponentDto
{
/// Package URL.
public required string Purl { get; init; }
/// Component name.
public required string Name { get; init; }
/// Component version.
public required string Version { get; init; }
/// Ecosystem (npm, maven, pypi, etc.).
public string? Ecosystem { get; init; }
/// License(s).
public IReadOnlyList? Licenses { get; init; }
/// CPE identifiers.
public IReadOnlyList? Cpes { get; init; }
}
///
/// Reachability evidence for evidence panel.
///
public sealed record ReachabilityEvidenceDto
{
/// Subgraph ID for detailed view.
public required string SubgraphId { get; init; }
/// Reachability status.
public required string Status { get; init; }
/// Confidence level (0-1).
public double Confidence { get; init; }
/// Analysis method (static, binary, runtime).
public required string Method { get; init; }
/// Entry points reaching vulnerable code.
public IReadOnlyList? EntryPoints { get; init; }
/// Call chain summary.
public CallChainSummaryDto? CallChain { get; init; }
/// Link to full reachability graph.
public string? GraphUri { get; init; }
}
///
/// Entry point information.
///
public sealed record EntryPointDto
{
/// Entry point identifier.
public required string Id { get; init; }
/// Entry point type (http, grpc, function, etc.).
public required string Type { get; init; }
/// Display name.
public required string Name { get; init; }
/// File location if known.
public string? Location { get; init; }
/// Distance (hops) to vulnerable code.
public int? Distance { get; init; }
}
///
/// Summary of call chain to vulnerable code.
///
public sealed record CallChainSummaryDto
{
/// Total path length.
public int PathLength { get; init; }
/// Number of distinct paths.
public int PathCount { get; init; }
/// Key symbols in the chain.
public IReadOnlyList? KeySymbols { get; init; }
/// Link to full call graph.
public string? CallGraphUri { get; init; }
}
///
/// VEX claim with trust scoring.
///
public sealed record VexClaimDto
{
/// VEX statement ID.
public required string StatementId { get; init; }
/// Source of the VEX statement.
public required string Source { get; init; }
/// Status (affected, not_affected, etc.).
public required string Status { get; init; }
/// Justification category.
public string? Justification { get; init; }
/// Impact statement.
public string? ImpactStatement { get; init; }
/// When issued.
public DateTimeOffset IssuedAt { get; init; }
/// Trust score (0-1).
public double TrustScore { get; init; }
/// Whether this meets policy threshold.
public bool MeetsPolicyThreshold { get; init; }
/// Link to full VEX document.
public string? DocumentUri { get; init; }
}
///
/// Attestation summary for evidence panel.
///
public sealed record AttestationSummaryDto
{
/// Attestation ID.
public required string Id { get; init; }
/// Predicate type.
public required string PredicateType { get; init; }
/// Subject digest.
public required string SubjectDigest { get; init; }
/// Signer identity.
public string? Signer { get; init; }
/// When signed.
public DateTimeOffset? SignedAt { get; init; }
/// Verification status.
public required string VerificationStatus { get; init; }
/// Transparency log entry if logged.
public string? TransparencyLogEntry { get; init; }
/// Link to full attestation.
public string? AttestationUri { get; init; }
}
///
/// Delta evidence showing what changed.
///
public sealed record DeltaEvidenceDto
{
/// Delta comparison ID.
public required string DeltaId { get; init; }
/// Previous scan ID.
public required string PreviousScanId { get; init; }
/// Current scan ID.
public required string CurrentScanId { get; init; }
/// When comparison was made.
public DateTimeOffset ComparedAt { get; init; }
/// Summary of changes.
public DeltaSummaryDto? Summary { get; init; }
/// Link to full delta report.
public string? DeltaReportUri { get; init; }
}
///
/// Summary of delta changes.
///
public sealed record DeltaSummaryDto
{
/// New findings.
public int AddedCount { get; init; }
/// Removed findings.
public int RemovedCount { get; init; }
/// Changed findings.
public int ChangedCount { get; init; }
/// Was this finding new in this scan?
public bool IsNew { get; init; }
/// Was this finding's status changed?
public bool StatusChanged { get; init; }
/// Previous status if changed.
public string? PreviousStatus { get; init; }
}
///
/// Policy evaluation evidence.
///
public sealed record PolicyEvidenceDto
{
/// Policy version used.
public required string PolicyVersion { get; init; }
/// Policy digest.
public required string PolicyDigest { get; init; }
/// Verdict from policy evaluation.
public required string Verdict { get; init; }
/// Rules that fired.
public IReadOnlyList? RulesFired { get; init; }
/// Counterfactuals - what would change the verdict.
public IReadOnlyList? Counterfactuals { get; init; }
/// Link to policy document.
public string? PolicyDocumentUri { get; init; }
}
///
/// Policy rule that fired during evaluation.
///
public sealed record PolicyRuleFiredDto
{
/// Rule ID.
public required string RuleId { get; init; }
/// Rule name.
public required string Name { get; init; }
/// Effect (allow, deny, warn).
public required string Effect { get; init; }
/// Reason the rule fired.
public string? Reason { get; init; }
}
///
/// Content-addressed manifest hashes for determinism verification.
///
public sealed record ManifestHashesDto
{
/// Artifact digest (image or SBOM).
public required string ArtifactDigest { get; init; }
/// Run manifest hash.
public required string ManifestHash { get; init; }
/// Feed snapshot hash.
public required string FeedSnapshotHash { get; init; }
/// Policy hash.
public required string PolicyHash { get; init; }
/// Knowledge snapshot ID.
public string? KnowledgeSnapshotId { get; init; }
/// Graph revision ID.
public string? GraphRevisionId { get; init; }
}
///
/// Overall verification status.
///
public sealed record VerificationStatusDto
{
/// Overall status (verified, partial, failed, unknown).
public required string Status { get; init; }
/// True if all hashes match expected values.
public bool HashesVerified { get; init; }
/// True if attestations verify.
public bool AttestationsVerified { get; init; }
/// True if evidence is complete.
public bool EvidenceComplete { get; init; }
/// Any verification issues.
public IReadOnlyList? Issues { get; init; }
/// Last verification timestamp.
public DateTimeOffset? VerifiedAt { get; init; }
}
// Sprint: SPRINT_20260112_009_SCANNER_binary_diff_bundle_export (BINDIFF-SCAN-001)
///
/// Binary diff evidence for unified evidence response.
///
public sealed record BinaryDiffEvidenceDto
{
/// Evidence status.
public required string Status { get; init; }
/// SHA-256 hash of the evidence content.
public string? Hash { get; init; }
/// Previous binary artifact digest.
public string? PreviousBinaryDigest { get; init; }
/// Current binary artifact digest.
public string? CurrentBinaryDigest { get; init; }
/// Type of diff (structural, semantic, hybrid).
public string? DiffType { get; init; }
/// Binary format/ISA (e.g., elf-x86_64).
public string? BinaryFormat { get; init; }
/// Tool and version used for diffing.
public string? ToolVersion { get; init; }
/// Overall similarity score (0.0-1.0).
public double? SimilarityScore { get; init; }
/// Number of function-level changes.
public int FunctionChangeCount { get; init; }
/// Number of symbol-level changes.
public int SymbolChangeCount { get; init; }
/// Number of section-level changes.
public int SectionChangeCount { get; init; }
/// Number of security-relevant changes.
public int SecurityChangeCount { get; init; }
/// Whether semantic diff is available.
public bool HasSemanticDiff { get; init; }
/// Semantic similarity score (0.0-1.0).
public double? SemanticSimilarity { get; init; }
/// Function-level changes.
public IReadOnlyList? FunctionChanges { get; init; }
/// Security-relevant changes.
public IReadOnlyList? SecurityChanges { get; init; }
/// DSSE attestation reference for binary diff.
public AttestationRefDto? Attestation { get; init; }
/// CAS URI for full binary diff evidence.
public string? CasUri { get; init; }
}
///
/// Function-level diff entry for binary diff.
///
public sealed record BinaryFunctionDiffDto
{
/// Diff operation (added, removed, modified).
public required string Operation { get; init; }
/// Function name.
public required string FunctionName { get; init; }
/// Function signature (if available).
public string? Signature { get; init; }
/// Semantic similarity score for modified functions.
public double? Similarity { get; init; }
/// Node hash for reachability correlation.
public string? NodeHash { get; init; }
/// Whether this function is security-sensitive.
public bool SecuritySensitive { get; init; }
}
///
/// Security-relevant change in binary.
///
public sealed record BinarySecurityChangeDto
{
/// Type of security change.
public required string ChangeType { get; init; }
/// Severity level (info, warning, critical).
public required string Severity { get; init; }
/// Description of the change.
public required string Description { get; init; }
/// Affected function name.
public string? AffectedFunction { get; init; }
/// Suggested remediation.
public string? Remediation { get; init; }
}
///
/// Attestation reference for evidence.
///
public sealed record AttestationRefDto
{
/// Attestation ID.
public required string Id { get; init; }
/// Predicate type URI.
public required string PredicateType { get; init; }
/// DSSE envelope digest.
public string? EnvelopeDigest { get; init; }
/// Rekor log index (if anchored).
public long? RekorLogIndex { get; init; }
/// CAS URI for full attestation.
public string? CasUri { get; init; }
}