using System; using System.Collections.Generic; namespace StellaOps.Signals.Models; public sealed class ReachabilityFactDocument { public string Id { get; set; } = Guid.NewGuid().ToString("N"); public string CallgraphId { get; set; } = string.Empty; public ReachabilitySubject Subject { get; set; } = new(); public List EntryPoints { get; set; } = new(); public List States { get; set; } = new(); public List? RuntimeFacts { get; set; } /// /// CAS URI for the runtime-facts batch artifact (cas://reachability/runtime-facts/{hash}). /// public string? RuntimeFactsBatchUri { get; set; } /// /// BLAKE3 hash of the runtime-facts batch artifact. /// public string? RuntimeFactsBatchHash { get; set; } public Dictionary? Metadata { get; set; } public ContextFacts? ContextFacts { get; set; } public UncertaintyDocument? Uncertainty { get; set; } /// /// Edge bundles attached to this graph. /// public List? EdgeBundles { get; set; } /// /// Whether any edges are quarantined (revoked) for this fact. /// public bool HasQuarantinedEdges { get; set; } public double Score { get; set; } public double RiskScore { get; set; } public int UnknownsCount { get; set; } public double UnknownsPressure { get; set; } public DateTimeOffset ComputedAt { get; set; } public string SubjectKey { get; set; } = string.Empty; } public sealed class ReachabilityStateDocument { public string Target { get; set; } = string.Empty; public bool Reachable { get; set; } public double Confidence { get; set; } public string Bucket { get; set; } = "unknown"; /// /// v1 lattice state code (U, SR, SU, RO, RU, CR, CU, X). /// public string? LatticeState { get; set; } /// /// Previous lattice state before this transition (for audit trail). /// public string? PreviousLatticeState { get; set; } public double Weight { get; set; } public double Score { get; set; } public List Path { get; set; } = new(); public ReachabilityEvidenceDocument Evidence { get; set; } = new(); /// /// Timestamp of the last lattice state transition. /// public DateTimeOffset? LatticeTransitionAt { get; set; } } public sealed class ReachabilityEvidenceDocument { public List RuntimeHits { get; set; } = new(); public List? BlockedEdges { get; set; } /// /// Combined gate multiplier in basis points (10000 = 100%). /// public int GateMultiplierBps { get; set; } = 10000; /// /// Gates detected on the computed path to the target (if any). /// public List? Gates { get; set; } } public sealed class ReachabilitySubject { public string? ImageDigest { get; set; } public string? Component { get; set; } public string? Version { get; set; } public string? ScanId { get; set; } public string ToSubjectKey() { if (!string.IsNullOrWhiteSpace(ScanId)) { return ScanId!; } if (!string.IsNullOrWhiteSpace(ImageDigest)) { return ImageDigest!; } return string.Join('|', Component ?? string.Empty, Version ?? string.Empty).Trim('|'); } } public sealed class RuntimeFactDocument { public string SymbolId { get; set; } = string.Empty; public string? CodeId { get; set; } public string? SymbolDigest { get; set; } public string? Purl { get; set; } public string? BuildId { get; set; } public string? LoaderBase { get; set; } public int? ProcessId { get; set; } public string? ProcessName { get; set; } public string? SocketAddress { get; set; } public string? ContainerId { get; set; } public string? EvidenceUri { get; set; } public int HitCount { get; set; } public DateTimeOffset? ObservedAt { get; set; } public Dictionary? Metadata { get; set; } }