You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Claude Code emits a well-specified OpenTelemetry stream that overlaps the hook tier and, on two fields, beats it. Rather than treat it as a competitor, ingest it as a third capture tier alongside IDE hooks and tools/mcp_audit_proxy.py.
Why
Two fields in the OTel stream are strictly better than what the hook tier produces today:
claude_code.tool_decision.source carries the observed provenance of a permission decision: config, hook, user_permanent, user_temporary, user_reject, user_abort. Agentmetry reconstructs this from timing and marks it inferred:tool_ran_after_ask, which the README correctly says must never be cited as a human decision. The telemetry observes what we guess.
An OTLP receiver that normalises into the existing canonical schema, so nothing downstream changes:
Hash chain, MITRE/ATLAS mapping, sequence rules and SIEM forwarders all operate on canonical events and should need no modification. Normalisation happens before detection, not inside it.
session.id maps to session_id; prompt.id is a correlation key within one agent and does not correlate across two, so correlation_id still has to be derived the way it is today.
Claude Code events land in the same local trail as Cursor and Codex events, which is the cross-agent correlation OTel cannot do by itself.
Where OTel and a hook both describe the same tool call, the observed tool_decision should win over the inferred approval and the inferred: marker should drop for that half of the trail. Dedup strategy needs deciding: see the batch dedup already in core/audit/ingest.py.
Open questions
Do the existing 15 rules actually fire unmodified on normalised OTel events? This is the assumption the whole design rests on and it is untested.
OTEL_LOG_TOOL_DETAILS is off by default. Without it there is no command string, so most command-shaped traits and therefore most sequence rules cannot fire. Is a tier that degrades to tool_name only worth shipping, and how should agentmetry doctor report that state?
Receiver transport: OTLP gRPC on loopback, or tail a file the collector writes? Loopback receiver is more work and avoids depending on a collector being configured.
Managed settings lock the OTLP destination. If an admin has pointed it at a central collector, can Agentmetry also receive locally, or does this only work where we own the endpoint config?
Not in scope
Emitting OTLP out of Agentmetry. That is the separate OTLP export item already on the roadmap.
Context
Reasoning written up in ai-audit-watch post why-not-just-opentelemetry, which links here for status and explicitly says this is a plan and not a release.
Claude Code emits a well-specified OpenTelemetry stream that overlaps the hook tier and, on two fields, beats it. Rather than treat it as a competitor, ingest it as a third capture tier alongside IDE hooks and
tools/mcp_audit_proxy.py.Why
Two fields in the OTel stream are strictly better than what the hook tier produces today:
claude_code.tool_decision.sourcecarries the observed provenance of a permission decision:config,hook,user_permanent,user_temporary,user_reject,user_abort. Agentmetry reconstructs this from timing and marks itinferred:tool_ran_after_ask, which the README correctly says must never be cited as a human decision. The telemetry observes what we guess.claude_code.tool_result.tool_result_size_bytesis the how-much-data-moved number tracked in Tool responses are not recorded, so the trail cannot see how much data moved #45.Everything else in the stream (
mcp_server_connection,permission_mode_changed,api_request,auth,internal_error) is additive rather than competing.Spec: https://code.claude.com/docs/en/monitoring-usage
Shape
An OTLP receiver that normalises into the existing canonical schema, so nothing downstream changes:
session.idmaps tosession_id;prompt.idis a correlation key within one agent and does not correlate across two, socorrelation_idstill has to be derived the way it is today.tool_decisionshould win over the inferred approval and theinferred:marker should drop for that half of the trail. Dedup strategy needs deciding: see the batch dedup already incore/audit/ingest.py.Open questions
OTEL_LOG_TOOL_DETAILSis off by default. Without it there is no command string, so most command-shaped traits and therefore most sequence rules cannot fire. Is a tier that degrades totool_nameonly worth shipping, and how shouldagentmetry doctorreport that state?Not in scope
Emitting OTLP out of Agentmetry. That is the separate OTLP export item already on the roadmap.
Context
Reasoning written up in
ai-audit-watchpostwhy-not-just-opentelemetry, which links here for status and explicitly says this is a plan and not a release.