CLI: background title generation emits legacy agent-turn-complete notifications
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Bug
Codex CLI 0.153.4 emits legacy agent-turn-complete notifications for its hidden task-title
generation thread as well as the visible user conversation. External consumers can therefore
receive a generated title as the answer, and prematurely mark the requested task complete.
Observed with the native TUI in tmux on Linux/WSL2, using agent-shell-py 0.4.0. A separate recorder
captured the raw notify arguments, confirming the extra event originates in Codex.
Reproduction
- Configure a per-invocation
notifycommand that appends its final JSON argument to a file. - Start a fresh native Codex conversation in an empty workspace.
- Ask:
Reply with exactly TEST_MARKER. Do not call tools, edit files, or run commands. - Keep the TUI running long enough for the background title request to complete.
- Inspect all notification records, rather than stopping after the first one.
The recorded reproduction used gpt-6-astra with high reasoning effort. The original failure
occurred during an integration test; later recorder runs confirmed both notification sources.
Actual behavior and evidence
An actual capture contained these two records (IDs shortened and workspace path omitted):
| Field | Visible conversation | Hidden title thread |
|---|---|---|
type |
agent-turn-complete |
agent-turn-complete |
client |
codex-tui |
codex-tui |
thread-id |
01a078ff-25d8-... |
01a078ff-354c-... |
last-assistant-message |
NOTIFY_ASTRA_88df63ec58 |
{"title":"Send NOTIFY_ASTRA_88df63ec58"} |
Both have the same cwd. The hidden thread's input-messages starts with
Generate a concise, single-line task title.... There is no explicit background/title source
field in the notification.
In that capture, the title notification followed the answer by 2.4 seconds. In an earlier failing
integration run, the first result consumed was {"title":"Reply with exact code"}, while the
visible root transcript contained the correct requested answer, LIVE_EMPTY_CODEX_926.
The consumed thread ID differed from the visible root ID. Raw notify records were not retained
for that earlier failure, so the later captures establish the dual emission directly.
This is a timing-dependent integration failure, not an incorrect answer from the visible model.
One of three initial integration runs returned the title; the other two returned the answer.
Expected behavior
Internal title-generation requests should not invoke the user's legacy completion notifier.
Alternatively, notifications need an explicit, documented origin discriminator so consumers can
reliably exclude internal auxiliary work. Filtering JSON shape or prompt wording is not robust:
a legitimate user request can ask for a title in JSON.
Suspected cause in version-matched source
- temporary_structured_request.rs, line 59
disables hooks and tools for temporary requests but leaves the inheritednotifycommand.
The temporary thread is also marked ephemeral with system feature provenance at lines 143–144. - registry.rs, line 113
registers the legacy notifier independently of the hooks feature switch. - thread_title.rs, line 70
starts the temporary title request.
A possible fix is to clear notify in temporary structured-request configuration, while retaining
it for the visible conversation. This is a source-based suggestion, not a tested patch.
Suggested regression: inherit a recording notifier, run a visible turn plus title generation,
and verify only the visible turn reaches the notifier, regardless of completion order.
No private project source, credentials, or full user transcripts are included in this report.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with codex-rs/tui/src/temporary_structured_request.rs and thread_title.rs, then inspect codex-rs/hooks/src/registry.rs to trace how the inherited notifier is registered. Add or run a regression covering a visible turn and title generation with a recording notifier. Done means only the visible turn invokes the legacy notifier, regardless of completion order.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100