Skip to main content

traverse_runtime/trace/
public.rs

1//! Public (CloudEvents-formatted) trace entry.
2
3use serde::{Deserialize, Serialize};
4use traverse_contracts::ViolationRecord;
5use traverse_registry::ModelResolutionEvidence;
6
7/// Outcome of a capability execution recorded in the public trace.
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9pub enum TraceOutcome {
10    /// The capability completed successfully.
11    Success,
12    /// The capability failed.
13    Failure,
14}
15
16/// A CloudEvents-formatted public trace entry.
17///
18/// Always logged and safe to share. Contains no raw inputs or outputs.
19#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
20pub struct PublicTraceEntry {
21    /// UUID v4 string identifying this trace.
22    pub id: String,
23    /// `CloudEvents` source: `traverse-runtime/<capability_id>`.
24    pub source: String,
25    /// `CloudEvents` type: `dev.traverse.execution.completed`.
26    pub event_type: String,
27    /// `CloudEvents` data content type: `application/json`.
28    pub datacontenttype: String,
29    /// RFC 3339 timestamp of when the trace was recorded.
30    pub time: String,
31    /// Identifier of the capability that was executed.
32    pub capability_id: String,
33    /// Placement target used during execution.
34    pub placement_target: String,
35    /// Whether the execution succeeded or failed.
36    pub outcome: TraceOutcome,
37    /// Wall-clock duration of the execution in milliseconds.
38    pub duration_ms: u64,
39    /// Aggregate contractual enforcement violations (if any).
40    #[serde(default, skip_serializing_if = "Vec::is_empty")]
41    pub violations: Vec<ViolationRecord>,
42    /// Non-sensitive governed model selection evidence, when inference was resolved.
43    #[serde(default, skip_serializing_if = "Vec::is_empty")]
44    pub model_resolution: Vec<ModelResolutionEvidence>,
45}
46
47impl PublicTraceEntry {
48    /// Creates a new [`PublicTraceEntry`].
49    #[must_use]
50    pub fn new(
51        id: String,
52        capability_id: String,
53        placement_target: String,
54        outcome: TraceOutcome,
55        duration_ms: u64,
56        time: String,
57    ) -> Self {
58        let source = format!("traverse-runtime/{capability_id}");
59        Self {
60            id,
61            source,
62            event_type: "dev.traverse.execution.completed".to_string(),
63            datacontenttype: "application/json".to_string(),
64            time,
65            capability_id,
66            placement_target,
67            outcome,
68            duration_ms,
69            violations: Vec::new(),
70            model_resolution: Vec::new(),
71        }
72    }
73}