Auto-review guardian turns fire UserPromptSubmit without matching subagent lifecycle hooks
What version of Codex CLI is running?
codex-cli 0.149.1
The same behavior first appears in local rollout data produced by 0.147.0.
What subscription do you have?
Pro
Which model were you using?
- Parent turn:
gpt-5.6-sol - Internal reviewer turn:
codex-auto-review
What platform is your computer?
Darwin 25.6.0 arm64 arm
What terminal emulator and version are you using (if applicable)?
iTerm2 3.6.11
Codex doctor report
Redacted relevant excerpt. The full report contains unrelated local paths and sandbox-only network diagnostics.
{
"schemaVersion": 1,
"codexVersion": "0.149.1",
"runtime": {
"platform": "macos-aarch64",
"installMethod": "standalone"
},
"config": {
"hooks": true,
"guardianApproval": true,
"approvalPolicy": "OnRequest"
}
}
What issue are you seeing?
With approvals_reviewer = "auto_review", every permission review starts an internal guardian turn. User-configured hooks receive a UserPromptSubmit event for that hidden reviewer turn, but receive no matching SubagentStart, SubagentStop, or Stop event.
The observed start event has this shape, with identifiers redacted:
{
"hook_event_name": "UserPromptSubmit",
"model": "codex-auto-review",
"session_id": "<parent-session-id>",
"turn_id": "<guardian-turn-id>",
"agent_id": null
}
The guardian's separate rollout confirms that the turn is a subagent and completes normally:
{"type":"session_meta","payload":{"session_id":"<parent-session-id>","source":{"subagent":{"other":"guardian"}},"thread_source":"subagent"}}
{"type":"event_msg","payload":{"type":"task_started","turn_id":"<guardian-turn-id>"}}
{"type":"event_msg","payload":{"type":"task_complete","turn_id":"<guardian-turn-id>"}}
No terminal hook is emitted for <guardian-turn-id>, even though task_complete is present in the rollout. This occurs in the interactive TUI (originator = "codex-tui"), not in codex exec.
The imbalance is large because one reviewer turn is created per permission request. In a sanitized local sample from August 17 through August 26:
- 520 unique
codex-auto-reviewUserPromptSubmitturns were emitted - 0 of those turns had a matching
StoporSubagentStop - In an August 26 snapshot, 59 reviewer turns had no terminal hook, while all 3 completed user-facing turns had matching
Stopevents; the fourth user-facing turn was still active
There was exactly one configured handler for each event, so this was not caused by duplicate hook configuration.
This leaves hook-based task status and analytics integrations with hundreds of phantom running tasks. Filtering on the internal model slug is possible, but it relies on an undocumented implementation detail and can break when the reviewer model changes.
What steps can reproduce the bug?
- Configure Auto Review:
approval_policy = "on-request"
approvals_reviewer = "auto_review"
sandbox_mode = "workspace-write"
- Configure the same append-only logger for
PermissionRequest,UserPromptSubmit,SubagentStart,SubagentStop, andStop:
{
"hooks": {
"PermissionRequest": [{"hooks":[{"type":"command","command":"tee -a /tmp/codex-hook-events.jsonl >/dev/null"}]}],
"UserPromptSubmit": [{"hooks":[{"type":"command","command":"tee -a /tmp/codex-hook-events.jsonl >/dev/null"}]}],
"SubagentStart": [{"hooks":[{"type":"command","command":"tee -a /tmp/codex-hook-events.jsonl >/dev/null"}]}],
"SubagentStop": [{"hooks":[{"type":"command","command":"tee -a /tmp/codex-hook-events.jsonl >/dev/null"}]}],
"Stop": [{"hooks":[{"type":"command","command":"tee -a /tmp/codex-hook-events.jsonl >/dev/null"}]}]
}
}
- Start the interactive
codexTUI and ask it to perform an operation that produces aPermissionRequest. - Let Auto Review approve or deny the request.
- Inspect
/tmp/codex-hook-events.jsonland the guardian rollout under~/.codex/sessions/. - Observe a
UserPromptSubmitformodel = "codex-auto-review"and a completed guardian rollout, but no matching subagent or stop lifecycle hook.
What is the expected behavior?
Internal Auto Review turns should either:
- Not fire user-facing
UserPromptSubmithooks; or - Emit balanced
SubagentStartandSubagentStopevents with stableagent_id/agent_typefields; or - Include a documented, stable internal-task discriminator and a corresponding terminal event.
The documented hook lifecycle says subagents use SubagentStart and SubagentStop, while Stop represents a main turn. Hook consumers should not need to infer internal reviewer identity from model = "codex-auto-review".
Documentation: https://developers.openai.com/codex/hooks
Additional information
Related but distinct reports:
- #33229 reports internal ChatGPT Desktop background tasks triggering user hooks. In this report, the internal task is specifically the Auto Review guardian, it has a persisted subagent rollout, and that rollout contains
task_complete. - #18607 reports missing terminal hooks in
codex exec. This report reproduces in the interactive TUI.
Guardian rollouts existed locally before this imbalance began. The first unbalanced guardian UserPromptSubmit was observed on August 17, while samples before and after that point both report CLI 0.147.0, so the local evidence does not establish a CLI-version transition as the trigger.