Native OTel export omits originating-thread context for side conversations and title-generation helpers

Open
#34,884 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
rust
Domain
observability

Research direction

Start with fork_side_thread in codex-rs/tui/src/app_server_session.rs, the fork handling in codex-rs/core/src/thread_manager.rs, and SessionTelemetryMetadata and conversation_starts in codex-rs/otel/src/events/session_telemetry.rs. Read the thread/name/set request and app-server tracing paths next. Done means native OTel logs and traces deterministically identify each derived conversation's originating thread and purpose without exporting prompt content or adding thread IDs to metrics.

Written by the indexing model from the issue text.

Description

app app-server bug
What issue are you seeing?

Native OTel logs and traces represent some Codex-created derived conversations as unrelated root conversations, even though the relevant lineage or purpose context is available in Codex before the telemetry export boundary.

This currently has at least two manifestations.

1. Side conversations

The open-source side-conversation path explicitly knows that it is creating a side conversation:

  • fork_side_thread selects ForkPresentation::SideConversation.
  • It calls thread/fork with the source thread ID.
  • Core derives source_thread_id and passes it as forked_from_thread_id.
  • The app-server Thread response exposes the relationship as forkedFromId.

However, native OTel events for the derived conversation expose only that conversation's own conversation.id. SessionTelemetryMetadata and codex.conversation_starts do not carry forked_from_thread_id, parent_thread_id, thread_source, or an equivalent derived-conversation purpose.

The side-conversation path also currently passes ThreadSource::User, so its purpose is not preserved as a distinct thread source even before OTel export.

As a result, an OTLP consumer cannot determine that conversation B is a side conversation forked from visible conversation A.

2. Title-generation helper conversations

This manifestation was previously reported in openai/codex#32708.

A title-generation helper receives its own conversation.id. The target visible thread ID is known when the generated name is applied through thread/name/set, whose public request type contains thread_id.

However:

  • The helper's native OTel events do not identify its purpose as title generation.
  • They do not identify the visible thread for which the title is being generated.
  • The app_server.request span records the RPC method and request ID, but not the target thread_id.

Therefore, the helper conversation cannot be deterministically correlated with the visible thread whose title it generated.

These are different creation paths, but they expose the same native OTel contract gap: Codex has the relevant derived-conversation context before export, but that context is not carried across the OTLP telemetry boundary.

This causes downstream observability systems to count side conversations and title-generation helpers as independent root sessions or leave them unattributed. Timestamp-, model-, prompt-, and ephemeral-state heuristics are not deterministic.

This report is not requesting high-cardinality thread IDs in OTel metrics. The relationship is needed in logs and traces only.

What steps can reproduce the bug?
Side conversation
  1. Configure Codex native OTel log and trace exporters. Keep otel.log_user_prompt = false.
  2. Start a regular conversation A.
  3. Open a side conversation from A and send a message, creating conversation B.
  4. Inspect codex.conversation_starts and the trace-safe events for B.
  5. Compare them with the fork information available through the app-server thread model.

Actual result:

  • B has its own conversation.id.
  • The app-server/core path retains A as the fork source.
  • Native OTel does not emit the relationship from B to A.
  • Native OTel does not identify B as a side conversation.
Title generation
  1. Start a new conversation in the Codex App.
  2. Wait for automatic title generation.
  3. Inspect native OTel events for the helper conversation and the thread/name/set request span.
  4. Attempt to determine which visible conversation received the generated title.

Actual result:

  • The helper has its own conversation.id.
  • Neither the helper events nor the request span provide a stable helper-to-visible-thread relationship.
  • The helper is not identified with a title-generation purpose.
What is the expected behavior?

Native OTel logs and traces should preserve enough context to classify a derived conversation and correlate it with its originating thread.

For example:

  • forked_from_thread_id or originating_thread_id
  • thread_source = "side_conversation" for side conversations
  • thread_source = "title_generation" for title-generation helpers

The exact field names are flexible. The important requirements are:

  • The derived conversation keeps its own conversation.id.
  • Its originating visible thread can be identified deterministically.
  • Its purpose can be distinguished from ordinary user-created root conversations.
  • The relationship remains available with otel.log_user_prompt = false.
  • No prompt text, generated title, or other user content needs to be exported.
  • Per-thread IDs do not need to be added to metrics.
Additional information

Environment available for reproduction:

  • Codex App: 26.715.10079.0
  • Platform: Microsoft Windows NT 10.0.26200.0 x64
  • Source snapshot inspected: openai/codex@4e0cee8030c4833baa6331b378101545accc9956

Relevant source evidence:

Related issue:

Dominant language
Rust
Stars
125k
Forks
19.5k
Avg merge
1m
Merged PRs (30d)
1k

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.