A Stop hook can block completion and still fail to keep the workflow moving.

One Codex issue recorded exactly that. The Hook returned decision: "block", normal completion was stopped, and Codex emitted a continuation prompt asking the agent to fix failing lint, type or test checks. The next Responses API request failed because it carried an invalid locally generated message id.[3]

The failure happened after the Hook had fired. The issue therefore shows a broken continuation path, not a missing Stop trigger.

When OpenAI moved Hooks to general availability, it described uses such as scanning prompts for secrets, running validators, logging conversations, creating memories and customising Codex behaviour for particular repositories or directories.[1][2] Each of those behaviours depends on a lifecycle event being emitted before the configured Hook can run.

A Stop Hook turns validation into a lifecycle control point

The event path sets the limit

Once the runtime emits the relevant Stop event, the configured Hook has a defined handling point. A blocking result can stop normal completion and return context that sends work back into the run.[3]

Nothing in that claim guarantees event delivery on every Codex surface.

Historical reports already referenced SessionStart, UserPromptSubmit, PreToolUse, PostToolUse and Stop.[4] The timing of SessionStart was questioned because it waited for the first prompt. An OpenAI contributor later clarified that waiting for that prompt was expected at the time; the ordering guarantee was that SessionStart ran before UserPromptSubmit.[5]

A separate UserPromptSubmit report shows additionalContext reaching the model while also being rendered as a visible developer message in the transcript. Context injection worked; transcript rendering was the bug.[6]

Tool hooks exposed a different gap. Code Mode’s freeform exec path could miss PreToolUse even though direct exec_command dispatches fired it.[7] A Desktop/app-server regression also left the same Hook setup working in the CLI while failing on that client path.[8]

A PreToolUse policy only covers tool paths that actually emit PreToolUse. Other paths need their own evidence before they can be treated as covered.

Even with the event path intact, an unmanaged command Hook may still not run before it is trusted. User-level Hooks could remain disabled until approval through /hooks, and a changed command identity could require review again.[9] The Codex app also added an in-app Hook trust flow.[2]

A hooks.json entry establishes configuration. Trust, event emission and command completion still need separate checks.

A Skill solves a different part of the Stop-validation problem. It can teach Codex which tests to run and how to interpret them. The Hook decides when the validator is invoked because the lifecycle reached Stop.

Where Hooks sit beside Skills, MCP and Plugins

The four mechanisms answer different implementation questions: how the agent should work, how it reaches external capabilities, what runs at a lifecycle event, and how reusable setup is packaged. The map below is only a placement aid for those responsibilities, not a formal Codex stack.

A Skill carries a reusable procedure. MCP gives a workflow a standard route to external tools and context when MCP-backed integration is needed. A Hook attaches logic to emitted lifecycle events. A Plugin packages reusable setup for installation and distribution.

How Skills, MCP, Hooks and Plugins divide responsibility

OpenAI’s team plugin-sharing changelog supplies one concrete product relationship: reusable plugin bundles can include skills, MCP servers and lifecycle hooks.[2]

That packaging relationship does not create a runtime sequence. A project can use a Stop hook without MCP. A Skill can use MCP without any Hook. A Plugin can package whichever pieces the setup requires.

A requirement written as:

When event Y is emitted, run X.

belongs naturally in the lifecycle. In the Stop example, the Skill can hold the test procedure while the Hook supplies the trigger. What the command can actually do still depends on the execution environment, trust and the surrounding permission model.

References

  1. OpenAI, Work with Codex from anywhere, 14 May 2026.
    https://openai.com/index/work-with-codex-from-anywhere/
  2. OpenAI, ChatGPT & Codex changelog, entries dated 8 May, 14 May and 21 May 2026.
    https://developers.openai.com/codex/changelog
  3. openai/codex GitHub issue #20783, Blocking stop hook continuation can fail with invalid local message id, 2 May 2026.
    https://github.com/openai/codex/issues/20783
  4. openai/codex GitHub issue #16226, Hooks: distinguish subagent events from main agent, 30 March 2026.
    https://github.com/openai/codex/issues/16226
  5. openai/codex GitHub issue #15266, UserPromptSubmit and SessionStart hooks fire simultaneously on first prompt, 20 March 2026.
    https://github.com/openai/codex/issues/15266
  6. openai/codex GitHub issue #16933, Codex CLI renders hook additionalContext as visible developer message, 6 April 2026.
    https://github.com/openai/codex/issues/16933
  7. openai/codex GitHub issue #23411, Code Mode exec doesn’t fire PreToolUse hooks, 19 May 2026.
    https://github.com/openai/codex/issues/23411
  8. openai/codex GitHub issue #21639, Hooks no longer run after Codex Desktop update, 8 May 2026.
    https://github.com/openai/codex/issues/21639
  9. openai/codex GitHub issue #21615, Provide a supported way for local IDE/wrapper installers to request trust for installed hooks, 7 May 2026.
    https://github.com/openai/codex/issues/21615