Support skill filtering for project-local skills.config entries

Resolved 💬 5 comments Opened Apr 29, 2026 by skyswordw Closed Jul 1, 2026
💡 Likely answer: A maintainer (gabrimatic, contributor) responded on this thread — see the highlighted reply below.

What version of Codex is running?

codex-cli 0.125.0

Which platform / environment?

macOS, Codex CLI installed via npm (@openai/codex).

What happened?

Project-local .codex/config.toml is loaded for normal project configuration, but [[skills.config]] entries in that project config do not affect the model-visible skills list.

This makes it impossible to selectively disable globally installed skills for one repository while keeping them available in other repositories.

For example, this project-local config does not hide codebase-to-course:

# <repo>/.codex/config.toml
[[skills.config]]
name = "codebase-to-course"
enabled = false

Nor does the path selector variant:

# <repo>/.codex/config.toml
[[skills.config]]
path = "/Users/me/.codex/skills/codebase-to-course/SKILL.md"
enabled = false

Running:

codex debug prompt-input 'test skill visibility' | rg 'codebase-to-course'

still shows the skill in <skills_instructions>.

However, the same setting does work when provided from the user config or from session flags:

codex debug prompt-input \
  -c 'skills.config=[{name="codebase-to-course", enabled=false}]' \
  'test skill visibility' | rg 'codebase-to-course'

In that case, the skill is absent from the generated prompt input.

Expected behavior

For a trusted project, [[skills.config]] in <repo>/.codex/config.toml should be able to enable or disable specific skills for that project only, using the same selectors that work in ~/.codex/config.toml and -c.

This would allow a common workflow:

  • Keep useful skills globally installed and available by default.
  • Disable unrelated/heavy skills in specific repositories.
  • Avoid disabling those skills globally for all other projects.

Actual behavior

Project-local [[skills.config]] entries are ignored for skill filtering. Globally installed skills remain visible in that project.

As a partial workaround, this project-local config does work:

[skills]
include_instructions = false

but that disables the entire skill instruction block, rather than selectively disabling a few skills.

Possible cause

From a quick source read, project config itself appears to be loaded, and project-local skills are also treated as skill roots.

But skill_config_rules_from_stack() currently only reads skills.config rules from ConfigLayerSource::User and ConfigLayerSource::SessionFlags, skipping ConfigLayerSource::Project:

if !matches!(
    layer.name,
    ConfigLayerSource::User { .. } | ConfigLayerSource::SessionFlags
) {
    continue;
}

This seems to explain the behavior:

  • ~/.codex/config.toml works because it is a User layer.
  • -c 'skills.config=...' works because it is a SessionFlags layer.
  • <repo>/.codex/config.toml does not work because it is a Project layer.

Why this matters

The docs describe project-local configuration as a configuration layer, and the skills docs describe skills.config as the mechanism for enabling/disabling skills. Users naturally expect those two features to compose.

Selective project-level skill filtering is useful for keeping prompts smaller and avoiding irrelevant automatic skill triggers without losing globally installed skills in other repositories.

View original on GitHub ↗

5 Comments

gabrimatic contributor · 4 months ago

Hi — I have a fix ready for this on a fork branch. Sharing here since external PRs are by-invitation only.

Root cause confirmed

skill_config_rules_from_stack in codex-rs/core-skills/src/config_rules.rs filters layers down to User and SessionFlags only, dropping Project. The check at lines 36–39:

if !matches!(
    layer.name,
    ConfigLayerSource::User { .. } | ConfigLayerSource::SessionFlags
) {
    continue;
}

This matches your analysis exactly. ConfigLayerSource::Project has precedence 25 (between User=20 and SessionFlags=30), so once the layer is permitted, the existing LowestPrecedenceFirst walk already produces the correct override semantics with no further changes.

bundled_skills_enabled_from_stack uses effective_config() (full layer merge), which is why the partial workaround [skills] include_instructions = false already works at the project level — only the per-skill rule path is gated.

There is also direct precedent in the same crate boundary: codex-rs/core/src/exec_policy.rs:538 accepts User | Project as peers for the same kind of layer-source filtering.

Fix

Add Project to the allowlist:

if !matches!(
    layer.name,
    ConfigLayerSource::User { .. }
        | ConfigLayerSource::Project { .. }
        | ConfigLayerSource::SessionFlags
) {
    continue;
}

Regression coverage

Three tests added to codex-rs/core-skills/src/manager_tests.rs:

  • disabled_paths_for_skills_honors_project_layer_name_selector — a Project-only stack disables a skill by name.
  • disabled_paths_for_skills_lets_project_layer_override_user_layer — Project layer correctly overrides a User-layer disable (precedence).
  • skills_for_config_disables_skill_via_project_layer — end-to-end through SkillsManager::skills_for_config with a real Project layer pointing at a <cwd>/.codex folder.

Verification (local)

  • cargo test -p codex-core-skills --lib → 99/99 pass (3 new + 96 existing).
  • cargo clippy -p codex-core-skills --tests -- -D warnings → clean.
  • cargo +nightly fmt -p codex-core-skills -- --check → clean.
  • cargo check -p codex-core → clean (downstream consumer).

Diff stat: 2 files changed, 116 insertions, 1 deletion.

Branch

Branch (forked, ready to cherry-pick or pull): https://github.com/gabrimatic/codex/tree/fix/project-skills-config-filter
Single commit: https://github.com/gabrimatic/codex/commit/0235d76cdc

Happy to open a PR if a maintainer can grant access, or you're welcome to pull the commit directly. Thanks for the very precise bug report — having skill_config_rules_from_stack flagged saved a lot of triage time.

xl-openai contributor · 4 months ago

Hi, thanks for reporting this.

This is actually the current intended design rather than a bug. At the moment, we only support global-level skill enable/disable, as it provides a more consistent overall UX in the Codex app.

etraut-openai contributor · 4 months ago

I'll change this from a bug report to an enhancement request.

skyswordw · 4 months ago

Thanks for clarifying. If global-only skill enable/disable is the current intended design, then treating this as an enhancement request makes sense.

I’d still find project-local selective skill filtering useful for trusted projects, so I appreciate keeping this open for future consideration.

Thanks also to @gabrimatic for confirming the code path and putting together a possible implementation.

etraut-openai contributor · 1 month ago

This feature request hasn't received enough upvotes, so it is being closed automatically. If you still feel this feature is needed, please open a new feature request with an updated title and description.