mirror of
https://github.com/openai/codex.git
synced 2026-05-02 12:21:26 +03:00
4.0 KiB
4.0 KiB
Task 11: User-Configurable Approval Predicates
This task is specific to codex-rs.
Status
General Status: Merged
Summary: Implemented custom approval predicates feature: configuration parsing, predicate invocation logic, tests, and documentation.
Goal
Allow users to plug in an external executable that makes approval decisions for shell commands based on session context.
Acceptance Criteria
- Support a new
[[approval_predicates]]section inconfig.tomlfor Python-based predicates, each with apython_predicate_binary = "..."field (pointing to the predicate executable) and an implicitnever_expire = truesetting. - Before prompting the user, invoke each configured predicate in order, passing the following (via CLI args or env vars):
- Session ID
- Container working directory (CWD)
- Host working directory (CWD)
- Candidate shell command string
- The predicate must print exactly one of
allow,deny, oraskon stdout:allow→ auto-approve and skip remaining predicatesdeny→ auto-reject and skip remaining predicatesask→ open the standard approval dialog and skip remaining predicates
- If a predicate exits non-zero or outputs anything else, treat it as
askand continue to the next predicate. - Write unit and integration tests covering typical and edge-case predicate behavior.
- Document configuration syntax and behavior in the top-level config docs (
config.md).
Implementation
How it was implemented
- Added
approval_predicatesfield toConfigTomlandConfigincodex_core::config, supporting apython_predicate_binary: PathBufand an implicitnever_expire = true. - Hooked into the command-approval code path in
codex_core::safetyto invoke each configured predicate executable before showing the approval prompt. Predicates are launched viastd::process::Commandwith context passed in environment variables (CODEX_SESSION_ID,CODEX_CONTAINER_CWD,CODEX_HOST_CWD,CODEX_COMMAND). - Parsed each predicate’s stdout for exactly
allow,deny, orask, short-circuiting onallowordeny(auto-approve/auto-reject) and treating failures or unexpected output asaskto continue to the next predicate. - Wrote unit tests for configuration parsing and predicate-invocation behavior, covering exit-code and output edge cases, plus integration tests verifying end-to-end approval decisions.
- Updated
config.mdto document the[[approval_predicates]]table syntax, default semantics, and runtime behavior.
How it works
When a shell command requires approval, Codex iterates over each entry in [[approval_predicates]] in order. For each predicate:
- Launch the configured binary with session context in its environment.
- If it exits successfully and writes
allow, Codex auto-approves and skips remaining predicates. - If it writes
deny, Codex auto-rejects and skips remaining predicates. - Otherwise (writes
ask, fails, or emits unexpected output), Codex moves to the next predicate or falls back to the manual approval dialog if none returnallowordeny. This mechanism lets users automate approval decisions via custom Python scripts while retaining manual control when predicates defer.
Notes
- Consider passing context via environment variables (e.g.
CODEX_SESSION_ID,CODEX_CONTAINER_CWD,CODEX_HOST_CWD,CODEX_COMMAND). - Reuse invocation logic from the auto-approval predicates feature (Task 02).
- Motivating example: auto-approve
pre-commit run --files <any number of space-separated files>. - Motivating example: auto-approve any
gitcommand (e.g.git add,git commit,git push,git status, etc.) provided its repository root is under<directory>, correctly handling common flags and safe invocation modes. - Motivating example: auto-approve any shell pipeline composed out of
<these known-safe commands>operating on<known-safe files>with<known-safe params>, using a general pipeline parser to ensure safety—a nontrivial example of predicate logic.