The 4-layer skill format
On this page
A complete skill ships two things in one signed package:
The 4-layer format: content folders an agent reads and drills into.
The guidance block in
client/schema.yaml: metadata the platform reads to decorate every reply with_guidance,telemetry_signaland, on request,_findings.
Ship only one and the skill is half-built. For the craft of making each layer hold up, read Write skills that hold up.
Folder layout
skills/<your-skill>/
├── SKILL.md ← Layer 1: the router (required)
├── client/
│ └── schema.yaml ← API surface + guidance block
├── references/ ← Layer 2: procedures (recommended)
│ └── <task-name>.md
├── learnings/ ← Layer 3: lessons with provenance (recommended)
│ └── <yyyy-mm-dd-slug>/
│ ├── metadata.json
│ └── artifacts/what-we-learned.md
├── registry/ ← Layer 4: typed assets agents install (recommended)
│ ├── registry.json
│ └── <item-name>/
│ ├── registry-item.json
│ └── <asset files>
└── scripts/ ← optional: checks the agent runs on its own work
└── verify-<thing>.mjsLayer 1: SKILL.md, the router
At most 500 lines, with frontmatter. The body is a decision tree that points at references/ files, not a manual. The description: line is the trigger: list every verb and noun an agent might meet, then name the sibling skills to use instead.
Put in it: frontmatter (name, description, version, and optionally category, triggers, requires_auth, vendor, entitlements); at most one <HARD-GATE> block for the single riskiest mistake; a table "if the user wants X → read references/X.md"; a short list of anti-patterns; and pointers to learnings/, registry/ and scripts/.
Layer 2: references/, procedures
One Markdown file per task or per trap, 50 to 200 lines each. Two shapes:
WRONG / RIGHT to teach a trap: the broken version, then the fix, with real values.
Steps / Gotchas / Verify to teach a multi-step job.
Every MUST is followed by why, so the agent can judge edge cases. Agents on OPVS read these with skill_read_reference; agents on other tools read the files after install.
Layer 3: learnings/, what you learned
One folder per lesson:
metadata.json:title,summary,created_at,updated_at,references[](provenance: the issue, incident or change that produced it), and optionallytags[]andstale_after.artifacts/what-we-learned.md: the lesson itself, plus any supporting files.
Agents read every summary and open the artifact only when it matches the task, so the summary is the trigger. Provenance in references[] is required for published learnings. Tell agents in SKILL.md that learnings are starting points to check, not ground truth.
Layer 4: registry/, assets agents install
Things the agent installs instead of writing: board templates, document starters, prompt packs, HTML components. Each item has its own folder with a registry-item.json and its files.
Required fields in registry-item.json: $schema, name, type, title, description, version, vendor, skill, files. Add preview for items with a visible surface, and references[] provenance for published items. type is one of opvs:block (drop-in), opvs:component (parameterised), opvs:template (multi-file starting point) or opvs:blueprint (multi-skill workspace setup).
Each item has its own semver, independent of the skill, and belongs to exactly one skill (the skill field).
scripts/, optional
Deterministic checks the agent runs on its own work and pastes the output of. Name each one in SKILL.md so the agent knows when to run it.
The guidance block
Add it to client/schema.yaml, next to your methods.
guidance: # skill level
use: "what this skill is for, one line"
not:
- "<sibling-skill> → what to do instead"
intent_aliases: # every name a free-text input goes by
- "query"
- "search"
pitfalls:
- "<the top gotcha, one sentence>"
methods:
getThing:
description: Plain-English summary.
guidance: # method level
use: "when an agent should call this"
next: "updateThing, listThings"
warn: "the one thing that catches first-time callers"
telemetry_signal_default: "warm"
http: GET /things/{id}
params:
id: { type: uuid, required: true, description: The thing's id. }
response:
format: yamlThree rules apply to every vendor:
Rule | What it means for you |
|---|---|
Declare | If any method takes a free-text search input, list every name it goes by under |
| When a caller sends |
| Set |
Nested object and array parameters
Declare the full shape inline; every generator then emits the nested JSON Schema and agents see the sub-fields.
params:
workflow:
type: object
required: true
description: The workflow to run.
properties:
smartlead:
type: object
properties:
connection_id:
type: string
required: true # per-field required, not a sibling list
description: Smartlead account connection id.
admin_regions:
type: array
items:
type: object
properties:
country: { type: string, required: true, description: ISO country code. }
cities: { type: array, items: string }Each sub-field carries its own
required. There is no siblingrequired: [names]list.itemsis a type name (items: string) or a full object spec.Validation reaches every level and reports a dotted path. Nesting is capped at 12 levels.
oneOf,allOf,anyOfand$refpass through but are not validated.A schema never restricts what callers send: undeclared keys still reach your API; a mismatch only produces a warning.
What happens at runtime
The envelope is added by the platform. It reads your
guidanceblock and decorates each reply. You write no code for it.The layer files travel with the install. Agents open
references/,learnings/andregistry/files directly, with no API call.
Packaging the layers
Nothing extra is needed in package.yaml: the publish command packs the whole package folder (minus a fixed exclude list), so new folders are included and signed automatically. See The package manifest.
Adding the layers to an existing skill is a minor version bump.
Bump a registry item's own
versionwhen you change a file inside it.
Questions
Do I need all four layers? No. Only SKILL.md is required. Ship at least one references/ file so the agent has somewhere to drill into.
Can I publish without the guidance block? Yes, but agents lose the per-method next and warn hints. Ship it.
Is a learnings folder the same as LEARNINGS.md? No. The security review looks for root files (README.md, SKILL.md, CHANGELOG.md). learnings/ inside a skill is the structured lesson format.
My skill teaches a method rather than calling an API. What then? Publish it guidance-only: no methods: in schema.yaml, rich references/. Never declare a method you do not serve, or every call to it fails.