entrenar/monitor/inference/provenance/node.rs
1//! Provenance node types for incident reconstruction.
2
3use serde::{Deserialize, Serialize};
4
5/// Unique identifier for a node in the provenance graph
6pub type NodeId = u64;
7
8/// Provenance graph node types
9#[derive(Clone, Debug, Serialize, Deserialize)]
10pub enum ProvenanceNode {
11 /// Raw sensor/input data
12 Input {
13 /// Source identifier
14 source: String,
15 /// Timestamp in nanoseconds
16 timestamp_ns: u64,
17 /// Hash of the input data
18 hash: u64,
19 },
20
21 /// Preprocessing transformation
22 Transform {
23 /// Operation name
24 operation: String,
25 /// References to input nodes
26 input_refs: Vec<NodeId>,
27 },
28
29 /// Model inference
30 Inference {
31 /// Model identifier
32 model_id: String,
33 /// Model version
34 model_version: String,
35 /// Confidence of the inference
36 confidence: f32,
37 /// Output value
38 output: f32,
39 },
40
41 /// Post-processing or sensor fusion
42 Fusion {
43 /// Fusion strategy
44 strategy: String,
45 /// References to input nodes
46 input_refs: Vec<NodeId>,
47 },
48
49 /// Final action/output
50 Action {
51 /// Action type
52 action_type: String,
53 /// Confidence
54 confidence: f32,
55 /// Alternatives considered
56 alternatives: Vec<(String, f32)>,
57 },
58}
59
60impl ProvenanceNode {
61 /// Get the timestamp if available
62 pub fn timestamp_ns(&self) -> Option<u64> {
63 match self {
64 ProvenanceNode::Input { timestamp_ns, .. } => Some(*timestamp_ns),
65 _ => None,
66 }
67 }
68
69 /// Get node type as string
70 pub fn type_name(&self) -> &'static str {
71 match self {
72 ProvenanceNode::Input { .. } => "Input",
73 ProvenanceNode::Transform { .. } => "Transform",
74 ProvenanceNode::Inference { .. } => "Inference",
75 ProvenanceNode::Fusion { .. } => "Fusion",
76 ProvenanceNode::Action { .. } => "Action",
77 }
78 }
79}