agentSkill
A skill packages what an agent needs to do one job well: the instructions, the assets and toolboxes the job runs through, and — for jobs with distinct branches — subskills that go deeper.
Skills advertise themselves. Every registered skill's name and one-line description rides the agent's tool responses, so an agent discovers what this world knows how to do without being told to look. Invoking one returns the instructions plus the exact identities and tool names the job needs.
Shape
<name>.agentSkill/
skill.yaml # the manifest: description, when, checks, dependencies, order
instructions.md # the prose an agent receives on invoke
README.md # what this skill is, for a human reading the tree
.metadata # tags
<sub>.agentSkill/ # optional subskills, reachable as <name>/<sub>
The manifest
$schema: zero/agent-skill/v1
description: Making a character a person can actually play.
when: >
Reach for this when the player should look like something else, or when
you are about to build a camera and a body and wire them together by hand.
checks:
- check: Holding a movement key in play moves the body across the ground.
observe: Read its position before and after holding the key; the numbers differ.
- check: The body animates while it moves.
observe: A time-sampled collage from a camera outside the player, while the key is held.
dependencies:
- "@builtin::tools.scene"
- "@builtin::tools.scene.player"
- "@builtin::components.PlayerPrototype"
- "@builtin::docs.core.multiplayer"
order: [spawn-points, camera-rig]
description is the line the roster carries, and the whole basis on which a
skill is chosen. Name the job the skill makes a reader competent at, in the
outcome they are after — "getting a scene's player and view right", "making
content the engine will load". A reader scanning the roster is matching it
against the job in front of them, so the closer it reads to their own
sentence about that job, the sooner they open it.
when is the longer trigger — the situations that should send a reader here,
in the words they would use for their own task.
checks is what the reader is answerable for at the end, and it leads the
rendered skill, ahead of the procedure. Each entry pairs a condition that
must hold with where it is seen, and both halves are required — a
condition alone is satisfied by any glance, and the wrong vantage is how a
job passes while every one of its faults sits outside the frame. Write them
as observations someone else could repeat and disagree with: a number that
changed, a thing visible in a named shot, a count that came back as one.
A skill publishes only once it carries at least one.
stages models a skill whose passes run in order, when the order is
load-bearing. Each stage is { name, detail?, checks? }, and a check that
sits in a stage is answered after that pass has run — which is the difference
between a criterion that means something and one that misleads. A skill with
no meaningful order leaves stages out and lists its checks flat; a skill
that has one may do both, and the flat checks then read as the final gate.
verdicts names the fixed set of outcomes a reader reports — at the end of
each stage when the skill has stages, and once at the end when it does not.
Each is { verdict, means }: the word, and what reporting it asserts. Both
halves are required for the reason both halves of a check are. A verdict is a
check one level up, deciding a whole pass rather than one condition, and a
bare refine is a label each reader fills in privately — so two runs report
the same word about different states and nothing downstream can tell them
apart. Saying what it means settles the boundary in the skill instead of in
whoever happens to be reading it.
A check marked perRun: true is one whose content is written for the job at
hand: the manifest can say keep a list of every feature this object must
have and answer against it, but not what is on that list, because that is
per run. It renders with that instruction attached.
verdicts:
- verdict: continue
means: Every check in the stage held, and the next stage can build on it.
- verdict: refine
means: A check failed on something this stage can still fix. Run it again.
- verdict: stop
means: A check failed on something an earlier stage decided. Go back to it.
stages:
- name: blockout
detail: Mass and proportion only.
checks:
- check: Every part on the identity list has a stand-in at roughly the right size.
observe: A capture beside the reference, at the same angle.
perRun: true
- name: material
checks:
- check: Metal reads as metal and cloth as cloth.
observe: The metallic and roughness passes, after the lighting stage has run.
dependencies is one flat list of asset identities: a toolbox, a single
tool, a guide, a component, a module, another skill. Each entry is resolved
when the skill is opened and reported with what it turned out to be, so a
skill never declares "this one is a toolbox" — the asset says so, and the
reader groups by that.
Identities are what make a skill portable. They pin like any other reference,
so installing a skill into another world brings the toolboxes and guides it
runs through along with it. A bare name (scene) or a guide path
(core/multiplayer) resolves to nothing and is refused before publish.
A toolbox entry lists the tools it carries, and a tool entry carries its own signature, so the instructions never restate a call contract that can drift. An identity this world lacks is reported as missing rather than dropped.
Write instructions that name the toolboxes and tools a job runs through, and leave the call form to the reader — an agent may be holding the MCP tool surface, the shell, or Luau, and the signatures are listed for it either way.
Subskills
A <sub>.agentSkill/ folder nested inside a skill is a subskill. It has the
same shape as its parent and is invoked as parent/sub.
Subskills are reachable only through their parent: they are absent from the
roster and from skills.list, and appear in the parent's invoke result. A
skill can therefore carry a dozen narrow procedures while costing the roster
one line.
order in the manifest names the subskills that lead. Any subskill it omits
still appears, sorted by name, after the ordered ones — so adding a subskill
folder is the only step needed to publish it.
Publishing one
Make a skill and it is live: it joins the roster agents read and it opens by name from the moment it exists. Edit its description and that is the line agents see next.
A skill lives anywhere under /zero/source/. asset.create hands you a
valid one to fill in:
asset.create("agentSkill", "waveSpawning", { folder = "skills" })
A skill's scope — builtin, library, or world — comes from where it
lives rather than from anything it declares, so a world's own skill always
reads as the world's.
Opening one
agent_skill {} -- the roster
agent_skill { name = "scenes" } -- one skill's instructions + deps
agent_skill { name = "scenes/player-setup" } -- a subskill
The same three through the toolbox — skills.list, skills.invoke — and
from Luau via tools.use("skills", "invoke", "scenes"). asset.inspect on a
skill ref returns the structured record all of them render.
Skills authored in a world are the world's own, and are labelled as world content wherever they surface beside built-in ones.