machi_protocol/
observability.rs1pub const SPAN_SESSION: &str = "machi.session";
5pub const SPAN_TURN: &str = "machi.turn";
7pub const SPAN_SAMPLE: &str = "machi.sample";
9pub const SPAN_TOOL: &str = "machi.tool";
11pub const SPAN_TOOL_BATCH: &str = "machi.tool.batch";
13pub const SPAN_SPAWN: &str = "machi.spawn";
15pub const SPAN_WORKFLOW: &str = "machi.workflow";
17pub const SPAN_WORKFLOW_HOST: &str = "machi.workflow.host";
19pub const SPAN_COMPACT: &str = "machi.compact";
21
22pub mod field {
24 pub const SESSION_ID: &str = "machi.session_id";
26 pub const AGENT_ID: &str = "machi.agent_id";
28 pub const AGENT_NAME: &str = "machi.agent_name";
30 pub const RUN_ID: &str = "machi.run_id";
32 pub const STEP: &str = "machi.step";
34 pub const TOOL_NAME: &str = "machi.tool_name";
36 pub const MODEL: &str = "machi.model";
38 pub const USAGE_INPUT: &str = "machi.usage.input_tokens";
40 pub const USAGE_OUTPUT: &str = "machi.usage.output_tokens";
42 pub const WORKFLOW_RUN_ID: &str = "machi.workflow.run_id";
44 pub const WORKFLOW_SEQ: &str = "machi.workflow.seq";
46}
47
48#[must_use]
52pub fn required_span_names() -> &'static [&'static str] {
53 &[
54 SPAN_SESSION,
55 SPAN_TURN,
56 SPAN_SAMPLE,
57 SPAN_TOOL,
58 SPAN_TOOL_BATCH,
59 SPAN_SPAWN,
60 SPAN_WORKFLOW,
61 SPAN_WORKFLOW_HOST,
62 SPAN_COMPACT,
63 ]
64}
65
66#[must_use]
68pub fn span_catalogue_snapshot() -> String {
69 required_span_names().join("\n")
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 const SPAN_CATALOGUE_GOLDEN: &str = "\
77machi.session
78machi.turn
79machi.sample
80machi.tool
81machi.tool.batch
82machi.spawn
83machi.workflow
84machi.workflow.host
85machi.compact";
86
87 #[test]
88 fn span_names_are_machi_prefixed_and_unique() {
89 let names = required_span_names();
90 assert_eq!(names.len(), 9, "expected nine spans");
91 let mut seen = std::collections::BTreeSet::new();
92 for name in names {
93 assert!(
94 name.starts_with("machi."),
95 "span {name} must start with machi."
96 );
97 assert!(seen.insert(*name), "duplicate span {name}");
98 }
99 }
100
101 #[test]
102 fn span_catalogue_snapshot_matches_golden() {
103 assert_eq!(
104 span_catalogue_snapshot(),
105 SPAN_CATALOGUE_GOLDEN,
106 "span catalogue changed — update golden only with deliberate contract change"
107 );
108 }
109
110 #[test]
111 fn field_keys_are_stable() {
112 assert_eq!(field::SESSION_ID, "machi.session_id");
113 assert_eq!(field::TOOL_NAME, "machi.tool_name");
114 assert_eq!(field::WORKFLOW_SEQ, "machi.workflow.seq");
115 }
116}