Repository navigation
Allow UserPromptSubmit hooks to fail closed before model requests #33630
Description
What variant of Codex are you using?
Codex Desktop/App, app-server, and CLI. The motivating reproduction was on Windows with Codex 0.144.5; the proposed behavior was also implemented and validated against current main.
What feature would you like to see?
Add an opt-in fail-closed policy for UserPromptSubmit command hooks so a detector or policy hook can prevent prompt transmission when the hook itself fails.
Today, a UserPromptSubmit hook can reject a prompt through a valid blocking result, but Codex continues submission when the hook process crashes, times out, cannot be executed, or emits malformed output. That makes the hook unsuitable for local secret-paste prevention or similar pre-transmission policy checks: detector failure must not silently become permission to send the prompt.
A narrow configuration shape would be:
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "",
"failureMode": "block",
"hooks": [
{
"type": "command",
"command": "path/to/local-detector"
}
]
}
]
}
}Proposed semantics:
failureModeacceptscontinueorblock.- Omitted or
continuepreserves the existing fail-open behavior. blockapplies only toUserPromptSubmit; other events warn and remain fail-open.- Nonzero exit, timeout, missing executable, malformed output, and event-serialization failure produce a redacted blocking diagnostic and no model request.
- The policy participates in hook trust hashing so changing it requires re-trust.
- Desktop/app-server config reads expose the effective value so UI and runtime state remain consistent.
This is the concrete blocking-policy part of the broader cross-surface hook goals tracked in #21753.
Additional information
I prepared a validated candidate implementation because external code contributions are invitation-only:
- Branch: https://github.com/AleZworks/codex/tree/codex/user-prompt-submit-fail-closed
- Compare: main...AleZworks:codex/user-prompt-submit-fail-closed
- Commit: AleZworks@11c13c7
The candidate:
- implements the opt-in policy in config and the hook engine;
- carries it through
configRequirements/readfor Desktop/app-server consumers; - regenerates config, JSON Schema, and TypeScript artifacts;
- adds unit and RPC coverage;
- adds a Linux core integration test that asserts a failed fail-closed
UserPromptSubmithook results in zero model requests.
Local validation completed:
just write-config-schemajust write-app-server-schemajust test -p codex-app-server-protocol(262 passed)just test -p codex-config(205 passed)just test -p codex-hooks -E 'test(user_prompt_submit)'(8 passed)just test -p codex-hooks -E 'test(failure_mode_changes_hook_trust_hash)'(1 passed)just test -p codex-app-server -E 'test(config_requirements_read_includes_hook_failure_mode)'(1 passed)- targeted
just fixacross affected crates cargo fmt --all
The core hooks integration suite is cfg-disabled on Windows and is intended to run in Linux CI.
Activity
SirRadek commentedon Sep 22, 2026
Additional Linux evidence for this request, from a disposable synthetic app-server fixture:
0.154.0-alpha.6.2on Linux x86_64.SessionStartandUserPromptSubmit), with hooks forced on through managed requirements.Observed results:
In the exit-1 case, the host emitted one failed
UserPromptSubmitcompletion, the local sink received one request, and a terminal event was observed.SessionStartcompleted normally. We changed only the generated disposable prompt-hook copy; original hook bytes and native/configuration/identity integrity checks remained unchanged.The block and continue controls also passed on CLI
0.154.0. The exit-1 fault case was tested on the Desktop binary only; this is not a claim that every failure class or client was covered.Our sequence was initialize → requirements/config read → empty MCP check → hook inventory → thread/start → thread-scoped MCP check → turn/start. Both hook lifecycles and their initiating thread/turn binding were checked. The controls distinguish hook blocking from an unreachable endpoint.
This supports an opt-in native failure policy, rather than changing the compatibility default for advisory hooks. For administrator-mandated bootstrap/admission checks, the policy needs to remain enforceable against lower-priority overrides and expose its effective value to Desktop/app-server clients. A wrapper can translate some inner errors into an explicit block, but cannot supply the same guarantee when the wrapper itself is missing, crashes, or times out.
Has a supported implementation of this policy landed, and if so, which Desktop/CLI versions support it? Otherwise, this remains a deployment blocker for a mandatory pre-transmission gate. Related tool-dispatch coverage is tracked in #41979.
These are summarized observations, not a standalone portable reproduction bundle or a claim of a broader host sandbox vulnerability.