fix(codex): surface hook blocks and empty turns instead of silent idle - #81
Merged
Merged
Conversation
codex core silently ends a turn when a UserPromptSubmit/SessionStart hook blocks the prompt: turn/completed reports status=completed with no items, no error event, and the prompt never enters the native thread history. baton dropped hook/* notifications and treated the zero-output completion as a normal end_turn, so the user saw their message swallowed (incident bs_01KXCNW0WVA11NZH2F8FKTCJ5E, misread as "codex stuck"). - handle hook/completed: blocked/stopped userPromptSubmit/sessionStart hooks emit a warning _baton_notice with source path and block reason, and stash the reason on the active turn - finishTurn: a completed driven turn with zero visible output emits an empty-turn warning notice, attributed to the hook block when known; interrupted turns and pure-compaction turns are exempt - wire shapes verified against a live codex 0.144.1 app-server session (inject_items + turn/start repro also disproved the earlier theory that cross-provider context injection caused the empty turns)
Documents the normalization semantics introduced by the empty-turn fix: codex hook/completed notifications (blocked/stopped userPromptSubmit or sessionStart — the paths that make codex end a turn silently with the prompt never entering native history) and zero-output completed turns normalize to a warning _baton_notice; lifecycle is unchanged, terminal state still flows through state_update. Claude has no wire counterpart (in-process SDK hook failures surface on the error stream).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
codex core silently ends a turn when a UserPromptSubmit/SessionStart hook
blocks the prompt: turn/completed reports status=completed with no items,
no error event, and the prompt never enters the native thread history.
baton dropped hook/* notifications and treated the zero-output completion
as a normal end_turn, so the user saw their message swallowed
(incident bs_01KXCNW0WVA11NZH2F8FKTCJ5E, misread as "codex stuck").
hooks emit a warning _baton_notice with source path and block reason,
and stash the reason on the active turn
empty-turn warning notice, attributed to the hook block when known;
interrupted turns and pure-compaction turns are exempt
(inject_items + turn/start repro also disproved the earlier theory that
cross-provider context injection caused the empty turns)
Documents the normalization semantics introduced by the empty-turn fix:
codex hook/completed notifications (blocked/stopped userPromptSubmit or
sessionStart — the paths that make codex end a turn silently with the
prompt never entering native history) and zero-output completed turns
normalize to a warning _baton_notice; lifecycle is unchanged, terminal
state still flows through state_update. Claude has no wire counterpart
(in-process SDK hook failures surface on the error stream).