feat: add --ignore-user-config and --ignore-rules (#18646)

Add those 2 flags to be able to fully isolate a run of `codex exec` from
any rules or tools.
This will be used by Chronicle
This commit is contained in:
jif-oai
2026-04-20 11:27:47 +01:00
committed by GitHub
parent 7d8bd69283
commit be4fe9f9b2
9 changed files with 274 additions and 13 deletions
+8
View File
@@ -78,6 +78,14 @@ pub struct Cli {
#[arg(long = "ephemeral", global = true, default_value_t = false)]
pub ephemeral: bool,
/// Do not load `$CODEX_HOME/config.toml`; auth still uses `CODEX_HOME`.
#[arg(long = "ignore-user-config", global = true, default_value_t = false)]
pub ignore_user_config: bool,
/// Do not load user or project execpolicy `.rules` files.
#[arg(long = "ignore-rules", global = true, default_value_t = false)]
pub ignore_rules: bool,
/// Path to a JSON Schema file describing the model's final response shape.
#[arg(long = "output-schema", value_name = "FILE")]
pub output_schema: Option<PathBuf>,
+17
View File
@@ -14,10 +14,14 @@ fn resume_parses_prompt_after_global_flags() {
"--dangerously-bypass-approvals-and-sandbox",
"--skip-git-repo-check",
"--ephemeral",
"--ignore-user-config",
"--ignore-rules",
PROMPT,
]);
assert!(cli.ephemeral);
assert!(cli.ignore_user_config);
assert!(cli.ignore_rules);
let Some(Command::Resume(args)) = cli.command else {
panic!("expected resume command");
};
@@ -53,3 +57,16 @@ fn resume_accepts_output_last_message_flag_after_subcommand() {
assert_eq!(args.session_id.as_deref(), Some("session-123"));
assert_eq!(args.prompt.as_deref(), Some(PROMPT));
}
#[test]
fn parses_config_isolation_flags() {
let cli = Cli::parse_from([
"codex-exec",
"--ignore-user-config",
"--ignore-rules",
"summarize",
]);
assert!(cli.ignore_user_config);
assert!(cli.ignore_rules);
}
+13 -3
View File
@@ -56,7 +56,7 @@ use codex_core::config::Config;
use codex_core::config::ConfigBuilder;
use codex_core::config::ConfigOverrides;
use codex_core::config::find_codex_home;
use codex_core::config::load_config_as_toml_with_cli_overrides;
use codex_core::config::load_config_as_toml_with_cli_and_loader_overrides;
use codex_core::config::resolve_oss_provider;
use codex_core::config_loader::ConfigLoadError;
use codex_core::config_loader::LoaderOverrides;
@@ -230,6 +230,8 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
skip_git_repo_check,
add_dir,
ephemeral,
ignore_user_config,
ignore_rules,
color,
last_message_file,
json: json_mode,
@@ -297,10 +299,17 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
};
#[allow(clippy::print_stderr)]
let config_toml = match load_config_as_toml_with_cli_overrides(
let loader_overrides = LoaderOverrides {
ignore_user_config,
ignore_user_and_project_exec_policy_rules: ignore_rules,
..Default::default()
};
let config_toml = match load_config_as_toml_with_cli_and_loader_overrides(
&codex_home,
Some(&config_cwd),
cli_kv_overrides.clone(),
loader_overrides.clone(),
)
.await
{
@@ -334,7 +343,7 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
chatgpt_base_url,
);
let run_cli_overrides = cli_kv_overrides.clone();
let run_loader_overrides = LoaderOverrides::default();
let run_loader_overrides = loader_overrides.clone();
let run_cloud_requirements = cloud_requirements.clone();
let model_provider = if oss {
@@ -399,6 +408,7 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
let config = ConfigBuilder::default()
.cli_overrides(cli_kv_overrides)
.harness_overrides(overrides)
.loader_overrides(loader_overrides)
.cloud_requirements(cloud_requirements)
.build()
.await?;