Skip to content

/goal-first sessions can still be omitted from codex resume when preview metadata stays empty #28263

Description

@favoyang

Summary

A Codex CLI session whose first interaction is /goal can still be omitted from the interactive codex resume list, even though the thread exists and can be resumed directly by ID.

This looks related to #20792, but the remaining failure is a writer-side gap: the existing fix lets resume/list metadata use a persisted ThreadGoalUpdated event as the preview, but the live app-server goal update path can notify the client without persisting that event to the rollout.

Steps to reproduce

  1. Use codex-cli 0.139.0 or a current main build.
  2. Start codex in a local project directory, for example /Users/alice/projects/codex.
  3. Make the first user interaction a /goal command. Example objective: echo 1,2,3 until 10.
  4. Let the goal complete.
  5. Quit the session. The CLI prints a direct resume hint such as codex resume <thread-id>.
  6. From the same project directory, run codex resume with no explicit thread ID.

Expected behavior

The goal-first session appears in the interactive resume list for the same cwd.

Actual behavior

The session can be missing from the interactive resume list, even though the thread row exists and has the expected cwd/source/provider/archive metadata. Direct resume by thread ID can still be available.

Investigation notes

I reproduced this on codex-cli 0.139.0. The affected thread had:

  • source = cli
  • model_provider = openai
  • cwd = /Users/alice/projects/codex
  • archived = 0
  • preview = ""
  • first_user_message = ""

The resume/list query excludes rows with an empty preview, so this thread is filtered out.

The corresponding rollout contained the session metadata and hidden goal context, but no durable EventMsg::ThreadGoalUpdated. That means the metadata sync path has no goal event to use as a preview later.

I checked the official refs:

  • origin/main at dfd03ea01bbec2613013b477fb82abc67534a7d7
  • rust-v0.139.0 at 7cadca4c6e8c821fa7b75b50006b1806ccebdf1c

Both have the same app-server listener behavior in codex-rs/app-server/src/request_processors/thread_lifecycle.rs: ThreadListenerCommand::EmitThreadGoalUpdated sends thread/goal/updated, but does not persist EventMsg::ThreadGoalUpdated into the rollout.

The earlier fix commit f10ddc3f13 (Use goal preview metadata for goal-first threads) is present, but it appears to cover the reader/indexing side. It does not cover this path where the goal event is never written.

Suspected fix

Persist EventMsg::ThreadGoalUpdated to the live thread rollout before/with the ordered thread/goal/updated notification. Then, even if the SQLite preview update happens before the thread metadata row exists, later rollout metadata sync can recover the preview from the persisted goal objective.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIapp-serverIssues involving app server protocol or interfacesbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions