config: add strict config parsing

This commit is contained in:
Michael Bolin
2026-05-12 17:57:13 -07:00
parent 0173f71143
commit 68a66c514b
41 changed files with 1280 additions and 106 deletions
+5 -1
View File
@@ -16,6 +16,10 @@ pub struct Cli {
#[command(subcommand)]
pub command: Option<Command>,
/// Error out when config.toml contains fields that are not recognized by this version of Codex.
#[arg(long = "strict-config", global = true, default_value_t = false)]
pub strict_config: bool,
#[clap(flatten)]
pub shared: ExecSharedCliOptions,
@@ -257,7 +261,7 @@ impl FromArgMatches for ResumeArgs {
}
}
#[derive(Parser, Debug)]
#[derive(Args, Debug)]
pub struct ReviewArgs {
/// Review staged, unstaged, and untracked changes.
#[arg(
+10 -4
View File
@@ -54,6 +54,7 @@ use codex_app_server_protocol::TurnStartedNotification;
use codex_arg0::Arg0DispatchPaths;
use codex_cloud_requirements::cloud_requirements_loader_for_storage;
use codex_config::ConfigLoadError;
use codex_config::ConfigLoadOptions;
use codex_config::LoaderOverrides;
use codex_config::format_config_error_with_source;
use codex_core::StateDbHandle;
@@ -62,7 +63,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_and_loader_overrides;
use codex_core::config::load_config_as_toml_with_cli_and_load_options;
use codex_core::config::resolve_oss_provider;
use codex_core::find_thread_meta_by_name_str;
use codex_core::format_exec_policy_error_with_source;
@@ -242,6 +243,7 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
let Cli {
command,
strict_config,
shared,
skip_git_repo_check,
ephemeral,
@@ -317,18 +319,20 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
}
};
#[allow(clippy::print_stderr)]
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(
let config_toml = match load_config_as_toml_with_cli_and_load_options(
&codex_home,
Some(&config_cwd),
cli_kv_overrides.clone(),
loader_overrides.clone(),
ConfigLoadOptions {
loader_overrides: loader_overrides.clone(),
strict_config,
},
)
.await
{
@@ -429,6 +433,7 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
.cli_overrides(cli_kv_overrides)
.harness_overrides(overrides)
.loader_overrides(loader_overrides)
.strict_config(strict_config)
.cloud_requirements(cloud_requirements)
.build()
.await?;
@@ -520,6 +525,7 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
config: std::sync::Arc::new(config.clone()),
cli_overrides: run_cli_overrides,
loader_overrides: run_loader_overrides,
strict_config,
cloud_requirements: run_cloud_requirements,
feedback: CodexFeedback::new(),
log_db: None,
+1 -2
View File
@@ -32,8 +32,7 @@ fn main() -> anyhow::Result<()> {
let mut inner = top_cli.inner;
inner
.config_overrides
.raw_overrides
.splice(0..0, top_cli.config_overrides.raw_overrides);
.prepend_root_overrides(top_cli.config_overrides);
run_main(inner, arg0_paths).await?;
Ok(())
+9 -3
View File
@@ -7,6 +7,7 @@ fn top_cli_parses_resume_prompt_after_config_flag() {
let cli = TopCli::parse_from([
"codex-exec",
"resume",
"--strict-config",
"--last",
"--json",
"--model",
@@ -17,8 +18,12 @@ fn top_cli_parses_resume_prompt_after_config_flag() {
"--skip-git-repo-check",
PROMPT,
]);
let mut inner = cli.inner;
inner
.config_overrides
.prepend_root_overrides(cli.config_overrides);
let Some(codex_exec::Command::Resume(args)) = cli.inner.command else {
let Some(codex_exec::Command::Resume(args)) = inner.command.as_ref() else {
panic!("expected resume command");
};
let effective_prompt = args.prompt.clone().or_else(|| {
@@ -29,9 +34,10 @@ fn top_cli_parses_resume_prompt_after_config_flag() {
}
});
assert_eq!(effective_prompt.as_deref(), Some(PROMPT));
assert_eq!(cli.config_overrides.raw_overrides.len(), 1);
assert_eq!(inner.config_overrides.raw_overrides.len(), 1);
assert_eq!(
cli.config_overrides.raw_overrides[0],
inner.config_overrides.raw_overrides[0],
"reasoning_level=xhigh"
);
assert!(inner.strict_config);
}