audit work, fixed StellaOps.sln warnings/errors, fixed tests, sprints work, new advisories
This commit is contained in:
175
src/__Libraries/StellaOps.Eventing/Models/TimelineEvent.cs
Normal file
175
src/__Libraries/StellaOps.Eventing/Models/TimelineEvent.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
// Copyright (c) StellaOps. Licensed under the AGPL-3.0-or-later.
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Serialization;
|
||||
using StellaOps.HybridLogicalClock;
|
||||
|
||||
namespace StellaOps.Eventing.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Canonical event envelope for unified timeline.
|
||||
/// </summary>
|
||||
public sealed record TimelineEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Deterministic event ID: SHA-256(correlation_id || t_hlc || service || kind)[0:32] as hex.
|
||||
/// </summary>
|
||||
[JsonPropertyName("event_id")]
|
||||
public required string EventId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// HLC timestamp from StellaOps.HybridLogicalClock.
|
||||
/// </summary>
|
||||
[JsonPropertyName("t_hlc")]
|
||||
public required HlcTimestamp THlc { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Wall-clock time (informational only).
|
||||
/// </summary>
|
||||
[JsonPropertyName("ts_wall")]
|
||||
public required DateTimeOffset TsWall { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Service name (e.g., "Scheduler", "AirGap", "Attestor").
|
||||
/// </summary>
|
||||
[JsonPropertyName("service")]
|
||||
public required string Service { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// W3C Trace Context traceparent.
|
||||
/// </summary>
|
||||
[JsonPropertyName("trace_parent")]
|
||||
public string? TraceParent { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Correlation ID linking related events.
|
||||
/// </summary>
|
||||
[JsonPropertyName("correlation_id")]
|
||||
public required string CorrelationId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Event kind (ENQUEUE, EXECUTE, EMIT, etc.).
|
||||
/// </summary>
|
||||
[JsonPropertyName("kind")]
|
||||
public required string Kind { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// RFC 8785 canonicalized JSON payload.
|
||||
/// </summary>
|
||||
[JsonPropertyName("payload")]
|
||||
public required string Payload { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// SHA-256 digest of Payload.
|
||||
/// </summary>
|
||||
[JsonPropertyName("payload_digest")]
|
||||
public required byte[] PayloadDigest { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Engine version for reproducibility.
|
||||
/// </summary>
|
||||
[JsonPropertyName("engine_version")]
|
||||
public required EngineVersionRef EngineVersion { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional DSSE signature.
|
||||
/// </summary>
|
||||
[JsonPropertyName("dsse_sig")]
|
||||
public string? DsseSig { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Schema version (current: 1).
|
||||
/// </summary>
|
||||
[JsonPropertyName("schema_version")]
|
||||
public int SchemaVersion { get; init; } = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Engine version reference for reproducibility tracking.
|
||||
/// </summary>
|
||||
/// <param name="EngineName">The name of the engine/service.</param>
|
||||
/// <param name="Version">The version string.</param>
|
||||
/// <param name="SourceDigest">SHA-256 digest of the source or assembly.</param>
|
||||
public sealed record EngineVersionRef(
|
||||
[property: JsonPropertyName("engine_name")] string EngineName,
|
||||
[property: JsonPropertyName("version")] string Version,
|
||||
[property: JsonPropertyName("source_digest")] string SourceDigest)
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an EngineVersionRef from the specified assembly metadata.
|
||||
/// </summary>
|
||||
public static EngineVersionRef FromAssembly(Assembly assembly)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(assembly);
|
||||
|
||||
var name = assembly.GetName();
|
||||
var version = name.Version?.ToString() ?? "0.0.0";
|
||||
|
||||
// Try to get source digest from assembly metadata
|
||||
var sourceDigest = assembly
|
||||
.GetCustomAttributes<AssemblyMetadataAttribute>()
|
||||
.FirstOrDefault(a => a.Key == "SourceDigest")?.Value
|
||||
?? "unknown";
|
||||
|
||||
return new EngineVersionRef(name.Name ?? "Unknown", version, sourceDigest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an EngineVersionRef from the entry assembly.
|
||||
/// </summary>
|
||||
public static EngineVersionRef FromEntryAssembly()
|
||||
{
|
||||
var assembly = Assembly.GetEntryAssembly()
|
||||
?? throw new InvalidOperationException("No entry assembly found");
|
||||
return FromAssembly(assembly);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pending event for batch emission.
|
||||
/// </summary>
|
||||
/// <param name="CorrelationId">Correlation ID linking related events.</param>
|
||||
/// <param name="Kind">Event kind (ENQUEUE, EXECUTE, etc.).</param>
|
||||
/// <param name="Payload">Event payload object.</param>
|
||||
public sealed record PendingEvent(
|
||||
string CorrelationId,
|
||||
string Kind,
|
||||
object Payload);
|
||||
|
||||
/// <summary>
|
||||
/// Standard event kinds used across StellaOps services.
|
||||
/// </summary>
|
||||
public static class EventKinds
|
||||
{
|
||||
// Scheduler events
|
||||
public const string Enqueue = "ENQUEUE";
|
||||
public const string Dequeue = "DEQUEUE";
|
||||
public const string Execute = "EXECUTE";
|
||||
public const string Complete = "COMPLETE";
|
||||
public const string Fail = "FAIL";
|
||||
|
||||
// AirGap events
|
||||
public const string Import = "IMPORT";
|
||||
public const string Export = "EXPORT";
|
||||
public const string Merge = "MERGE";
|
||||
public const string Conflict = "CONFLICT";
|
||||
|
||||
// Attestor events
|
||||
public const string Attest = "ATTEST";
|
||||
public const string Verify = "VERIFY";
|
||||
|
||||
// Policy events
|
||||
public const string Evaluate = "EVALUATE";
|
||||
public const string GatePass = "GATE_PASS";
|
||||
public const string GateFail = "GATE_FAIL";
|
||||
|
||||
// VexLens events
|
||||
public const string Consensus = "CONSENSUS";
|
||||
public const string Override = "OVERRIDE";
|
||||
|
||||
// Generic events
|
||||
public const string Emit = "EMIT";
|
||||
public const string Ack = "ACK";
|
||||
public const string Error = "ERR";
|
||||
}
|
||||
Reference in New Issue
Block a user