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; }
}