config-advanced.md +145 −20
84 84
85In addition to your user config, Codex reads project-scoped overrides from `.codex/config.toml` files inside your repo. Codex walks from the project root to your current working directory and loads every `.codex/config.toml` it finds. If multiple files define the same key, the closest file to your working directory wins.85In addition to your user config, Codex reads project-scoped overrides from `.codex/config.toml` files inside your repo. Codex walks from the project root to your current working directory and loads every `.codex/config.toml` it finds. If multiple files define the same key, the closest file to your working directory wins.
86 86
8787For security, Codex loads project-scoped config files only when the project is trusted. If the project is untrusted, Codex ignores `.codex/config.toml` files in the project.For security, Codex loads project-scoped config files only when the project is trusted. If the project is untrusted, Codex ignores project `.codex/` layers, including `.codex/config.toml`, project-local hooks, and project-local rules. User and system layers remain separate and still load.
88 88
89Relative paths inside a project config (for example, `model_instructions_file`) are resolved relative to the `.codex/` folder that contains the `config.toml`.89Relative paths inside a project config (for example, `model_instructions_file`) are resolved relative to the `.codex/` folder that contains the `config.toml`.
90 90
98- `~/.codex/hooks.json`98- `~/.codex/hooks.json`
99- `<repo>/.codex/hooks.json`99- `<repo>/.codex/hooks.json`
100 100
101Project-local hooks load only when the project `.codex/` layer is trusted.
102User-level hooks remain independent of project trust.
103
101Turn hooks on with:104Turn hooks on with:
102 105
103```toml106```toml
230 233
231You can also use a granular approval policy (`approval_policy = { granular = { ... } }`) to allow or auto-reject individual prompt categories. This is useful when you want normal interactive approvals for some cases but want others, such as `request_permissions` or skill-script prompts, to fail closed automatically.234You can also use a granular approval policy (`approval_policy = { granular = { ... } }`) to allow or auto-reject individual prompt categories. This is useful when you want normal interactive approvals for some cases but want others, such as `request_permissions` or skill-script prompts, to fail closed automatically.
232 235
233236```Set `approvals_reviewer = "auto_review"` to route eligible interactive approval
237requests through automatic review. This changes the reviewer, not the sandbox
238boundary.
239
240Use `[auto_review].policy` for local reviewer policy instructions. Managed
241`guardian_policy_config` takes precedence.
242
243```toml
234approval_policy = "untrusted" # Other options: on-request, never, or { granular = { ... } }244approval_policy = "untrusted" # Other options: on-request, never, or { granular = { ... } }
245approvals_reviewer = "user" # Or "auto_review" for automatic review
235sandbox_mode = "workspace-write"246sandbox_mode = "workspace-write"
236allow_login_shell = false # Optional hardening: disallow login shells for shell tools247allow_login_shell = false # Optional hardening: disallow login shells for shell tools
237 248
249exclude_slash_tmp = false # Allow /tmp260exclude_slash_tmp = false # Allow /tmp
250writable_roots = ["/Users/YOU/.pyenv/shims"]261writable_roots = ["/Users/YOU/.pyenv/shims"]
251network_access = false # Opt in to outbound network262network_access = false # Opt in to outbound network
263
264[auto_review]
265policy = """
266Use your organization's automatic review policy.
267"""
252```268```
253 269
254Need the complete key list (including profile-scoped overrides and requirements constraints)? See [Configuration Reference](https://developers.openai.com/codex/config-reference) and [Managed configuration](https://developers.openai.com/codex/enterprise/managed-configuration).270Need the complete key list (including profile-scoped overrides and requirements constraints)? See [Configuration Reference](https://developers.openai.com/codex/config-reference) and [Managed configuration](https://developers.openai.com/codex/enterprise/managed-configuration).
370 386
371#### Metrics catalog387#### Metrics catalog
372 388
373389Each metric includes the required fields plus the default context fields above. Every metric is prefixed by `codex.`.Each metric includes the required fields plus the default context fields above. Metric names below omit the `codex.` prefix.
390Most metric names are centralized in `codex-rs/otel/src/metrics/names.rs`; feature-specific metrics emitted outside that file are included here too.
374If a metric includes the `tool` field, it reflects the internal tool used (for example, `apply_patch` or `shell`) and doesn't contain the actual shell command or patch `codex` is trying to apply.391If a metric includes the `tool` field, it reflects the internal tool used (for example, `apply_patch` or `shell`) and doesn't contain the actual shell command or patch `codex` is trying to apply.
375 392
393#### Runtime and model transport
394
395| Metric | Type | Fields | Description |
396| --- | --- | --- | --- |
397| `api_request` | counter | `status`, `success` | API request count by HTTP status and success/failure. |
398| `api_request.duration_ms` | histogram | `status`, `success` | API request duration in milliseconds. |
399| `sse_event` | counter | `kind`, `success` | SSE event count by event kind and success/failure. |
400| `sse_event.duration_ms` | histogram | `kind`, `success` | SSE event processing duration in milliseconds. |
401| `websocket.request` | counter | `success` | WebSocket request count by success/failure. |
402| `websocket.request.duration_ms` | histogram | `success` | WebSocket request duration in milliseconds. |
403| `websocket.event` | counter | `kind`, `success` | WebSocket message/event count by type and success/failure. |
404| `websocket.event.duration_ms` | histogram | `kind`, `success` | WebSocket message/event processing duration in milliseconds. |
405| `responses_api_overhead.duration_ms` | histogram | | Responses API overhead timing from websocket responses. |
406| `responses_api_inference_time.duration_ms` | histogram | | Responses API inference timing from websocket responses. |
407| `responses_api_engine_iapi_ttft.duration_ms` | histogram | | Responses API engine IAPI time-to-first-token timing. |
408| `responses_api_engine_service_ttft.duration_ms` | histogram | | Responses API engine service time-to-first-token timing. |
409| `responses_api_engine_iapi_tbt.duration_ms` | histogram | | Responses API engine IAPI time-between-token timing. |
410| `responses_api_engine_service_tbt.duration_ms` | histogram | | Responses API engine service time-between-token timing. |
411| `transport.fallback_to_http` | counter | `from_wire_api` | WebSocket-to-HTTP fallback count. |
412| `remote_models.fetch_update.duration_ms` | histogram | | Time to fetch remote model definitions. |
413| `remote_models.load_cache.duration_ms` | histogram | | Time to load the remote model cache. |
414| `startup_prewarm.duration_ms` | histogram | `status` | Startup prewarm duration by outcome. |
415| `startup_prewarm.age_at_first_turn_ms` | histogram | `status` | Startup prewarm age when the first real turn resolves it. |
416| `cloud_requirements.fetch.duration_ms` | histogram | | Workspace-managed cloud requirements fetch duration. |
417| `cloud_requirements.fetch_attempt` | counter | See note | Workspace-managed cloud requirements fetch attempts. |
418| `cloud_requirements.fetch_final` | counter | See note | Final workspace-managed cloud requirements fetch outcome. |
419| `cloud_requirements.load` | counter | `trigger`, `outcome` | Workspace-managed cloud requirements load outcome. |
420
421The `cloud_requirements.fetch_attempt` metric includes `trigger`, `attempt`, `outcome`, and `status_code` fields. The `cloud_requirements.fetch_final` metric includes `trigger`, `outcome`, `reason`, `attempt_count`, and `status_code` fields.
422
423#### Turn and tool activity
424
425| Metric | Type | Fields | Description |
426| --- | --- | --- | --- |
427| `turn.e2e_duration_ms` | histogram | | End-to-end time for a full turn. |
428| `turn.ttft.duration_ms` | histogram | | Time to first token for a turn. |
429| `turn.ttfm.duration_ms` | histogram | | Time to first model output item for a turn. |
430| `turn.network_proxy` | counter | `active`, `tmp_mem_enabled` | Whether the managed network proxy was active for the turn. |
431| `turn.memory` | counter | `read_allowed`, `feature_enabled`, `config_use_memories`, `has_citations` | Per-turn memory read availability and memory citation usage. |
432| `turn.tool.call` | histogram | `tmp_mem_enabled` | Number of tool calls in the turn. |
433| `turn.token_usage` | histogram | `token_type`, `tmp_mem_enabled` | Per-turn token usage by token type (`total`, `input`, `cached_input`, `output`, or `reasoning_output`). |
434| `tool.call` | counter | `tool`, `success` | Tool invocation count by tool name and success/failure. |
435| `tool.call.duration_ms` | histogram | `tool`, `success` | Tool execution duration in milliseconds by tool name and outcome. |
436| `tool.unified_exec` | counter | `tty` | Unified exec tool calls by TTY mode. |
437| `approval.requested` | counter | `tool`, `approved` | Tool approval request result (`approved`, `approved_with_amendment`, `approved_for_session`, `denied`, `abort`). |
438| `mcp.call` | counter | See note | MCP tool invocation result. |
439| `mcp.call.duration_ms` | histogram | See note | MCP tool invocation duration. |
440| `mcp.tools.list.duration_ms` | histogram | `cache` | MCP tool-list duration, including cache hit/miss state. |
441| `mcp.tools.fetch_uncached.duration_ms` | histogram | | Duration of uncached MCP tool fetches. |
442| `mcp.tools.cache_write.duration_ms` | histogram | | Duration of Codex Apps MCP tool-cache writes. |
443| `hooks.run` | counter | `hook_name`, `source`, `status` | Hook run count by hook name, source, and status. |
444| `hooks.run.duration_ms` | histogram | `hook_name`, `source`, `status` | Hook run duration in milliseconds. |
445
446The `mcp.call` and `mcp.call.duration_ms` metrics include `status`; normal tool-call emissions also include `tool`, plus `connector_id` and `connector_name` when available. Blocked Codex Apps MCP calls may emit `mcp.call` with only `status`.
447
448#### Threads, tasks, and features
449
376| Metric | Type | Fields | Description |450| Metric | Type | Fields | Description |
377| --- | --- | --- | --- |451| --- | --- | --- | --- |
378| `feature.state` | counter | `feature`, `value` | Feature values that differ from defaults (emit one row per non-default). |452| `feature.state` | counter | `feature`, `value` | Feature values that differ from defaults (emit one row per non-default). |
379453| `thread.started` | counter | `is_git` | New thread created. || `status_line` | counter | | Session started with a configured status line. |
380454| `thread.fork` | counter | | New thread created by forking an existing thread. || `model_warning` | counter | | Warning sent to the model. |
455| `thread.started` | counter | `is_git` | New thread created, tagged by whether the working directory is in a Git repo. |
456| `conversation.turn.count` | counter | | User/assistant turns per thread, recorded at the end of the thread. |
457| `thread.fork` | counter | `source` | New thread created by forking an existing thread. |
381| `thread.rename` | counter | | Thread renamed. |458| `thread.rename` | counter | | Thread renamed. |
459| `thread.side` | counter | `source` | Side conversation created. |
460| `thread.skills.enabled_total` | histogram | | Number of skills enabled for a new thread. |
461| `thread.skills.kept_total` | histogram | | Number of enabled skills kept after prompt rendering. |
462| `thread.skills.truncated` | histogram | | Whether skill rendering truncated the enabled skills list (`1` or `0`). |
382| `task.compact` | counter | `type` | Number of compactions per type (`remote` or `local`), including manual and auto. |463| `task.compact` | counter | `type` | Number of compactions per type (`remote` or `local`), including manual and auto. |
383| `task.user_shell` | counter | | Number of user shell actions (`!` in the TUI for example). |
384| `task.review` | counter | | Number of reviews triggered. |464| `task.review` | counter | | Number of reviews triggered. |
385| `task.undo` | counter | | Number of undo actions triggered. |465| `task.undo` | counter | | Number of undo actions triggered. |
386466| `approval.requested` | counter | `tool`, `approved` | Tool approval request result (`approved`, `approved_with_amendment`, `approved_for_session`, `denied`, `abort`). || `task.user_shell` | counter | | Number of user shell actions (`!` in the TUI for example). |
387467| `conversation.turn.count` | counter | | User/assistant turns per thread, recorded at the end of the thread. || `shell_snapshot` | counter | See note | Whether taking a shell snapshot succeeded. |
388| `turn.e2e_duration_ms` | histogram | | End-to-end time for a full turn. |
389| `mcp.call` | counter | `status` | MCP tool invocation result (`ok` or error string). |
390| `model_warning` | counter | | Warning sent to the model. |
391| `tool.call` | counter | `tool`, `success` | Tool invocation result (`success`: `true` or `false`). |
392| `tool.call.duration_ms` | histogram | `tool`, `success` | Tool execution time. |
393| `remote_models.fetch_update.duration_ms` | histogram | | Time to fetch remote model definitions. |
394| `remote_models.load_cache.duration_ms` | histogram | | Time to load the remote model cache. |
395| `shell_snapshot` | counter | `success` | Whether taking a shell snapshot succeeded. |
396| `shell_snapshot.duration_ms` | histogram | `success` | Time to take a shell snapshot. |468| `shell_snapshot.duration_ms` | histogram | `success` | Time to take a shell snapshot. |
397469| `db.init` | counter | `status` | State DB initialization outcomes (`opened`, `created`, `open_error`, `init_error`). || `skill.injected` | counter | `status`, `skill` | Skill injection outcomes by skill. |
470| `plugins.startup_sync` | counter | `transport`, `status` | Curated plugin startup sync attempts. |
471| `plugins.startup_sync.final` | counter | `transport`, `status` | Final curated plugin startup sync outcome. |
472| `multi_agent.spawn` | counter | `role` | Agent spawns by role. |
473| `multi_agent.resume` | counter | | Agent resumes. |
474| `multi_agent.nickname_pool_reset` | counter | | Agent nickname pool resets. |
475
476The `shell_snapshot` metric includes `success` and, on failures, `failure_reason`.
477
478#### Memory and local state
479
480| Metric | Type | Fields | Description |
481| --- | --- | --- | --- |
482| `memory.phase1` | counter | `status` | Memory phase 1 job counts by status. |
483| `memory.phase1.e2e_ms` | histogram | | End-to-end duration for memory phase 1. |
484| `memory.phase1.output` | counter | | Memory phase 1 outputs written. |
485| `memory.phase1.token_usage` | histogram | `token_type` | Memory phase 1 token usage by token type. |
486| `memory.phase2` | counter | `status` | Memory phase 2 job counts by status. |
487| `memory.phase2.e2e_ms` | histogram | | End-to-end duration for memory phase 2. |
488| `memory.phase2.input` | counter | | Memory phase 2 input count. |
489| `memory.phase2.token_usage` | histogram | `token_type` | Memory phase 2 token usage by token type. |
490| `memories.usage` | counter | `kind`, `tool`, `success` | Memory usage by kind, tool, and success/failure. |
491| `external_agent_config.detect` | counter | See note | External agent config detections by migration item type. |
492| `external_agent_config.import` | counter | See note | External agent config imports by migration item type. |
398| `db.backfill` | counter | `status` | Initial state DB backfill results (`upserted`, `failed`). |493| `db.backfill` | counter | `status` | Initial state DB backfill results (`upserted`, `failed`). |
399494| `db.backfill.duration_ms` | histogram | `status` | Duration of the initial state DB backfill, tagged with `success`, `failed`, or `partial_failure`. || `db.backfill.duration_ms` | histogram | `status` | Duration of the initial state DB backfill. |
400495| `db.error` | counter | `stage` | Errors during state DB operations (for example, `extract_metadata_from_rollout`, `backfill_sessions`, `apply_rollout_items`). || `db.error` | counter | `stage` | Errors during state DB operations. |
401496| `db.compare_error` | counter | `stage`, `reason` | State DB discrepancies detected during reconciliation. |
497The `external_agent_config.detect` and `external_agent_config.import` metrics include `migration_type`; skills migrations also include `skills_count`.
498
499#### Windows sandbox
500
501| Metric | Type | Fields | Description |
502| --- | --- | --- | --- |
503| `windows_sandbox.setup_success` | counter | `originator`, `mode` | Windows sandbox setup successes. |
504| `windows_sandbox.setup_failure` | counter | `originator`, `mode` | Windows sandbox setup failures. |
505| `windows_sandbox.setup_duration_ms` | histogram | `result`, `originator`, `mode` | Windows sandbox setup duration. |
506| `windows_sandbox.elevated_setup_success` | counter | | Elevated Windows sandbox setup successes. |
507| `windows_sandbox.elevated_setup_failure` | counter | See note | Elevated Windows sandbox setup failures. |
508| `windows_sandbox.elevated_setup_canceled` | counter | See note | Canceled elevated Windows sandbox setup attempts. |
509| `windows_sandbox.elevated_setup_duration_ms` | histogram | `result` | Elevated Windows sandbox setup duration. |
510| `windows_sandbox.elevated_prompt_shown` | counter | | Elevated sandbox setup prompt shown. |
511| `windows_sandbox.elevated_prompt_accept` | counter | | Elevated sandbox setup prompt accepted. |
512| `windows_sandbox.elevated_prompt_use_legacy` | counter | | User chose legacy sandbox from the elevated prompt. |
513| `windows_sandbox.elevated_prompt_quit` | counter | | User quit from the elevated prompt. |
514| `windows_sandbox.fallback_prompt_shown` | counter | | Fallback sandbox prompt shown. |
515| `windows_sandbox.fallback_retry_elevated` | counter | | User retried elevated setup from the fallback prompt. |
516| `windows_sandbox.fallback_use_legacy` | counter | | User chose legacy sandbox from the fallback prompt. |
517| `windows_sandbox.fallback_prompt_quit` | counter | | User quit from the fallback prompt. |
518| `windows_sandbox.legacy_setup_preflight_failed` | counter | See note | Legacy Windows sandbox setup preflight failure. |
519| `windows_sandbox.setup_elevated_sandbox_command` | counter | | Elevated sandbox setup command invoked. |
520| `windows_sandbox.createprocessasuserw_failed` | counter | `error_code`, `path_kind`, `exe`, `level` | Windows `CreateProcessAsUserW` failures. |
521
522The elevated setup failure metrics include `code` and `message` when Windows setup failure details are available, and may include `originator` when emitted from the shared setup path. The `windows_sandbox.legacy_setup_preflight_failed` metric includes `originator` when emitted from the shared setup path, but fallback-prompt preflight failures may not include any fields.
402 523
403### Feedback controls524### Feedback controls
404 525
476- `notify` runs an external program (good for webhooks, desktop notifiers, CI hooks).597- `notify` runs an external program (good for webhooks, desktop notifiers, CI hooks).
477- `tui.notifications` is built in to the TUI and can optionally filter by event type (for example, `agent-turn-complete` and `approval-requested`).598- `tui.notifications` is built in to the TUI and can optionally filter by event type (for example, `agent-turn-complete` and `approval-requested`).
478- `tui.notification_method` controls how the TUI emits terminal notifications (`auto`, `osc9`, or `bel`).599- `tui.notification_method` controls how the TUI emits terminal notifications (`auto`, `osc9`, or `bel`).
600- `tui.notification_condition` controls whether TUI notifications fire only when
601 the terminal is `unfocused` or `always`.
479 602
480In `auto` mode, Codex prefers OSC 9 notifications (a terminal escape sequence some terminals interpret as a desktop notification) and falls back to BEL (`\x07`) otherwise.603In `auto` mode, Codex prefers OSC 9 notifications (a terminal escape sequence some terminals interpret as a desktop notification) and falls back to BEL (`\x07`) otherwise.
481 604
522 645
523- `tui.notifications`: enable/disable notifications (or restrict to specific types)646- `tui.notifications`: enable/disable notifications (or restrict to specific types)
524- `tui.notification_method`: choose `auto`, `osc9`, or `bel` for terminal notifications647- `tui.notification_method`: choose `auto`, `osc9`, or `bel` for terminal notifications
648- `tui.notification_condition`: choose `unfocused` or `always` for when
649 notifications fire
525- `tui.animations`: enable/disable ASCII animations and shimmer effects650- `tui.animations`: enable/disable ASCII animations and shimmer effects
526- `tui.alternate_screen`: control alternate screen usage (set to `never` to keep terminal scrollback)651- `tui.alternate_screen`: control alternate screen usage (set to `never` to keep terminal scrollback)
527- `tui.show_tooltips`: show or hide onboarding tooltips on the welcome screen652- `tui.show_tooltips`: show or hide onboarding tooltips on the welcome screen