1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Span builders for the four CFA surfaces.
//!
//! Each builder returns a `tracing::Span` already populated with the
//! mandatory ADR-017 §4 attributes for that surface. The returned span has
//! NOT yet been entered — the caller is responsible for `.in_scope(|| ...)`
//! or `.entered()` so the span tree topology matches the actual control flow.
//!
//! Usage pattern from `crates/corp-finance-cli/src/main.rs` (illustrative):
//!
//! ```ignore
//! let span = corp_finance_core::observability::span_helpers::cli_span(&subcmd);
//! let _enter = span.entered();
//! dispatch_subcommand(subcmd, args)?;
//! // Span closes when `_enter` drops.
//! ```
//!
//! Every helper generates a fresh `Uuid::now_v7()` for `cfa.surface_event_id`.
//! This is the *event-instance* id (one per surface fire); it is distinct
//! from `SpanContext::run_id`, which is the *correlation* id assembled across
//! all surface events that share a single CFA run.
use crate;
use ;
use Uuid;
/// Create the root span for a CLI subcommand invocation.
///
/// Attributes set: `cfa.surface=cli`, `cfa.cli.subcommand=<subcommand>`,
/// `cfa.surface_event_id=<uuid-v7>`. The `cfa.tenant_id` and `cfa.run_id`
/// fields are declared but left empty so [`with_tenant`] / [`with_run_id`]
/// can populate them later in the same span without re-creating it.
/// Create the root span for an MCP `server.tool(...)` handler invocation.
///
/// Attributes set: `cfa.surface=mcp`, `cfa.mcp.tool=<tool_name>`,
/// `cfa.surface_event_id=<uuid-v7>`.
/// Create the root span for a plugin hook fire (Write / Edit / PreToolUse /
/// PostToolUse / PreMemoryWrite).
///
/// Attributes set: `cfa.surface=plugin`, `cfa.plugin.hook=<hook_name>`,
/// `cfa.surface_event_id=<uuid-v7>`.
/// Create the root span for a slash-command-driven skill invocation.
///
/// Attributes set: `cfa.surface=skill`, `cfa.skill.name=<skill_name>`,
/// `cfa.surface_event_id=<uuid-v7>`.
/// Attach `cfa.tenant_id` to an existing span. Returns the same span (the
/// `tracing` API mutates in place; the return is only for chaining
/// ergonomics).
///
/// ADR-017 §4 / RUF-OBS-003 require this value be redacted to
/// first-initial-last-name format BEFORE this helper is called. The helper
/// itself performs no transformation — redaction is the caller's
/// responsibility because the canonical "username -> redacted form"
/// algorithm depends on environment shape (USER vs FULL_NAME vs an LDAP
/// lookup) and does not belong in the span layer.
/// Attach `cfa.run_id` to an existing span. The run id is a uuid-v7 minted
/// at the root of a CFA run that may span multiple surface events (e.g., a
/// CLI subcommand that fans out to four MCP tool calls — all five spans
/// share one run id).