Extract codex-config from codex-core (#11389)

`codex-core` had accumulated config loading, requirements parsing,
constraint logic, and config-layer state handling in a single crate.
This change extracts that subsystem into `codex-config` to reduce
`codex-core` rebuild/test surface area and isolate future config work.

## What Changed

### Added `codex-config`

- Added new workspace crate `codex-rs/config` (`codex-config`).
- Added workspace/build wiring in:
  - `codex-rs/Cargo.toml`
  - `codex-rs/config/Cargo.toml`
  - `codex-rs/config/BUILD.bazel`
- Updated lockfiles (`codex-rs/Cargo.lock`, `MODULE.bazel.lock`).
- Added `codex-core` -> `codex-config` dependency in
`codex-rs/core/Cargo.toml`.

### Moved config internals from `core` into `config`

Moved modules to `codex-rs/config/src/`:

- `core/src/config/constraint.rs` -> `config/src/constraint.rs`
- `core/src/config_loader/cloud_requirements.rs` ->
`config/src/cloud_requirements.rs`
- `core/src/config_loader/config_requirements.rs` ->
`config/src/config_requirements.rs`
- `core/src/config_loader/fingerprint.rs` -> `config/src/fingerprint.rs`
- `core/src/config_loader/merge.rs` -> `config/src/merge.rs`
- `core/src/config_loader/overrides.rs` -> `config/src/overrides.rs`
- `core/src/config_loader/requirements_exec_policy.rs` ->
`config/src/requirements_exec_policy.rs`
- `core/src/config_loader/state.rs` -> `config/src/state.rs`

`codex-config` now re-exports this surface from `config/src/lib.rs` at
the crate top level.

### Updated `core` to consume/re-export `codex-config`

- `core/src/config_loader/mod.rs` now imports/re-exports config-loader
types/functions from top-level `codex_config::*`.
- Local moved modules were removed from `core/src/config_loader/`.
- `core/src/config/mod.rs` now re-exports constraint types from
`codex_config`.
This commit is contained in:
Michael Bolin
2026-02-11 10:02:49 -08:00
committed by GitHub
parent 7e0178597e
commit 577a416f9a
20 changed files with 292 additions and 163 deletions

View File

@@ -474,44 +474,46 @@ mod tests {
} else {
absolute_path("/etc/codex/requirements.toml")
};
let mut requirements = ConfigRequirements::default();
requirements.approval_policy = ConstrainedWithSource::new(
Constrained::allow_any(AskForApproval::OnRequest),
Some(RequirementSource::CloudRequirements),
);
requirements.sandbox_policy = ConstrainedWithSource::new(
Constrained::allow_any(SandboxPolicy::ReadOnly),
Some(RequirementSource::SystemRequirementsToml {
file: requirements_file.clone(),
}),
);
requirements.mcp_servers = Some(Sourced::new(
BTreeMap::from([(
"docs".to_string(),
McpServerRequirement {
identity: McpServerIdentity::Command {
command: "codex-mcp".to_string(),
let requirements = ConfigRequirements {
approval_policy: ConstrainedWithSource::new(
Constrained::allow_any(AskForApproval::OnRequest),
Some(RequirementSource::CloudRequirements),
),
sandbox_policy: ConstrainedWithSource::new(
Constrained::allow_any(SandboxPolicy::ReadOnly),
Some(RequirementSource::SystemRequirementsToml {
file: requirements_file.clone(),
}),
),
mcp_servers: Some(Sourced::new(
BTreeMap::from([(
"docs".to_string(),
McpServerRequirement {
identity: McpServerIdentity::Command {
command: "codex-mcp".to_string(),
},
},
)]),
RequirementSource::LegacyManagedConfigTomlFromMdm,
)),
enforce_residency: ConstrainedWithSource::new(
Constrained::allow_any(Some(ResidencyRequirement::Us)),
Some(RequirementSource::CloudRequirements),
),
web_search_mode: ConstrainedWithSource::new(
Constrained::allow_any(WebSearchMode::Cached),
Some(RequirementSource::CloudRequirements),
),
network: Some(Sourced::new(
NetworkConstraints {
enabled: Some(true),
allowed_domains: Some(vec!["example.com".to_string()]),
..Default::default()
},
)]),
RequirementSource::LegacyManagedConfigTomlFromMdm,
));
requirements.enforce_residency = ConstrainedWithSource::new(
Constrained::allow_any(Some(ResidencyRequirement::Us)),
Some(RequirementSource::CloudRequirements),
);
requirements.web_search_mode = ConstrainedWithSource::new(
Constrained::allow_any(WebSearchMode::Cached),
Some(RequirementSource::CloudRequirements),
);
requirements.network = Some(Sourced::new(
NetworkConstraints {
enabled: Some(true),
allowed_domains: Some(vec!["example.com".to_string()]),
..Default::default()
},
RequirementSource::CloudRequirements,
));
RequirementSource::CloudRequirements,
)),
..ConfigRequirements::default()
};
let requirements_toml = ConfigRequirementsToml {
allowed_approval_policies: Some(vec![AskForApproval::OnRequest]),
@@ -631,11 +633,13 @@ approval_policy = "never"
#[test]
fn debug_config_output_normalizes_empty_web_search_mode_list() {
let mut requirements = ConfigRequirements::default();
requirements.web_search_mode = ConstrainedWithSource::new(
Constrained::allow_any(WebSearchMode::Disabled),
Some(RequirementSource::CloudRequirements),
);
let requirements = ConfigRequirements {
web_search_mode: ConstrainedWithSource::new(
Constrained::allow_any(WebSearchMode::Disabled),
Some(RequirementSource::CloudRequirements),
),
..ConfigRequirements::default()
};
let requirements_toml = ConfigRequirementsToml {
allowed_approval_policies: None,