Goal: reduce any skill problem to a single concrete fix. A skill "loading successfully" and a skill "triggering" are two different things — distinguish them first.
A person inspects skills in Settings → Skills and the / menu (the Skills group); an agent inspects by reading the skill files at the locations below.
1. Discovery order (earlier locations take precedence)
- Explicitly configured roots
- User
~/.zcode/skills - User
~/.agents/skills - Workspace
.zcode/skills(from the current directory up to the repository root; every level counts, and a deeper location wins) - Workspace
.agents/skills - Enabled plugin roots (lowest precedence)
Within a level, .zcode is scanned before .agents. A skill's identity is its file path, so same-named skills at different paths are all discovered, but only the first in discovery order is loaded — higher-precedence copies shadow the rest. Directories beginning with . (except .system) and node_modules are skipped.
2. SKILL.md format (two-tier failure model)
A skill is a directory containing a SKILL.md. Frontmatter is a ----delimited block of flat key: value lines (indented keys are ignored; use > or | for multi-line values). The recognized keys are name, description, when_to_use, license, and metadata.
Fails to load (the skill is dropped): frontmatter is present but name is missing, description is missing, or description exceeds 1024 characters.
Loads but may not trigger: no frontmatter at all — name defaults to the directory name and description is empty, leaving the model nothing to match on; a malformed line is skipped.
Triggering: a skill's name, description (truncated to ~250 characters), and when_to_use are presented to the model, which decides on its own whether to invoke the skill. There is no keyword matcher — a description that clearly states "when to use this" is what makes a skill discoverable to the model.
3. How to inspect skills
- In the client: Settings → Skills lists every discovered skill and its group, including a Plugin Skills group for plugin-provided ones. In the input box, type
/and open the Skills group to see what is available and search by keyword. - As an agent: read the
SKILL.mdat each location in discovery order. The file that would actually load is the first one whose frontmattername(or the plugin'splugin:skillqualified name) matches — if that is not the file you edited, you have found a shadow.
4. Common pitfalls (symptom → cause → fix)
- Not discovered — wrong directory — absent from the Skills list. It is not directly under a discovery root, or the file is not named
SKILL.md(case-sensitive on Linux). → Move the skill directory under a real root:~/.zcode/skills/<name>/SKILL.mdor<repo>/.zcode/skills/<name>/SKILL.md. - Skipped inside a dot-directory — a skill under, for example,
~/.zcode/skills/.foo/never appears. Directories beginning with.(except.system) are excluded. → Rename to remove the leading.. - Not triggering — weak or empty description — it appears but the model never invokes it. Without frontmatter the description is empty, and it is truncated to ~250 characters when presented. → Add a frontmatter
descriptionandwhen_to_use, front-loading the trigger wording within the first ~250 characters. - Shadowed by a higher-precedence skill of the same name — your edits have no effect. On load the first same-named skill wins; user overrides workspace overrides plugin, and a deeper working-directory location overrides the repository root. → Find the higher-precedence copy in discovery order and rename or remove it.
- Disabled by configuration — a known-good skill disappears entirely. The configuration disables it by absolute path. → In
~/.zcode/cli/config.json(or the workspace.zcode/config.json), set that path'senabletotrueor remove the override. - Frontmatter parse error or wrong shape —
name/descriptionmissing or garbled. The parser reads only top-level scalars; indented keys are ignored, and multi-line values need>or|. → Keepname/descriptionas top-level scalars and usedescription: >with an indented continuation for long text. - Missing SKILL.md — the directory exists but the skill never appears. → Ensure the file is named exactly
SKILL.md. - Description too long (over 1024 characters) — the skill is dropped. → Trim
descriptionunder 1024 characters and move detail into the body. - An
.agentscopy is shadowed by a same-named.zcodecopy — it is discovered but the.zcodecopy is what loads, because.zcodeis scanned first within a level. → Remove the.zcodeduplicate or rename one. - A plugin skill disappears because the plugin is disabled or suppressed — a disabled plugin contributes no skill roots. → Enable the plugin in Settings → Plugin Management, or remove it from the suppressed-built-ins list.
- Path-versus-name confusion — a skill is invoked by
nameorplugin:skill, not by file path and not with a leading/. → Reference the exact name. - The whole skill subsystem is off — no skills appear and the skill tool reports it is not configured. The skill feature or
skills.enabledis false. → Set both totrue(both default to true).
5. Localization workflow (in order; stop when the cause is found)
- Is the subsystem on? In
~/.zcode/cli/config.json(and the workspace file) confirm the skill feature andskills.enabled; either being false disables discovery — pitfall 12. - Is it discovered at all? Check Settings → Skills, and read the skill files from the same working directory the session runs in (discovery is relative to it). Absent entirely → pitfalls 1, 2, 5, 7, 10, or 12.
- Check for load failures. A skill present on disk but not listed usually has a frontmatter problem: missing
name/description, an over-longdescription, or a malformed frontmatter line — pitfalls 6 and 8. - Which file actually wins? Walk the discovery order for the name and compare the first matching
SKILL.mdto the file you edited. A mismatch means shadowing — pitfalls 4 and 9. - Is it disabled? Look in both configuration files for the skill's absolute path with
enable: false. - A plugin skill? If the name is
plugin:skill, confirm the plugin is enabled and not suppressed. - Discovered but will not trigger? Inspect the
description/when_to_use; empty or overly long/truncated → pitfall 3.