// // SPDX-License-Identifier: BUSL-1.1 // using System.Text.Json.Serialization; namespace StellaOps.Signals.Ebpf.Schema; /// /// Event emitted when a function call is observed via eBPF. /// /// /// This record is the deserialized form of events from the eBPF ring buffer. /// The schema is designed for efficient serialization and deterministic ordering. /// public sealed record RuntimeCallEvent { /// /// Unique event identifier. /// public required Guid EventId { get; init; } /// /// Container ID where the call was observed. /// public required string ContainerId { get; init; } /// /// Process ID within the container. /// public required int Pid { get; init; } /// /// Thread ID. /// public required int Tid { get; init; } /// /// Timestamp in nanoseconds since boot. /// public required ulong TimestampNs { get; init; } /// /// Called function symbol name (if resolved). /// public string? Symbol { get; init; } /// /// Called function address. /// public required ulong FunctionAddress { get; init; } /// /// Call stack (addresses from bottom to top). /// public required IReadOnlyList StackTrace { get; init; } /// /// Runtime type (native, jvm, node, python, dotnet, go). /// public required RuntimeType RuntimeType { get; init; } /// /// Library/module containing the function. /// public string? Library { get; init; } /// /// Package URL if resolvable. /// public string? Purl { get; init; } /// /// UTC timestamp when this event was received by the collector. /// public DateTimeOffset ReceivedAt { get; init; } = DateTimeOffset.UtcNow; // --- Sprint: SPRINT_20260112_005_SIGNALS_runtime_nodehash (PW-SIG-001) --- /// /// Fully qualified function signature (namespace.type.method(params)). /// public string? FunctionSignature { get; init; } /// /// SHA256 digest of the binary containing this function. /// public string? BinaryDigest { get; init; } /// /// Offset within the binary where the function is located. /// public ulong? BinaryOffset { get; init; } /// /// Canonical node hash (sha256:hex) for static/runtime evidence joining. /// Computed using NodeHashRecipe from PURL + FunctionSignature. /// public string? NodeHash { get; init; } /// /// SHA256 hash of the callstack for deterministic aggregation. /// public string? CallstackHash { get; init; } } /// /// Runtime type detected from process characteristics. /// [JsonConverter(typeof(JsonStringEnumConverter))] public enum RuntimeType { /// Native binary (ELF/PE/Mach-O). Native = 0, /// Java Virtual Machine. Jvm = 1, /// Node.js / V8. Node = 2, /// Python interpreter. Python = 3, /// .NET runtime (CoreCLR). DotNet = 4, /// Go runtime. Go = 5, /// Ruby interpreter. Ruby = 6, /// Unknown or unidentified runtime. Unknown = 255, } /// /// Observed call path from runtime signals. /// public sealed record ObservedCallPath { /// /// Symbols in the call path (entry point to vulnerable function). /// public required IReadOnlyList Symbols { get; init; } /// /// Number of times this path was observed. /// public required int ObservationCount { get; init; } /// /// Package URL if resolvable. /// public string? Purl { get; init; } /// /// Runtime type where this path was observed. /// public RuntimeType RuntimeType { get; init; } = RuntimeType.Unknown; /// /// First observation timestamp. /// public DateTimeOffset FirstObservedAt { get; init; } /// /// Last observation timestamp. /// public DateTimeOffset LastObservedAt { get; init; } // --- Sprint: SPRINT_20260112_005_SIGNALS_runtime_nodehash (PW-SIG-001) --- /// /// Canonical node hashes for each symbol in the path (deterministic order). /// public IReadOnlyList? NodeHashes { get; init; } /// /// Canonical path hash (sha256:hex) computed from ordered node hashes. /// public string? PathHash { get; init; } /// /// Callstack hash for efficient deduplication. /// public string? CallstackHash { get; init; } /// /// Function signatures for each symbol in the path. /// public IReadOnlyList? FunctionSignatures { get; init; } /// /// Binary digests for each symbol in the path (null if not resolvable). /// public IReadOnlyList? BinaryDigests { get; init; } /// /// Binary offsets for each symbol in the path (null if not resolvable). /// public IReadOnlyList? BinaryOffsets { get; init; } } /// /// Summary of runtime signals collected for a container. /// public sealed record RuntimeSignalSummary { /// /// Container ID. /// public required string ContainerId { get; init; } /// /// When signal collection started. /// public required DateTimeOffset StartedAt { get; init; } /// /// When signal collection stopped. /// public required DateTimeOffset StoppedAt { get; init; } /// /// Total events captured. /// public required long TotalEvents { get; init; } /// /// Aggregated call paths. /// public required IReadOnlyList CallPaths { get; init; } /// /// Unique symbols observed. /// public required IReadOnlyList ObservedSymbols { get; init; } /// /// Events that were dropped due to rate limiting. /// public long DroppedEvents { get; init; } /// /// Runtime types detected in this container. /// public IReadOnlyList DetectedRuntimes { get; init; } = []; // --- Sprint: SPRINT_20260112_005_SIGNALS_runtime_nodehash (PW-SIG-004) --- /// /// Unique node hashes observed in this summary (deterministic sorted order). /// public IReadOnlyList? ObservedNodeHashes { get; init; } /// /// Unique path hashes for all observed call paths (deterministic sorted order). /// public IReadOnlyList? ObservedPathHashes { get; init; } /// /// Combined hash of all observed paths for summary-level identity. /// public string? CombinedPathHash { get; init; } } /// /// Statistics about signal collection. /// public sealed record SignalStatistics { /// /// Total events received. /// public required long TotalEvents { get; init; } /// /// Events per second (current rate). /// public required double EventsPerSecond { get; init; } /// /// Unique call paths observed. /// public required int UniqueCallPaths { get; init; } /// /// Ring buffer utilization percentage. /// public required double BufferUtilization { get; init; } /// /// Events dropped due to rate limiting. /// public required long DroppedEvents { get; init; } /// /// CPU overhead percentage from eBPF probes. /// public double CpuOverheadPercent { get; init; } /// /// Memory usage in bytes for signal collection. /// public long MemoryUsageBytes { get; init; } }