[FEATURE] Include current git branch (vcs.ref.head.name) on all OTel events
Context: Claude Code v2.1.269 addedvcs.repository.*attributes behindOTEL_METRICS_INCLUDE_REPOSITORY, andvcs.ref.head.*attributes ontool_resultevents forgit commit. This request builds on both: put the branch on every event, not just commits.
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
We run Claude Code for ~100 developers with telemetry exported via OTel into our data platform. We need to attribute sessions, cost and activity to the piece of work being done, not just the repository.
OTEL_METRICS_INCLUDE_REPOSITORY=true gives us the repo, which is a great start. But a busy repo has dozens of concurrent branches, and the branch is what maps to a ticket or feature in our workflow. Today the branch only appears on tool_result events for successful git commit calls (with OTEL_LOG_TOOL_DETAILS=1), so sessions that don't commit, and all the work before a commit, can't be attributed to a branch.
Proposed Solution
When OTEL_METRICS_INCLUDE_REPOSITORY=true (or a new opt-in flag such as OTEL_METRICS_INCLUDE_VCS_REF=true), add vcs.ref.head.name to every event, reflecting the branch at the time the event was emitted. Omit it on detached HEAD, and optionally include vcs.ref.head.revision.
This follows the OTel VCS semantic conventions Claude Code already uses for vcs.repository.*. To avoid cardinality problems in Prometheus-style backends, keep it off metric datapoints by default or put that behind its own flag.
Alternative Solutions
- Launch wrapper setting
OTEL_RESOURCE_ATTRIBUTES: only captures the branch at startup, goes stale aftergit switchor worktree changes, and misses IDE and desktop launches. - Hook that runs git and sends its own record: works, but needs a separate ingestion path and a timestamp-based join, since hooks don't receive the OTel exporter config.
- Shipping a projection of the session transcript via a Stop hook: transcripts already record
gitBranchper message, and we can join onmessage.uuid. This is the most accurate option, but it depends on an internal file format the docs say can change between versions. otelHeadersHelperplus collector enrichment: per export batch rather than per event, and doesn't follow the session's working directory.
Priority
Medium - Would be very helpful
Feature Category
Other
Use Case Example
- A developer starts Claude Code in a repo on branch
feature/PROJ-1234-new-ingestion. - They work for an hour across several prompts, then switch to
bugfix/PROJ-1250partway through to fix something urgent, without restarting the session. - In our data platform we query
claude_code.api_requestevents grouped byvcs.repository.nameandvcs.ref.head.name, and extract the ticket ID from the branch name. - That gives us cost and token usage per ticket, correctly split across both pieces of work, which we report back to teams and use for AI spend governance.
Today step 3 isn't possible without one of the workarounds above.
Additional Context
- The data already exists: session transcripts record
gitBranchper message, so this is about surfacing it in telemetry rather than collecting something new. - A repo-relative working directory (e.g.
vcs.repository.path) would be a useful companion for monorepos, but it should be relative to the repo root so home directories and usernames aren't exposed. - Not a duplicate of #29826: #31300 asked for per-event branch attributes and was auto-closed as a duplicate of #29826, but that issue only covered repo org/name, which has since shipped as
OTEL_METRICS_INCLUDE_REPOSITORY. Both are locked, so this is the follow-up the bot asked for. - Docs reference: https://code.claude.com/docs/en/monitoring-usage#repository-attributes