Symlinked standalone skills inherit plugin namespace from target ancestors
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of Codex is running?
0.147.0
What platform is your computer?
Darwin 25.5.0 arm64 arm
What issue are you seeing?
A standalone skill installed as a directory symlink under the user skills directory inherits a plugin namespace from an ancestor of the symlink target.
The skill is not installed as part of a Codex plugin, and codex plugin list does not list that plugin. Nevertheless, Codex displays the skill as:
foreign-plugin:demo
instead of:
demo
This affects declarative package managers such as Nix/Home Manager, which normally install files by linking them from an immutable store.
Steps to reproduce
Create this source tree:
source/
├── .claude-plugin/
│ └── plugin.json
└── skills/
└── demo/
└── SKILL.md
.claude-plugin/plugin.json:
{
"name": "foreign-plugin"
}
skills/demo/SKILL.md:
---
name: demo
description: Demonstrate symlinked skill discovery.
---
Then symlink only the individual skill into the Codex user skills directory:
$CODEX_HOME/skills/demo -> source/skills/demo
Restart Codex and inspect the skill selector or run:
codex debug prompt-input "diagnostic"
What did you expect to happen?
Following a symlink for file access should not make an individually installed standalone skill inherit plugin ownership from directories above the symlink target.
Codex should use:
- the canonical path for reading and deduplication; and
- the logical discovery path, or explicit plugin installation metadata, for namespace ownership.
The skill should therefore remain demo.
Additional information
Codex canonicalizes the symlinked SKILL.md, treats the canonical target's parent as a namespace root, walks upward outside the configured skills directory, and reads source/.claude-plugin/plugin.json.
Relevant implementation:
codex-rs/ext/skills/src/loader/host.rsload_skills_under_rootcanonicalizes discovered skill paths.- When canonicalization changes the path, it adds the target parent to
namespace_roots.
codex-rs/ext/skills/src/loader/namespace.rsSkillNamespaceResolverwalks upward from those roots and applies the nearest manifest name.
The official documentation says Codex supports symlinked skill folders and follows their targets, but it does not document inheriting plugin metadata from ancestors outside the configured skills root:
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in codex-rs/ext/skills/src/loader/host.rs, then read codex-rs/ext/skills/src/loader/namespace.rs to trace canonicalization and namespace resolution. Reproduce the issue with the supplied symlinked skill and codex debug prompt-input "diagnostic". Done means the skill is displayed as demo and does not inherit plugin metadata from an ancestor outside the configured skills directory.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100