using System.Text.Json.Serialization; namespace StellaOps.Testing.Determinism; /// /// Determinism manifest tracking artifact reproducibility with canonical bytes hash, /// version stamps, and toolchain information. /// public sealed record DeterminismManifest { /// /// Version of this manifest schema (currently "1.0"). /// [JsonPropertyName("schemaVersion")] public required string SchemaVersion { get; init; } /// /// Artifact being tracked for determinism. /// [JsonPropertyName("artifact")] public required ArtifactInfo Artifact { get; init; } /// /// Hash of the canonical representation of the artifact. /// [JsonPropertyName("canonicalHash")] public required CanonicalHashInfo CanonicalHash { get; init; } /// /// Version stamps of all inputs used to generate the artifact. /// [JsonPropertyName("inputs")] public InputStamps? Inputs { get; init; } /// /// Toolchain version information. /// [JsonPropertyName("toolchain")] public required ToolchainInfo Toolchain { get; init; } /// /// UTC timestamp when artifact was generated (ISO 8601). /// [JsonPropertyName("generatedAt")] public required DateTimeOffset GeneratedAt { get; init; } /// /// Reproducibility metadata. /// [JsonPropertyName("reproducibility")] public ReproducibilityMetadata? Reproducibility { get; init; } /// /// Verification instructions for reproducing the artifact. /// [JsonPropertyName("verification")] public VerificationInfo? Verification { get; init; } /// /// Optional cryptographic signatures of this manifest. /// [JsonPropertyName("signatures")] public IReadOnlyList? Signatures { get; init; } } /// /// Artifact being tracked for determinism. /// public sealed record ArtifactInfo { /// /// Type of artifact. /// [JsonPropertyName("type")] public required string Type { get; init; } /// /// Artifact identifier or name. /// [JsonPropertyName("name")] public required string Name { get; init; } /// /// Artifact version or timestamp. /// [JsonPropertyName("version")] public required string Version { get; init; } /// /// Artifact format (e.g., 'SPDX 3.0.1', 'CycloneDX 1.6', 'OpenVEX'). /// [JsonPropertyName("format")] public string? Format { get; init; } /// /// Additional artifact-specific metadata. /// [JsonPropertyName("metadata")] public IReadOnlyDictionary? Metadata { get; init; } } /// /// Hash of the canonical representation of the artifact. /// public sealed record CanonicalHashInfo { /// /// Hash algorithm used (SHA-256, SHA-384, SHA-512). /// [JsonPropertyName("algorithm")] public required string Algorithm { get; init; } /// /// Hex-encoded hash value. /// [JsonPropertyName("value")] public required string Value { get; init; } /// /// Encoding of the hash value (hex or base64). /// [JsonPropertyName("encoding")] public required string Encoding { get; init; } } /// /// Version stamps of all inputs used to generate the artifact. /// public sealed record InputStamps { /// /// SHA-256 hash of the vulnerability feed snapshot used. /// [JsonPropertyName("feedSnapshotHash")] public string? FeedSnapshotHash { get; init; } /// /// SHA-256 hash of the policy manifest used. /// [JsonPropertyName("policyManifestHash")] public string? PolicyManifestHash { get; init; } /// /// Git commit SHA or source code hash. /// [JsonPropertyName("sourceCodeHash")] public string? SourceCodeHash { get; init; } /// /// Hash of dependency lockfile (e.g., package-lock.json, Cargo.lock). /// [JsonPropertyName("dependencyLockfileHash")] public string? DependencyLockfileHash { get; init; } /// /// Container base image digest (sha256:...). /// [JsonPropertyName("baseImageDigest")] public string? BaseImageDigest { get; init; } /// /// Hashes of all VEX documents used as input. /// [JsonPropertyName("vexDocumentHashes")] public IReadOnlyList? VexDocumentHashes { get; init; } /// /// Custom input hashes specific to artifact type. /// [JsonPropertyName("custom")] public IReadOnlyDictionary? Custom { get; init; } } /// /// Toolchain version information. /// public sealed record ToolchainInfo { /// /// Runtime platform (e.g., '.NET 10.0', 'Node.js 20.0'). /// [JsonPropertyName("platform")] public required string Platform { get; init; } /// /// Toolchain component versions. /// [JsonPropertyName("components")] public required IReadOnlyList Components { get; init; } /// /// Compiler information if applicable. /// [JsonPropertyName("compiler")] public CompilerInfo? Compiler { get; init; } } /// /// Toolchain component version. /// public sealed record ComponentInfo { /// /// Component name (e.g., 'StellaOps.Scanner', 'CycloneDX Generator'). /// [JsonPropertyName("name")] public required string Name { get; init; } /// /// Semantic version or git SHA. /// [JsonPropertyName("version")] public required string Version { get; init; } /// /// Optional: SHA-256 hash of the component binary. /// [JsonPropertyName("hash")] public string? Hash { get; init; } } /// /// Compiler information. /// public sealed record CompilerInfo { /// /// Compiler name (e.g., 'Roslyn', 'rustc'). /// [JsonPropertyName("name")] public required string Name { get; init; } /// /// Compiler version. /// [JsonPropertyName("version")] public required string Version { get; init; } } /// /// Reproducibility metadata. /// public sealed record ReproducibilityMetadata { /// /// Deterministic random seed if used. /// [JsonPropertyName("deterministicSeed")] public int? DeterministicSeed { get; init; } /// /// Whether system clock was fixed during generation. /// [JsonPropertyName("clockFixed")] public bool? ClockFixed { get; init; } /// /// Ordering guarantee for collections in output. /// [JsonPropertyName("orderingGuarantee")] public string? OrderingGuarantee { get; init; } /// /// Normalization rules applied (e.g., 'UTF-8', 'LF line endings', 'no whitespace'). /// [JsonPropertyName("normalizationRules")] public IReadOnlyList? NormalizationRules { get; init; } } /// /// Verification instructions for reproducing the artifact. /// public sealed record VerificationInfo { /// /// Command to regenerate the artifact. /// [JsonPropertyName("command")] public string? Command { get; init; } /// /// Expected SHA-256 hash after reproduction. /// [JsonPropertyName("expectedHash")] public string? ExpectedHash { get; init; } /// /// Baseline manifest file path for regression testing. /// [JsonPropertyName("baseline")] public string? Baseline { get; init; } } /// /// Cryptographic signature of the manifest. /// public sealed record SignatureInfo { /// /// Signature algorithm (e.g., 'ES256', 'RS256'). /// [JsonPropertyName("algorithm")] public required string Algorithm { get; init; } /// /// Key identifier used for signing. /// [JsonPropertyName("keyId")] public required string KeyId { get; init; } /// /// Base64-encoded signature. /// [JsonPropertyName("signature")] public required string Signature { get; init; } /// /// UTC timestamp when signature was created. /// [JsonPropertyName("timestamp")] public DateTimeOffset? Timestamp { get; init; } }