SKILL.md Frontmatter Reference¶
All SKILL.md files in the V025-claude-toolkit use YAML frontmatter to declare metadata, capabilities, and execution context. This reference documents all recognized fields.
Required Fields¶
name¶
Type: string Required: Yes
The skill identifier. Must be lowercase, use hyphens as separators, and be max 64 characters. Must match the skill's directory name.
description¶
Type: string Required: Yes
What the skill does and when to use it. Max 1024 characters. Should be written in third person and include both the purpose and the trigger conditions.
description: Converts Mermaid diagram files (.mmd) to PNG images using mmdc CLI. Use when you have .mmd files that need to be rendered as PNG images.
Optional Fields (Claude Code Platform)¶
context¶
Type: string
Values: fork
Source: Claude Code 2.1
Execution context for the skill. When set to fork, the skill spawns as an isolated sub-agent that returns only its output to the parent conversation.
Important: Skills with context: fork MUST include an "Error Handling (context: fork)" section. See Fork Context Requirements below.
hooks¶
Type: object Source: Claude Code 2.1
Defines PreToolUse and/or PostToolUse hooks that run automatically during skill execution. Hooks can match specific tool names and execute shell commands.
hooks:
PostToolUse:
- matcher: "Write|Edit"
hooks:
- type: command
command: "echo 'Validation check: verify output quality.'"
skills¶
Type: array of strings Source: Claude Code 2.1
Declares skill dependencies — other skills that this skill may invoke during execution.
allowed-tools¶
Type: string or array Source: Claude Code platform
Restricts which tools the skill can use during execution. Pre-authorizes the listed tools so they do not trigger approval prompts. Use this for interactive skills (without context: fork) that need specific tools without manual approval each time.
agent¶
Type: string
Source: Claude Code 2.1
Requires: context: fork
Specifies which agent type executes the skill when running in a forked context. Valid values: any agent name from .claude/agents/ or built-in types (general-purpose, Explore, Plan).
When set, the skill runs inside the specified agent, inheriting the agent's tools: list as its permission boundary. This enables autonomous execution with a declared, auditable set of pre-authorized tools.
When omitted with context: fork, defaults to general-purpose.
When to use agent: vs allowed-tools:
| Mechanism | Use when | Context |
|---|---|---|
allowed-tools |
Skill runs interactively and needs specific tools without approval prompts | Main conversation |
agent: + context: fork |
Skill should run autonomously in isolation with a defined tool boundary | Forked sub-agent |
| Neither | Skill has minimal tool needs or approval prompts are acceptable | Default behavior |
metadata¶
Type: object
Arbitrary key-value metadata pairs for skill categorization or tracking.
Optional Fields (Custom)¶
requires_agents¶
Declares the agents a skill dispatches, and which of them can determine a gate status.
| value | meaning |
|---|---|
gate-critical |
this agent's verdict can become a gate status. Its absence must never yield one. |
advisory |
informational. Its absence cannot produce a wrong gate status, so it needs no preflight. |
Why the split matters (BUG-022). A skill that dispatched a validator, got nothing back,
and self-assessed could write status: PASS that no validator produced — and nothing
downstream could tell. Measured: a plan the inline assessment passed 9/9 was then failed by
the real checker with 4 blocking defects, two of which would have caused real damage.
Only gate-critical entries need declaring for that reason: an advisory agent's absence
cannot produce a wrong status, so the failure mode does not reach it.
Who must declare. A skill whose dispatched agent's verdict can become a gate status.
Today that is workflow-2-plan (plan-checker) and workflow-4-review (its Step 2.9
Collection Barrier makes reviewer verdicts determine the gate). A skill that only dispatches
advisory agents needs no entry.
How readers use it. A gate artifact records validator and validators_run. A consumer
renders prescribed − validators_run from this field to name which prescribed validators
did not run — which is what a reader needs, and what validators_run alone cannot supply.
Related. Constitution Principle IV already requires agent files to declare their sub-agent dependencies; this is the same rule one layer down, for skills. See SPEC-189 FR-1.
output_contract¶
Type: string — multi-step | single-fact
Declares the skill's output class, so the SPEC-170 output-clarity audit
(plugins/vt-base/bin/check-output-contract.sh) knows whether to require a delimited
"Next actions" block. Class only — it does not set the enforcement tier, which is decided by
the shrink-only plugins/vt-base/lib/output-contract-baseline.txt.
| Value | Meaning |
|---|---|
multi-step |
Skill runs a workflow or produces multi-paragraph output → MUST document a ## Next actions (or ## Next steps) heading/bold block with real content. This is the default when the field is absent. |
single-fact |
Skill returns one fact or one answer → exempt from the block. |
The heading must BEGIN with "Next actions" or "Next steps" — either word may be capitalised (## Next actions and ## Next Actions both pass), as an H1-H4 heading or a bold run-in. Trailing words are allowed (## Next Steps After Validation passes), though sentence case with no suffix is the house style. Synonyms such as "Required actions" are rejected, and so is an all-caps ## NEXT ACTIONS. A heading whose body is only [TODO] placeholders does not count as content —
that is what makes a scaffolded-but-unfilled skill fail by design.
The field is opt-out, not opt-in: omitting it means multi-step and the block is required.
Never tag a genuinely multi-step skill single-fact to dodge the block — reason: it is an audit
escape hatch, and an escape-hatch guard in test-output-contract.sh hard-fails if the
single-fact population grows past its bound (currently 5). That guard is a population counter,
NOT a calibration gate — real calibration is deferred to
intake/pending/spec-170-followup-calibration-gate.md.
Gate scope and enforcement (moved here from CLAUDE.defaults.md by SPEC-220, so every
session no longer loads it):
- The gate is
plugins/vt-base/bin/check-output-contract.sh, run by the test suite (scripts/run-tests.sh). It verifies the Next-actions block only — answer-first and concision are guidance, not gated, because neither is checkable against a SKILL.md template. - It hard-FAILs an off-baseline
multi-stepskill with no such block. Skills that predate the standard are grandfathered inplugins/vt-base/lib/output-contract-baseline.txtand WARN instead. That baseline is a shrink-only ratchet: it never grows, every conformance is banked, and anything not on it hard-FAILs — the grandfathered set is a migration, not an exemption. - It checks presence and substance, not position: placing the block last is the rule authors follow, but a few skills legitimately document next actions mid-file inside their Execution section, and rejecting those would be a false negative.
- Scope: skill-driven output authored in SKILL.md. Agent definition files
(
plugins/*/agents/**/*.md) are out of scope; command files (plugins/*/commands/**/*.md) are a known, deliberately-deferred gap. A skill that returns structured data to an orchestrator rather than user-facing prose (including somecontext: forksub-agents) opts out withoutput_contract: single-fact. Free-form base-Claude responses not driven by a skill are a stated non-goal.
CLAUDE.defaults ## Before Every Response states the standard itself and points here;
this section is the single source for its gate mechanics and scope. The authoring rule is in
.claude/rules/vt-base-rules.md.
license¶
Type: string
License identifier for the skill content.
preconditions¶
Type: string or array
Required conditions that must be met before the skill can execute.
triggers¶
Type: string or array
Conditions or keywords that suggest this skill should be invoked.
Not a SKILL.md Field¶
argument-hint¶
Type: string
Valid in: Command files (~/.claude/commands/*.md) only
This field provides UI hints about what arguments a slash command accepts. It is not recognized in SKILL.md files — it is silently ignored if present. 26 existing skills include it due to copy-paste from command file templates; it causes no harm but should not be added to new skills.
# In command files (valid):
argument-hint: "[--scope path/to/review]"
# In SKILL.md files (ignored, do not add):
# argument-hint: "[--scope path/to/review]" # ← no effect
Fork Context Requirements¶
Skills with context: fork execute as isolated sub-agents. They MUST include an "Error Handling (context: fork)" section with these rules:
-
NEVER ask interactive questions. No "Would you like...?", no "Should I...?", no AskUserQuestion calls. Fork sub-agents cannot interact with the user — the question is swallowed, the sub-agent dies, and the parent conversation receives no output.
-
If a file write fails, report it inline and continue. Use this format:
Warning — file not persisted: Could not write
{filename}. The full content is included in the output above. -
Always produce the full formatted output as the primary deliverable. File persistence is secondary. The formatted summary returned to the parent conversation must be complete regardless of file write outcomes.
-
Always end with a TL;DR summary. The last output block MUST be a TL;DR section using standardized delimiters (
━━━ TL;DR ━━━), max 10 lines between delimiters, containing: decision result, key metrics, and recommended next action. This ensures the user sees the most important information first without scrolling. Nothing may follow the TL;DR in the REPORTED output. The run may continue afterwards only with work that writes no file, performs no git operation, changes no gate or state record, and has no external effect (no network call, no publish) — anything beyond that MUST appear in the reported output before the TL;DR. A gate verdict written after the final report would be invisible to the user by construction, which is exactly what this rule prevents (SPEC-205 W4.4, bounded after review pass 2, finding SEC-F1).
Interaction with output_contract (SPEC-170) — these two rules compose, they do not
conflict. A fork skill carries both, in this order at runtime: the report body ends with its
next-actions content, and the TL;DR is then appended as the final output block, its Next:
line naming the single most important of those actions.
The confusion worth heading off: a ## Next actions section in a SKILL.md is a reference
section describing what the agent must tell the user — its position in the template is not
its position in the output. In both current fork skills the TL;DR step is the last step
(workflow-4-review Step 8, workflow-5-finalize Step 5, each titled "Final Output") and
## Next actions sits below it among the other reference sections. That is correct and is
not a violation of "nothing may follow the TL;DR", which governs emitted output only.
Skills Currently Using context: fork¶
| Skill | Purpose |
|---|---|
workflow-4-review |
Code review with a diff-scoped reviewer set |
workflow-5-finalize |
Final quality verification |
mermaid-to-images |
Mermaid diagram to PNG conversion |
container-logistics-ux-expert |
Container logistics UI evaluation |
pd-4-validate |
Usability testing and validation |
Field Summary¶
| Field | Required | Source | SKILL.md | Command file |
|---|---|---|---|---|
name |
Yes | Platform | Yes | No |
description |
Yes | Platform | Yes | Yes |
context |
No | Claude Code 2.1 | Yes | No |
hooks |
No | Claude Code 2.1 | Yes | No |
skills |
No | Claude Code 2.1 | Yes | No |
allowed-tools |
No | Platform | Yes | Yes |
agent |
No | Claude Code 2.1 | Yes | No |
metadata |
No | Custom | Yes | No |
license |
No | Custom | Yes | No |
preconditions |
No | Custom | Yes | No |
triggers |
No | Custom | Yes | No |
argument-hint |
No | Platform | No (ignored) | Yes |