55
66A "Run" is orthogonal to tracing:
77- Trace context (W3C): ties distributed spans together (trace_id, span_id)
8- - Run context (Botanu): ties business execution together (run_id, use_case , outcome)
8+ - Run context (Botanu): ties business execution together (run_id, workflow , outcome)
99
1010Invariant: A run can span multiple traces (retries, async fanout).
1111The run_id must remain stable across those boundaries.
@@ -85,9 +85,10 @@ class RunContext:
8585 """
8686
8787 run_id : str
88- use_case : str
88+ workflow : str
89+ event_id : str
90+ customer_id : str
8991 environment : str
90- workflow : Optional [str ] = None
9192 workflow_version : Optional [str ] = None
9293 tenant_id : Optional [str ] = None
9394 parent_run_id : Optional [str ] = None
@@ -111,8 +112,9 @@ def __post_init__(self) -> None:
111112 @classmethod
112113 def create (
113114 cls ,
114- use_case : str ,
115- workflow : Optional [str ] = None ,
115+ workflow : str ,
116+ event_id : str ,
117+ customer_id : str ,
116118 workflow_version : Optional [str ] = None ,
117119 environment : Optional [str ] = None ,
118120 tenant_id : Optional [str ] = None ,
@@ -131,9 +133,10 @@ def create(
131133
132134 return cls (
133135 run_id = run_id ,
134- use_case = use_case ,
135- environment = env ,
136136 workflow = workflow ,
137+ event_id = event_id ,
138+ customer_id = customer_id ,
139+ environment = env ,
137140 workflow_version = workflow_version ,
138141 tenant_id = tenant_id ,
139142 parent_run_id = parent_run_id ,
@@ -147,8 +150,9 @@ def create(
147150 def create_retry (cls , previous : RunContext ) -> RunContext :
148151 """Create a new RunContext for a retry attempt."""
149152 return cls .create (
150- use_case = previous .use_case ,
151153 workflow = previous .workflow ,
154+ event_id = previous .event_id ,
155+ customer_id = previous .customer_id ,
152156 workflow_version = previous .workflow_version ,
153157 environment = previous .environment ,
154158 tenant_id = previous .tenant_id ,
@@ -215,14 +219,14 @@ def to_baggage_dict(self, lean_mode: Optional[bool] = None) -> Dict[str, str]:
215219
216220 baggage : Dict [str , str ] = {
217221 "botanu.run_id" : self .run_id ,
218- "botanu.use_case" : self .use_case ,
222+ "botanu.workflow" : self .workflow ,
223+ "botanu.event_id" : self .event_id ,
224+ "botanu.customer_id" : self .customer_id ,
219225 }
220226 if lean_mode :
221227 return baggage
222228
223229 baggage ["botanu.environment" ] = self .environment
224- if self .workflow :
225- baggage ["botanu.workflow" ] = self .workflow
226230 if self .tenant_id :
227231 baggage ["botanu.tenant_id" ] = self .tenant_id
228232 if self .parent_run_id :
@@ -243,12 +247,12 @@ def to_span_attributes(self) -> Dict[str, Union[str, float, int, bool]]:
243247 """Convert to dict for span attributes."""
244248 attrs : Dict [str , Union [str , float , int , bool ]] = {
245249 "botanu.run_id" : self .run_id ,
246- "botanu.use_case" : self .use_case ,
250+ "botanu.workflow" : self .workflow ,
251+ "botanu.event_id" : self .event_id ,
252+ "botanu.customer_id" : self .customer_id ,
247253 "botanu.environment" : self .environment ,
248254 "botanu.run.start_time" : self .start_time .isoformat (),
249255 }
250- if self .workflow :
251- attrs ["botanu.workflow" ] = self .workflow
252256 if self .workflow_version :
253257 attrs ["botanu.workflow.version" ] = self .workflow_version
254258 if self .tenant_id :
@@ -285,8 +289,8 @@ def to_span_attributes(self) -> Dict[str, Union[str, float, int, bool]]:
285289 def from_baggage (cls , baggage : Dict [str , str ]) -> Optional [RunContext ]:
286290 """Reconstruct RunContext from baggage dict."""
287291 run_id = baggage .get ("botanu.run_id" )
288- use_case = baggage .get ("botanu.use_case " )
289- if not run_id or not use_case :
292+ workflow = baggage .get ("botanu.workflow " )
293+ if not run_id or not workflow :
290294 return None
291295
292296 attempt_str = baggage .get ("botanu.attempt" , "1" )
@@ -305,11 +309,15 @@ def from_baggage(cls, baggage: Dict[str, str]) -> Optional[RunContext]:
305309
306310 cancelled = baggage .get ("botanu.cancelled" , "" ).lower () == "true"
307311
312+ event_id = baggage .get ("botanu.event_id" , "" )
313+ customer_id = baggage .get ("botanu.customer_id" , "" )
314+
308315 return cls (
309316 run_id = run_id ,
310- use_case = use_case ,
317+ workflow = workflow ,
318+ event_id = event_id ,
319+ customer_id = customer_id ,
311320 environment = baggage .get ("botanu.environment" , "unknown" ),
312- workflow = baggage .get ("botanu.workflow" ),
313321 tenant_id = baggage .get ("botanu.tenant_id" ),
314322 parent_run_id = baggage .get ("botanu.parent_run_id" ),
315323 root_run_id = baggage .get ("botanu.root_run_id" ) or run_id ,
0 commit comments