Brief IA

Codex: Enforce Your Rules with a Stop Hook

🔬 Research·Tom Levy·

Codex: Enforce Your Rules with a Stop Hook

Codex: Enforce Your Rules with a Stop Hook
Key Takeaways
1A Stop hook blocks the closure of a report if source and domain thresholds are not met.
2The script .codex/hooks/validate_research.py checks 2 sources per trend, 10 unique sources, and 5 domains.
3A test succeeded after 12 unique sources from 10 domains, with the output recorded in JSON.
💡Why it mattersHooks add deterministic logic around the execution of Codex and allow for quality safeguards on the outputs.
Le brief IA que lisent les pros

Le brief IA que les pros lisent chaque soir

Les 7 actus IA du jour, décryptées en 5 min. Gratuit.

Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.

Choisis ton rythme

Gratuit · Pas de spam · Désabonnement en 1 clic

📄
Full Analysis

A control triggered on the Stop event can prevent Codex from concluding a session if a report does not meet thresholds for sources and domains. In a test on data center infrastructure, the report was only validated after 12 unique sources from 10 domains. The mechanism relies on an external script, a JSON output schema, and a command mode hook configuration. This approach extends to other lifecycle events to insert deterministic logic around execution.

A test validated after 12 unique sources and 10 domains

During an execution on the theme of recent trends in data center infrastructure, Codex initially delivered three trends supported by seven unique sources. Each trend exceeded two references, but the overall count did not meet the target of ten sources. The hook triggered on Stop returned feedback requesting more corroborations, with the addition of at least three independent sources within the same time window. After an additional round, the output reached 12 unique sources from 10 domains. Three major axes were retained: the rise of AI campuses at the gigawatt scale, constraints on energy access and permits, and the rise of liquid cooling. The hook executed once more and allowed the session to conclude, with the synthesis saved in outputs/research_brief.json.

Validation occurs at the Stop moment without terminating execution

The checks take place once the report is prepared, with the chosen hook being the Stop event. At this stage, Codex transmits last_assistant_message according to the defined schema, allowing the script to control the content. A blocking decision on Stop does not interrupt the run: it simply prevents closure and returns indications for a new round to improve the output within the same cycle. The hook is declared in .codex/hooks.json with a "command" type launching the Python script, and a commandWindows field for the Windows environment. No matcher is provided here, as Codex does not apply any on the Stop event.

Three thresholds controlled by a dedicated Python script

The file .codex/hooks/validate_research.py defines three thresholds: at least two sources per trend, ten unique sources in total, and five unique domains. The script reads the event from standard input, loads the assistant's last response into a dictionary, and then iterates through the numbered trends starting from 1. URLs are aggregated into a set to ensure uniqueness, and urlparse extracts the domains. Error messages are added if a threshold is not met, then grouped into a failure text prefixed with "Research report validation failed:". The returned object sets decision to "block" and reason to the message detailing the deficiencies.

A JSON schema and a prompt bound the output format

The upstream framing relies on an instruction model specifying the subject, an inclusive publication window, and the production of three key trends accompanied by a brief sourced report. A JSON schema of type object, without additional properties, makes summary and trends mandatory, and imposes the fields title, summary, and an array of sources as strings for each trend. Saved under schemas/research_brief.schema.json, this format is what the hook expects during the Stop event. The agent must thus return a structured synthesis compliant with these constraints.

Non-interactive execution and event tracing in JSONL

The test uses the subject "recent trends in data center infrastructure," with as_of set to 2026-08-01 and lookback_days to 90. The rendered prompt is saved in outputs/research_prompt.md and may be preceded by a review of the hooks via the /hooks command in the project. Execution is done in non-interactive mode with exec and the --search option activates web search. The selected model is gpt-5.6-sol, with the output constrained by --output-schema to schemas/research_brief.schema.json and saved with -o in outputs/research_brief.json. The instruction file is provided via standard input by "< outputs/research_prompt.md" and the event output is redirected to outputs/run.jsonl. The --json option emits these events in JSONL format, providing an execution trace. The "-" sign indicates to Codex to accept input via stdin when redirection is used.

Where to hook into the loop and with what rules

Several attachment points punctuate a session: SessionStart at launch, PreToolUse before calling a tool, PostToolUse after its execution, Stop just before the end of the response, and SessionEnd at closure. A hook can load context as early as SessionStart, inspect an operation at PreToolUse, process a result at PostToolUse, or validate the output at Stop. At each event, Codex can pass useful information to the script, but the same moment can correspond to multiple actions: a matcher then selects the targeted cases, for example, only shell commands. The configuration articulates three components — event, matcher, and handler — which define when to execute, under what conditions, and what action to take. This framework allows for the addition of deterministic logic around Codex's execution throughout the entire cycle.

Brief IA — L'actualité IA en français

L'essentiel de l'actualité de l'intelligence artificielle, décrypté et expliqué chaque jour.