Files
git.stella-ops.org/src/Scheduler/__Libraries/StellaOps.Scheduler.Queue/Models/ChainVerificationResult.cs
2026-01-06 19:07:48 +02:00

126 lines
3.3 KiB
C#

// -----------------------------------------------------------------------------
// ChainVerificationResult.cs
// Sprint: SPRINT_20260105_002_002_SCHEDULER_hlc_queue_chain
// Task: SQC-015 - Implement chain verification
// -----------------------------------------------------------------------------
using StellaOps.Scheduler.Persistence.Postgres;
namespace StellaOps.Scheduler.Queue.Models;
/// <summary>
/// Result of chain verification.
/// </summary>
public sealed record ChainVerificationResult
{
/// <summary>
/// Whether the chain is valid (no issues found).
/// </summary>
public required bool IsValid { get; init; }
/// <summary>
/// Number of entries checked.
/// </summary>
public required int EntriesChecked { get; init; }
/// <summary>
/// List of issues found during verification.
/// </summary>
public required IReadOnlyList<ChainVerificationIssue> Issues { get; init; }
/// <summary>
/// First valid entry's HLC timestamp (null if no entries).
/// </summary>
public string? FirstHlc { get; init; }
/// <summary>
/// Last valid entry's HLC timestamp (null if no entries).
/// </summary>
public string? LastHlc { get; init; }
/// <summary>
/// Head link after verification (null if no entries).
/// </summary>
public byte[]? HeadLink { get; init; }
/// <summary>
/// Get a summary of the verification result.
/// </summary>
public string GetSummary()
{
if (IsValid)
{
return $"Chain valid: {EntriesChecked} entries verified, range [{FirstHlc}, {LastHlc}], head {SchedulerChainLinking.ToHexString(HeadLink)}";
}
return $"Chain INVALID: {Issues.Count} issue(s) found in {EntriesChecked} entries";
}
}
/// <summary>
/// Represents a single issue found during chain verification.
/// </summary>
public sealed record ChainVerificationIssue
{
/// <summary>
/// Job ID where the issue was found.
/// </summary>
public required Guid JobId { get; init; }
/// <summary>
/// HLC timestamp of the problematic entry.
/// </summary>
public required string THlc { get; init; }
/// <summary>
/// Type of issue found.
/// </summary>
public required ChainVerificationIssueType IssueType { get; init; }
/// <summary>
/// Human-readable description of the issue.
/// </summary>
public required string Description { get; init; }
/// <summary>
/// Expected value (for comparison issues).
/// </summary>
public string? Expected { get; init; }
/// <summary>
/// Actual value found (for comparison issues).
/// </summary>
public string? Actual { get; init; }
}
/// <summary>
/// Types of chain verification issues.
/// </summary>
public enum ChainVerificationIssueType
{
/// <summary>
/// The prev_link doesn't match the previous entry's link.
/// </summary>
PrevLinkMismatch,
/// <summary>
/// The stored link doesn't match the computed link.
/// </summary>
LinkMismatch,
/// <summary>
/// The HLC timestamp is out of order.
/// </summary>
HlcOrderViolation,
/// <summary>
/// The payload hash has invalid length.
/// </summary>
InvalidPayloadHash,
/// <summary>
/// The link has invalid length.
/// </summary>
InvalidLinkLength
}