Codex CLI, OpenAI's command-line coding agent, gets the same level of Paqad enforcement as Claude Code: Paqad can stop certain edits before they happen and check the change when the AI finishes its turn. Onboarding writes AGENTS.md for the instructions and .codex/hooks.json for the hooks, the moments when Codex runs a Paqad program and respects its answer. There is one extra step: you must approve the hooks inside Codex before they run.
What Paqad can enforce in Codex CLI
Codex CLI is at the blocks and checks level. Once the hooks are approved and Paqad is switched on:
- A change made with Codex's
apply_patchtool is refused until the AI has loaded the Paqad framework in this session. - Changes are refused while a decision is waiting for your answer.
- For feature work, a source-code change is refused until the earlier stages (such as planning and specification) are recorded and the relevant rules are loaded. If one patch touches several files, it counts as feature work when any of them is.
- When the AI finishes its turn, a verification script checks the change. If a check fails outright, Codex is told to keep working and fix it.
These are deterministic checks made by scripts, not by the AI. They are the same scripts Claude Code uses, given one extra argument, codex-cli, so the records show which tool did the work.
Earlier material, including Paqad's own explainer written for version 1.86.0, describes Codex CLI as record-only. That is out of date. In 1.91.1 Codex CLI gets the full set of blocking hooks.
Files onboarding writes
| File | What it is |
|---|---|
AGENTS.md | The entry file. It tells the AI to open .paqad/framework-path.txt and follow the installed framework, or to act as a normal assistant if Paqad is missing or off. An existing AGENTS.md keeps its text; Paqad's lines go in a marked block. |
.codex/hooks.json | The hook file Codex runs. Hooks you already had are kept. |
.codex/.gitignore | Tells git to ignore hooks.json and settings.hooks.json, because the hook commands contain a path specific to your computer. |
.codex/settings.hooks.json | A bookkeeping list of the hook files Paqad selected. Codex does not run it. |
.codex/mcp.json | The MCP servers Paqad suggests for your stack. It has no start commands, so it does not connect Codex to anything by itself. |
.codex/cache.json, .codex/memory.json | Paqad bookkeeping. Not Codex settings. |
Outside the project, the Paqad install writes six stage helpers to ~/.codex/agents/, one per stage, named paqad-planning.toml through paqad-documentation-sync.toml. These are subagents: separate AI helpers Codex can start for one stage of the work.
The hooks Paqad adds
| Codex event | Paqad scripts | Can it stop work? |
|---|---|---|
PreToolUse, matched to ^apply_patch$ | agent-entry-gate.mjs, stage-writer.mjs, decision-pause-gate.mjs, capability-gate.mjs pre-mutation | Yes. The entry, decision and capability gates can refuse the change. The stage writer only records. |
UserPromptSubmit | agent-entry-prompt-gate.mjs, ticket-intake-prompt.mjs | No, by default. Adds loading instructions and context to your message. |
SessionStart | agent-entry-session-start.mjs, silent-update.mjs | No. |
Stop | stage-marker-parse.mjs, verification-completion.mjs, capability-gate.mjs completion | Yes, once per turn, on a hard failure. |
SubagentStop, matched to ^paqad- | stage-agent-completion.mjs | No. Records a row when a Paqad stage helper finishes. |
Scripted rule checks refuse a change only when rule_compliance is strict. The default is warn, which reports without blocking.
Setting it up
- Run
paqad-ai onboard --providers codex-cli, or tick Codex when onboarding asks. - Open Codex in the project, run
/hooks, and approve Paqad's hooks. Codex only runs project hooks from a.codex/folder you have trusted. Until you approve them, nothing is enforced. - Ask each teammate to run
paqad-ai joinon their own machine and approve the hooks the same way..codex/hooks.jsonis ignored by git, so it does not arrive with a clone. - Run
paqad-ai doctor. Its "Codex hooks wired" check confirms that.codex/hooks.jsoncovers all four main events. It cannot see whether you approved them in Codex. See paqad-ai doctor.
Automatic updates
At the start of each session, silent-update.mjs checks for a newer paqad-ai. If one exists, it runs npm install -g paqad-ai@latest in the background, then paqad-ai update --silent. To turn this off, set auto_update=false in Paqad's config (for example .paqad/.config) or set PAQAD_AUTO_UPDATE.
Limits to know
- Only
apply_patchis checked before it runs. A file changed by a shell command is not stopped in advance. The end-of-turn check reads the working tree, so it still sees the change afterwards. - The end-of-turn check blocks at most once per turn, then lets the session end.
- The stage check is on by default (
stages_modeisstrict). A team can lower it towarnoroffin its shared Paqad config; a single developer can only make it stricter, not weaker. - If the hook scripts cannot run, they let work continue.
- Paqad can be switched off with
paqad-ai disableorPAQAD_DISABLED=1. Then nothing blocks, although a finished turn is logged as a disabled session.