[FEATURE] Session journal: local file sink for OTel events, with source-side privacy controls and a few missing events

Status Open
Maintainer reply None cached
Activity 2 comments · opened Sep 28, 2026

Re-filing #81701. The inactivity bot closed it after it had been triaged as area:core. Since then OpenTelemetry has gained most of the event content the original asked for, so this version is much narrower. #81701 has the full spec.

Problem Statement

A team wants a durable record of its Claude Code sessions: what was asked, which files changed, what a subagent concluded. The record should live next to the code, and it should not double as a log of anyone's working hours.

OTel now carries most of the content, opt-in: prompts (OTEL_LOG_USER_PROMPTS), file paths and Edit diffs (OTEL_LOG_TOOL_DETAILS), tool output (OTEL_LOG_TOOL_CONTENT), subagent attribution (agent_id, parent_agent_id), tool decisions and repository attributes. Three gaps remain:

  1. No local sink. The exporters are OTLP, Prometheus and console. Keeping a journal in the repo or a local file means running a collector, which is heavy for an individual developer or a small team.
  2. No source-side privacy. user.email and organization.id can't be turned off, timestamps are always full precision, and there's no pseudonymization. Attribution ("who changed this subsystem") and chronology ("when did this person work") are separate needs, and today they come as one package.
  3. A few missing events. The documented events include no commit sha (commits appear only in the claude_code.commit.count metric), no rewind or compaction event, and nothing for what a subagent returns to its parent. That makes it impossible to tie a change to history or to tell finished work from work that was undone.

Proposed Solution

Reuse the existing event schema and add a file sink, with privacy controls applied before anything is written:

{
  "journal": {
    "sink": ".claude/journal/",   // JSONL, one file per session, same schema as the OTel log events
    "identity": "author",         // author | pseudonymous | anonymous
    "timestamps": "day",          // full | day | none (order only)
    "content": "prompts"          // none | prompts | full
  }
}

Then add the missing events: commit sha, rewind, compaction and subagent result. It's off by default and needs no new data, since the client already holds every field.

Minimal version: the file sink with the identity and timestamps controls. Readable journals, session aggregates and hook access can be built on top of the JSONL by users.

Alternative Solutions

  • A local OTel collector with a file exporter. Works, but it's a service to install and configure on every machine, and redaction has to be rebuilt in collector config.
  • Parsing transcripts in ~/.claude/projects. An undocumented format that changes between releases. My own hook, work-audit, does this, and it covers roughly half of the original request.
  • Hooks. They see tool events, not the conversation.

Additional Context

Related: #95970 (which rule, hook or classifier decided a tool call), #89595 (session-finalization contract for audit integrations).

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗