TL;DR: Before a Skill can reach Claude's candidate list, Claude Code must discover its directory, combine sources, resolve names, and apply path and invocation visibility rules. Personal, project, enterprise, and plugin locations represent different ownership models, not merely four installation paths. Nested Skills and
pathsnarrow “available in this project” to “relevant to the files being worked on.”
Part 2: From Description to Full Instructions followed one Skill through three loading stages: metadata for discovery, full instructions on activation, and supporting resources when needed.
But where does that metadata come from? Claude Code does not search every SKILL.md on your computer. First, it must answer a more basic question:
Which Skills are eligible to be candidates in a session started from this working directory?
Discovery has three gates
Creating a Skill on disk does not mean Claude can use it. At least three decisions stand between the file and execution:
Filesystem discovery
Does Claude Code load Skills from this location?
↓
Candidate exposure
May this Skill appear among Claude's available capabilities?
↓
Task matching and activation
Should this request load its full instructions?
People often call all three “automatic discovery.” That hides distinct failures:
- Put the file in the wrong location, and the first gate never opens.
- Make a Skill user-invocable only, and the file may exist without being advertised to the model for automatic selection.
- Write a description that does not match the task, and Claude may know the Skill exists but not select it.
- Apply a path condition that does not match the current files, and a project Skill is not relevant yet.
When a Skill fails to trigger, do not repeatedly rewrite its description until you have confirmed that it actually entered the candidate set.
Four scopes, four ownership relationships
The Claude Code Skills documentation identifies four principal distribution sources:
| Scope | Typical location | Maintainer | Reach |
|---|---|---|---|
| Enterprise / managed | Managed settings directory, .claude/skills/<name>/SKILL.md
|
Administrator | Users whose machines receive the managed configuration |
| Personal | ~/.claude/skills/<name>/SKILL.md |
Individual user | That user's local projects |
| Project | .claude/skills/<name>/SKILL.md |
Project team | Sessions in the repository |
| Plugin | <plugin>/skills/<name>/SKILL.md |
Plugin author | Environments where the plugin is enabled |
These may look like four paths, but they encode four different kinds of ownership.
Personal: my general way of working
Personal Skills fit reusable practices that cross projects without requiring everyone on the team to install them: a private review routine, a note-organizing workflow, a generic commit-message helper, or a wrapper around tools available on your machine.
They follow the user, not the repository. A teammate who clones the repository does not automatically get them.
Project: a practice owned by this repository
Project Skills can be versioned with the code: a release checklist, a repository-specific migration procedure, an internal architecture-document generator, or a test workflow tailored to the project.
This scope says that people working on the project may need the capability. Committing it also makes changes reviewable alongside code.
Enterprise: an organization-provided capability
Managed Skills suit centrally deployed processes, knowledge, and governance requirements. The author and user may be different: a user can invoke a Skill without being able to edit its source.
This is about organizational consistency, not personal reuse. Central distribution of instructions, however, should not be mistaken for enforcement; permissions and execution boundaries are separate concerns.
Plugin: a capability in an installable component
A plugin can distribute Skills with supporting scripts, assets, subagents, hooks, MCP server configuration, and other extension content. Its Skills use the plugin namespace, such as /plugin-name:skill-name, rather than competing for a bare name with personal or project Skills.
The first question when choosing a scope is who owns this capability?, not which folder is easiest to write to.
Scope is not synchronization
A personal Skill being available in local projects does not mean its files automatically reach another machine or Claude surface. Likewise:
- A project Skill travels with Git only if it is committed.
- A plugin Skill travels through plugin installation and versioning.
- A local Claude Code Skill does not automatically become a Claude API or claude.ai Skill.
- A cloud session cannot simply read your machine's
~/.claude/skills/.
Claude Code now also supports Skills synced from a claude.ai account in eligible sessions, but that is a separate sync mechanism, not a property of every local personal Skill. Scope answers who should see a capability in one environment; synchronization answers how its files get there.
Project discovery does not stop at the current directory
In a monorepo, reading only the current directory's .claude/skills/ would be surprising. If a session starts in repo/apps/web/, should the root-level release Skill disappear? Claude Code searches the start directory and its parents up to the repository root:
repo/apps/web/ ← session starts here
↑ parent
repo/apps/
↑ parent
repo/ ← repository root
└── .claude/skills/release-check/
The shared root capability remains available regardless of which package you start in. Upward discovery solves inheritance, but monorepos also need the opposite: a package may have its own local Skills.
Nested Skills appear with the subdirectory
Suppose the frontend package has a distinct deployment procedure:
repo/
├── .claude/skills/deploy/SKILL.md
└── apps/web/
├── .claude/skills/deploy/SKILL.md
└── src/
The root deploy is the project default; the one under apps/web is a frontend variant. Recursively scanning the entire monorepo at startup could flood the candidate list with Skills from unrelated packages, examples, and dependency trees.
Instead, Claude Code discovers nested .claude/skills/ directories as work moves into their file trees:
Working only in repo/backend/
→ the apps/web Skill need not appear
Working in repo/apps/web/src/
→ apps/web/.claude/skills/ becomes relevant
A nested Skill is not simply “a higher-priority project-wide setting.” It is a local capability whose relevance follows the work path.
Name collisions are not always simple overrides
For enterprise, personal, and project Skills with the same name, the documented precedence is:
Enterprise > Personal > Project
Nested variants are a different case. Both the root deploy and the apps/web variant can be useful. Silently replacing one with whichever is closest would discard information. Claude Code keeps both: /deploy can identify the root Skill, while a qualified name such as /apps/web:deploy explicitly identifies the nested one.
This preserves three useful distinctions:
- The bare name remains the main project entry point.
- The qualified name identifies the directory that owns the variant.
- Claude can consider which files it is actually working on.
Sometimes a same-named Skill is not an accidental conflict but a package-specific supplement to a global process. Plugin Skills avoid this particular collision by using /plugin-name:skill-name from the start.
paths: relevance without a duplicate Skill folder
Not every path-sensitive capability needs its own nested directory. An API review Skill might be owned at the repository root but become automatically relevant only for interface files:
---
name: api-review
description: Reviews this project's API design and compatibility
paths:
- "services/api/**"
- "packages/contracts/**"
---
paths separates ownership from activation:
- Ownership: The project maintains one shared Skill.
- Automatic relevance: Claude loads it when working with files that match the patterns.
| Mechanism | Best fit |
|---|---|
| Nested Skill | A subdirectory owns an independent capability or local variant |
Root Skill with paths
|
The project owns one capability that applies only to specific files |
paths is not a filesystem permission or sandbox. It governs automatic activation, not which files Claude may read. Treating a relevance filter as a security boundary would overstate what frontmatter can enforce.
--add-dir: a separate route into discovery
--add-dir gives Claude access to another directory, and Claude Code also watches that directory's .claude/skills/ for Skills. This is useful when shared capabilities live outside the product repository:
product-repo/
shared-engineering/
└── .claude/skills/
├── incident-review/
└── architecture-check/
Add shared-engineering when starting the session, and its Skills become available. Do not generalize that into “all Claude configuration in an added directory loads the same way.” The documentation distinguishes Skills from commands, agents, and other configuration, and behavior can depend on settings. This is a Skill-discovery rule, not ordinary file access alone.
Live detection: the list can change during a session
Claude Code watches Skill locations it has included in discovery. Adding a Skill, editing SKILL.md, or removing a Skill can update the candidate list during the session. A caveat: if a top-level Skills directory did not exist when monitoring began and is created only later, a restart may be needed.
Live detection updates the disk definition and candidate listing. It does not rewind a conversation to replace instructions already loaded into context. The source file, candidate metadata, and active instructions are three different states; the later lifecycle article explores this further.
Symlinks: shared source without duplicate capabilities
Enterprise, personal, and project Skill folders can be symlinks to directories elsewhere on disk. Claude Code resolves the target and avoids loading the same Skill twice merely because multiple locations point to it. Plugin symlinks follow their own distribution rules.
For authors, symlinks are convenient during personal development or when maintaining one local source. For stable team distribution, a plugin or an explicitly versioned project Skill is generally easier to review.
The candidate list is not a disk listing
After all these steps, not every Skill that exists on disk is exposed to Claude in the same way:
- A user-only Skill does not need a description to prompt model invocation.
- A path-constrained Skill may not match the files currently being worked on.
- A nested Skill may not have been discovered yet.
- Visibility settings or runtime modes may hide a capability.
- Precedence, namespaces, and qualified names may reorganize overlapping sources.
The candidate list is a runtime view of capabilities for this session:
Skill definitions on disk
↓ scope / parent / nested / added directory
Discoverable set
↓ precedence / namespace / path / visibility
Current candidate list
↓ description and user request
Activated Skill
Separating these stages reveals whether a failure lies in installation, scope, exposure, or task matching. Skill discovery is not just find SKILL.md: scope determines ownership, parent and nested lookup determine inheritance, namespaces let variants coexist, and paths determine relevance. Only after a Skill reaches the list can its description perform the routing discussed in Part 2.
Up next
Once the candidate list exists, we can revisit the Tool-like selection behavior. Do /release-check from a user and Claude's own choice of release-check follow the same path? Part 4 will separate manual invocation, model invocation, bundled Skills, and built-in commands.
References
- Claude Code documentation: Where Skills load, discovery, precedence, and configuration
- Previous article: From Description to Full Instructions
- Related future reading: the Claude Code Memory series on the
CLAUDE.mdhierarchy.
Top comments (0)