Skill format
This page defines what Syllabus accepts in a skill: its folder, its SKILL.md file, and the Syllabus keys in its metadata. The same format applies to every skill a repository authors, whether it’s a library, a project, or both. For how to write a skill well, see Write a skill.
A skill uses the Agent Skills format. Syllabus adds three optional metadata keys and checks the rest of the format as the Agent Skills specification defines it, so a skill that passes syllabus library check also works in tools that read Agent Skills directly.
Skill folders
Section titled “Skill folders”A repository’s authored skills live in .syllabus/skills/, one folder per skill, beside rules/. Project files shows the whole layout.
skills/ build-feature/ SKILL.md references/ slicing.md scripts/ verify.sh review-tests/ SKILL.mdEach skill folder holds a SKILL.md file and anything the skill bundles. The Agent Skills format suggests scripts/ for code the agent runs, references/ for documents it reads when needed, and assets/ for templates and other files it uses, but any layout inside the folder works. The assets/ folder inside a skill belongs to the skill; it isn’t a rule asset directory, and the shared .syllabus/assets/ directory isn’t part of any skill.
skills/ holds only skill folders, and is flat: a skill folder can’t contain another skill’s SKILL.md, and it can’t contain _group.yaml. Skills don’t belong to rule groups, so a skill folder is never inside rules/.
Git-tracked files
Section titled “Git-tracked files”A skill’s content is the files Git tracks in its folder. Files Git ignores, such as __pycache__/, node_modules/, or .venv/ that a skill’s scripts create, are neither versioned nor installed. syllabus library check warns about a file in a skill folder that Git neither tracks nor ignores, because it isn’t part of the skill until you commit it. A repository outside Git has no library releases, and Syllabus reads every file in each skill folder.
Symbolic links, submodules, and Git LFS pointers aren’t supported in a skill folder, as for every file Syllabus takes from a source.
File modes
Section titled “File modes”A file’s executable bit is part of the skill’s content. Git records it as mode 100755 for an executable file and 100644 for any other file. Syllabus keeps the mode in a project’s vendor snapshot and in every installed copy, so a step that runs ./scripts/verify.sh works after install. Changing only a file’s mode is a change to the skill, and after the first library release it needs a change note, like any other change.
File contents
Section titled “File contents”Markdown files in a skill folder, including SKILL.md, must be UTF-8, so their links can be checked. Other files can be binary; Syllabus keeps their original bytes. The source limits on file size and count apply to skill files as to any other vendored file.
Skill IDs
Section titled “Skill IDs”A skill’s ID is its folder’s path in the repository that holds it. For a skill a repository authors, that’s its path in the Syllabus directory, skills/<name>, such as skills/build-feature. For a skill in a non-library source, it’s the folder’s path from the repository root, such as skills/engineering/to-spec. A skill’s identity is its repository plus its ID, so two sources that reach the same repository name the same skill.
In a project, an ID from a source is qualified by the source name the project chose, such as fabrica:skills/build-feature. A skill a library borrows adds the borrowed source’s name, such as fabrica:mattpocock:skills/engineering/to-spec. An authored skill’s ID has no source name. See Source names and IDs.
<name> follows the Agent Skills name grammar:
- 1 to 64 characters,
- only lowercase letters
a–z, digits0–9, and hyphens-, - not starting or ending with a hyphen, and
- no two hyphens in a row.
The folder name is the skill’s name, and it must equal the name field in its SKILL.md. Renaming the folder changes the skill’s ID. In a library, a rename retires the old ID, replaced by the new one; see Retire or replace a skill. A retired skill’s ID can’t be reused.
The name is also the skill’s install name, the folder name of every installed copy, such as .claude/skills/build-feature/, so two skills with the same name can’t be installed in one project, even from different sources. A project resolves a clash by renaming one of them, which changes the install name but not the ID.
Frontmatter
Section titled “Frontmatter”SKILL.md starts with YAML frontmatter, from the first byte of the file, followed by a non-blank Markdown body with the skill’s instructions:
---name: build-featuredescription: Build a feature from an agreed spec, one slice at a time. Use when starting implementation of a new feature or a change to an existing one.license: MITmetadata: syllabus-skill-type: playbook syllabus-rules-used: | practices/architecture/decide-module-boundaries-first practices/testing/test-behavior-not-implementation syllabus-skills-used: | skills/tdd---
1. Read the spec and name the slice you're building.2. ...These are the Agent Skills fields. Unknown top-level fields are rejected, because tools that read Agent Skills, such as claude.ai, reject them too.
| Field | Meaning |
|---|---|
name | Required. The skill’s name, following the name grammar. Must equal the folder name. |
description | Required. One non-blank string of at most 1,024 characters saying what the skill does and when to use it. Agents read it to decide when to load the skill, so name the task that should trigger it. |
license | Optional string naming the skill’s license, such as an SPDX expression. Informational in a library; see Licenses. |
compatibility | Optional non-blank string of at most 500 characters describing what the skill needs to run, such as tools, network access, or a product. |
allowed-tools | Optional string listing tools the skill is approved to use, separated by spaces, as the Agent Skills format defines it. Syllabus preserves it and doesn’t interpret it. |
metadata | Optional map of string keys to string values. Syllabus reads the three keys below and preserves every other key unchanged. |
The frontmatter uses one YAML document. Duplicate keys, anchors, aliases, and explicit tags are rejected. A value that YAML reads as something other than a string, such as true or 2026-10-14, must be quoted where a string is required.
A skill has no version field, and no metadata key sets its version. In a library, its version comes from library releases; see How a skill is versioned.
Metadata
Section titled “Metadata”Syllabus adds three optional keys under metadata. Each value is a string, as the Agent Skills format requires, so the file stays valid everywhere skills are read.
| Key | Value | Checks |
|---|---|---|
syllabus-skill-type | playbook or review | Must be a type on the canonical list. Unknown values fail syllabus library check. |
syllabus-rules-used | The IDs of the rules the skill applies, one per line | Each must be a current rule in this repository, or, outside a library, in a source the project names. |
syllabus-skills-used | The IDs of the skills this skill calls, one per line | Each must be a current skill in the same repository, other than this one, and the skills called can’t form a cycle. |
Other metadata keys, such as author, are preserved and ignored. Keys that start with syllabus- are reserved for Syllabus, so any other syllabus- key fails syllabus library check.
Skill type
Section titled “Skill type”syllabus-skill-type labels the skill as a playbook or a review; see Skill types. Leave it out when neither fits. The type is a plain label: Syllabus shows it, and syllabus project list skills --type filters by it, but it installs, checks, and updates every skill the same way, whatever its type.
The canonical type list is canonical-skill-types.yaml in the Syllabus repository. Each Syllabus release builds the list in, so a new type needs a Syllabus release, and your library’s CI must use that release before a skill can declare the type. Only syllabus library check checks the type: a project installs a skill whose type its Syllabus doesn’t know without complaint, and shows the type as written.
Rules a skill applies
Section titled “Rules a skill applies”syllabus-rules-used lists the rules the skill applies, one library rule ID per line, in a YAML block string:
metadata: syllabus-rules-used: | practices/architecture/decide-module-boundaries-first practices/testing/test-behavior-not-implementation practices/verification/verify-on-the-surface-users-touchIn a library, each line is a rule ID in this library: the rule’s path in rules/ without .md, and without a source name, because each project chooses its own source names. Surrounding whitespace and blank lines are ignored. Each ID can appear once. A library’s skill can cite rules from any rule group in its library, and only rules in its library. A skill in a repository that isn’t a library can also cite its sources’ rules by project ID; see Skills in a project.
When a project installs the skill, Syllabus takes every cited rule, even ones the project’s rule include doesn’t name, and appends a generated section to the installed SKILL.md that links to the project’s version of each one. Cited rules are for reference only: they never join RULES.md. See Installed copies.
Skills a skill uses
Section titled “Skills a skill uses”syllabus-skills-used lists the other skills this skill calls, one skill ID per line, in the same form:
metadata: syllabus-skills-used: | skills/architect skills/tddEach line is a skill ID in the same repository, skills/<name>. A skill can’t call itself, and the skills called can’t form a cycle, directly or through other skills. When a project installs the skill, Syllabus also installs every skill it calls, and the skills those call in turn, from the same repository and revision. A project declares calls a skill’s metadata leaves out with skills.uses; Syllabus doesn’t search skill text for them.
Links in a skill’s Markdown files must be absolute URLs, such as https://agentskills.io, or relative paths that stay inside the skill’s own folder, such as references/slicing.md or scripts/verify.sh. Installed copies are self-contained, so a skill can’t link to a rule file, another skill, the shared assets/ directory, or any other file in the repository. Cite rules with syllabus-rules-used instead, and the installed copy links to the project’s version of each one.
Syllabus checks Markdown links, images, reference definitions, and the href and src attributes of HTML. Relative links must point to a file that exists in the skill’s folder. Links to a heading in the same file, such as #verify, are allowed. Syllabus keeps external URLs as links and never downloads them. Files other than Markdown, such as scripts, aren’t checked for links.
Licenses
Section titled “Licenses”A library’s license, declared in its manifest, covers its skills as it covers its rules. The license field in SKILL.md is informational: Syllabus preserves it, and when it differs from the library’s SPDX expression, syllabus library check warns. Skills from a non-library source have no library declaration, so their license comes from the skill or the repository instead. See License rules.
Validation
Section titled “Validation”syllabus library check validates every skill in the library, whatever a project selects. It reports every skill problem it finds, one per line, each starting with the file or folder it’s about, and fails with the code invalid-skill:
$ syllabus library checkError: skills don't pass library check: - skills/build-feature/SKILL.md: syllabus-rules-used names practices/testing/test-behaviour-not-implementation, which isn't a rule in this library - skills/build-feature/SKILL.md: syllabus-skills-used names skills/tdd-loop, which isn't a skill in this library - skills/build-feature/SKILL.md: syllabus-skill-type is design; use playbook or review, or leave it outCheck fails with these problems:
| Problem | Message |
|---|---|
A file directly in skills/ | skills/README.md: skills/ holds only skill folders |
| Two skills the manifest lists, authored or borrowed, with the same name | library.skills lists skills/review and mattpocock:skills/review, which both install as review; list one of them, or rename the folder of your own skill |
| A skill listed in more than one level | library.skills lists skills/fix-bug as both required and recommended; list it once |
| A listed skill that doesn’t exist | library.skills.recommended names skills/fix-bugs, which isn't a skill in this library |
A borrowed skill whose source isn’t in sources, or that the source doesn’t have at its ref | library.skills.offered names mattpocock:skills/productivity/grill, which mattpocock doesn't have at main |
| A folder name that breaks the name grammar | skills/Build_Feature: a skill name uses 1 to 64 lowercase letters, digits, and hyphens, without a leading, trailing, or doubled hyphen |
A skill folder without SKILL.md | skills/build-feature: expected SKILL.md in the skill folder |
| A skill inside another skill’s folder | skills/build-feature/steps/SKILL.md: a skill folder can't contain another skill; move it to its own folder in skills/ |
| Rule group metadata in a skill folder | skills/build-feature/_group.yaml: a skill folder can't contain group metadata |
| A symbolic link, submodule, or Git LFS pointer | skills/build-feature/scripts/verify.sh: symbolic links, submodules, and Git LFS pointers aren't supported in a skill folder |
| A Markdown file that isn’t UTF-8 | skills/build-feature/references/slicing.md: expected UTF-8 Markdown |
No frontmatter at the start of SKILL.md | skills/build-feature/SKILL.md: expected YAML frontmatter at the start of the file |
| Invalid YAML, such as a duplicate key or an alias | skills/build-feature/SKILL.md: followed by the YAML problem and its line |
| A blank body | skills/build-feature/SKILL.md: expected instructions after the frontmatter |
| An unfinished draft | skills/build-feature/SKILL.md: complete the draft and remove its syllabus:draft marker |
| An unknown top-level field | skills/build-feature/SKILL.md: unknown field version; SKILL.md accepts name, description, license, compatibility, allowed-tools, and metadata |
A missing or blank name or description | skills/build-feature/SKILL.md: description is required |
A name that differs from the folder name | skills/build-feature/SKILL.md: name is build-features, but the folder is build-feature; they must match |
A description over 1,024 characters | skills/build-feature/SKILL.md: description is 1,310 characters; use at most 1,024 |
A compatibility over 500 characters, or blank | skills/build-feature/SKILL.md: compatibility is 612 characters; use at most 500 |
A field or metadata value that isn’t a string | skills/build-feature/SKILL.md: metadata.syllabus-skill-type must be a string |
A reserved syllabus- key Syllabus doesn’t define | skills/build-feature/SKILL.md: metadata.syllabus-groups isn't a Syllabus key; use syllabus-skill-type, syllabus-rules-used, or syllabus-skills-used |
| A type that isn’t on the canonical list | skills/build-feature/SKILL.md: syllabus-skill-type is design; use playbook or review, or leave it out |
| A cited rule that doesn’t exist | skills/build-feature/SKILL.md: syllabus-rules-used names practices/testing/test-behaviour-not-implementation, which isn't a rule in this library |
A cited rule with a source name or .md | skills/build-feature/SKILL.md: syllabus-rules-used names fabrica:practices/testing/test-behavior-not-implementation; cite a rule by its ID in this library, such as practices/testing/test-behavior-not-implementation |
| A cited rule that a library release or a pending change note retired, with a replacement | skills/build-feature/SKILL.md: syllabus-rules-used names practices/testing/check-retry-backoff, which is retired and replaced by practices/testing/verify-retries; cite the replacement |
| A cited rule that was retired without a replacement | skills/build-feature/SKILL.md: syllabus-rules-used names practices/code-design/comment-intent, which is retired; remove it |
| An ID listed twice | skills/build-feature/SKILL.md: syllabus-rules-used names practices/testing/verify-retries twice |
| A used skill that doesn’t exist | skills/build-feature/SKILL.md: syllabus-skills-used names skills/tdd-loop, which isn't a skill in this library |
| A used skill that is retired | skills/build-feature/SKILL.md: syllabus-skills-used names skills/triage-bug, which is retired and replaced by skills/fix-bug; use the replacement, or which is retired; remove it when nothing replaces it |
| A skill that uses itself | skills/build-feature/SKILL.md: syllabus-skills-used names the skill itself |
| Skills that use each other in a cycle | skills/build-feature/SKILL.md: syllabus-skills-used forms a cycle: skills/build-feature -> skills/tdd -> skills/build-feature |
| A link that leaves the skill folder | skills/build-feature/SKILL.md: link leaves the skill folder: ../../practices/testing/verify-retries.md; link inside skills/build-feature/ or use an absolute URL |
| A relative link to a missing file | skills/build-feature/SKILL.md: link target doesn't exist: references/slices.md |
| A skill that reuses the ID of a retired skill | skills/triage-bug reuses the ID of a skill that release/5 retired. Retired IDs can't be reused; give the skill a new ID. |
After the first library release, check also compares every skill with the latest library release and fails, with the code change-notes, when a skill’s change notes don’t match its changes, exactly as for rules. See Change notes and library check.
Check warns, without failing, when:
- A skill’s
licensediffers from the library’s declared SPDX expression:skills/build-feature/SKILL.md: license is Apache-2.0, but the library declares MIT. The library's license applies to its skills; make them match. - A skill declares a
licenseand the library declares none:skills/build-feature/SKILL.md: license is MIT, but the library declares no license. Declare the library's terms in library.license. - A file in a skill folder is neither tracked nor ignored by Git:
skills/build-feature/scripts/new-check.sh isn't tracked by Git, so it isn't part of the skill. Add it with git add, or ignore it.
To find borrowed skills’ names, check reads each borrowed source at its ref, so it needs access to those repositories.
Check validates the format, not whether the steps are good. Use Write a skill to review a skill’s guidance.
Installed copies
Section titled “Installed copies”When a project installs a skill, Syllabus writes a copy of its folder into each of the project’s skill targets, such as .claude/skills/build-feature/. Every file is copied as the source has it, with its executable bit, and SKILL.md gets two changes, plus a new name when the project renames the skill:
-
A marker comment becomes the first line after the frontmatter, so the frontmatter still starts the file:
<!-- syllabus:installed fabrica:skills/build-feature 1.3.0. Do not edit; fork it with syllabus project add skill --from. --> -
When the skill cites rules, a generated Rules this skill applies section is appended at the end. It links to the project’s version of each rule the skill cites, including an authored rule that replaces one, and marks a rule the project excluded. A Skills this skill uses line follows when the skill calls others.
Don’t edit installed copies: sync rewrites them, and syllabus project check fails when one differs from what sync would write. Installed skills shows the complete generated section and how Syllabus records the folders it owns.
Skills in a project
Section titled “Skills in a project”A repository that isn’t a library authors skills in the same .syllabus/skills/<name>/ folders, with the same format, and two differences:
- They can cite rules and call skills from the project’s sources, by project ID with the source name, because a project can use several sources:
fabrica:practices/testing/test-behavior-not-implementationorfabrica:skills/tdd. Bare IDs, such aspractices/architecture/follow-bounded-contexts, name the repository’s own rules and skills. Syllabus takes each cited rule, and installs each called skill, from the source it names. - They have no versions and need no change notes.
syllabus project add skill creates one, and syllabus project add skill --from forks a skill from a source into one; see project add skill. Sync and build validate these skills with the checks above and fail on the first problem. syllabus project check also fails when one cites a rule its library retired, naming the replacement when there is one, so a project’s skills never point at a rule that’s gone.
Skills from non-library sources
Section titled “Skills from non-library sources”A repository without a library manifest, such as a third party’s skill collection, can supply skills too. Each folder in it that has a SKILL.md file is a skill, and its ID is the folder’s path from the repository root, such as skills/engineering/to-spec. Syllabus checks these skills leniently: where a skill breaks this format, such as a name that doesn’t match its folder, a missing description, or a link outside its folder, sync warns and installs the skill as it is. The checks that protect your project still fail: unsafe paths, symbolic links, submodules, Git LFS pointers, and the source limits. A non-library source’s syllabus-rules-used lists are ignored, because it has no rules. Its syllabus-skills-used lists name skills in the same repository; the project declares calls they leave out with skills.uses. See Non-library sources.
Related pages
Section titled “Related pages”- Skill explains what a skill is and how it relates to rules.
- Write a skill walks through writing, checking, and versioning a skill.
- Library format covers where skills live in a library.
- Rule and skill versions defines what a skill version covers.