Files
codex/codex-rs/core/src/config_loader
Michael Bolin de3fa03e1c feat: change ConfigLayerName into a disjoint union rather than a simple enum (#8095)
This attempts to tighten up the types related to "config layers."
Currently, `ConfigLayerEntry` is defined as follows:


bef36f4ae7/codex-rs/core/src/config_loader/state.rs (L19-L25)

but the `source` field is a bit of a lie, as:

- for `ConfigLayerName::Mdm`, it is
`"com.openai.codex/config_toml_base64"`
- for `ConfigLayerName::SessionFlags`, it is `"--config"`
- for `ConfigLayerName::User`, it is `"config.toml"` (just the file
name, not the path to the `config.toml` on disk that was read)
- for `ConfigLayerName::System`, it seems like it is usually
`/etc/codex/managed_config.toml` in practice, though on Windows, it is
`%CODEX_HOME%/managed_config.toml`:


bef36f4ae7/codex-rs/core/src/config_loader/layer_io.rs (L84-L101)

All that is to say, in three out of the four `ConfigLayerName`, `source`
is a `PathBuf` that is not an absolute path (or even a true path).

This PR tries to uplevel things by eliminating `source` from
`ConfigLayerEntry` and turning `ConfigLayerName` into a disjoint union
named `ConfigLayerSource` that has the appropriate metadata for each
variant, favoring the use of `AbsolutePathBuf` where appropriate:

```rust
pub enum ConfigLayerSource {
    /// Managed preferences layer delivered by MDM (macOS only).
    #[serde(rename_all = "camelCase")]
    #[ts(rename_all = "camelCase")]
    Mdm { domain: String, key: String },
    /// Managed config layer from a file (usually `managed_config.toml`).
    #[serde(rename_all = "camelCase")]
    #[ts(rename_all = "camelCase")]
    System { file: AbsolutePathBuf },
    /// Session-layer overrides supplied via `-c`/`--config`.
    SessionFlags,
    /// User config layer from a file (usually `config.toml`).
    #[serde(rename_all = "camelCase")]
    #[ts(rename_all = "camelCase")]
    User { file: AbsolutePathBuf },
}
```
2025-12-17 08:13:59 -08:00
..

codex-core config loader

This module is the canonical place to load and describe Codex configuration layers (user config, CLI/session overrides, managed config, and MDM-managed preferences) and to produce:

  • An effective merged TOML config.
  • Per-key origins metadata (which layer “wins” for a given key).
  • Per-layer versions (stable fingerprints) used for optimistic concurrency / conflict detection.

Public surface

Exported from codex_core::config_loader:

  • load_config_layers_state(codex_home, cli_overrides, overrides) -> ConfigLayerStack
  • ConfigLayerStack
    • effective_config() -> toml::Value
    • origins() -> HashMap<String, ConfigLayerMetadata>
    • layers_high_to_low() -> Vec<ConfigLayer>
    • with_user_config(user_config) -> ConfigLayerStack
  • ConfigLayerEntry (one layers {name, config, version}; name carries source metadata)
  • LoaderOverrides (test/override hooks for managed config sources)
  • merge_toml_values(base, overlay) (public helper used elsewhere)

Layering model

Precedence is top overrides bottom:

  1. MDM managed preferences (macOS only)
  2. System managed config (e.g. managed_config.toml)
  3. Session flags (CLI overrides, applied as dotted-path TOML writes)
  4. User config (config.toml)

This is what ConfigLayerStack::effective_config() implements.

Typical usage

Most callers want the effective config plus metadata:

use codex_core::config_loader::{load_config_layers_state, LoaderOverrides};
use toml::Value as TomlValue;

let cli_overrides: Vec<(String, TomlValue)> = Vec::new();
let layers = load_config_layers_state(
    &codex_home,
    &cli_overrides,
    LoaderOverrides::default(),
).await?;

let effective = layers.effective_config();
let origins = layers.origins();
let layers_for_ui = layers.layers_high_to_low();

Internal layout

Implementation is split by concern:

  • state.rs: public types (ConfigLayerEntry, ConfigLayerStack) + merge/origins convenience methods.
  • layer_io.rs: reading config.toml, managed config, and managed preferences inputs.
  • overrides.rs: CLI dotted-path overrides → TOML “session flags” layer.
  • merge.rs: recursive TOML merge.
  • fingerprint.rs: stable per-layer hashing and per-key origins traversal.
  • macos.rs: managed preferences integration (macOS only).