Skip to content

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.

name: mermaid-to-images

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.

context: fork

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.

skills:
  - mermaid-to-images
  - visitrans-design-system

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.

allowed-tools: "Read, Grep, Glob, WebSearch"

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.

context: fork
agent: ims-writer

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.

metadata:
  category: documentation
  version: "1.0"

Optional Fields (Custom)

requires_agents

Declares the agents a skill dispatches, and which of them can determine a gate status.

requires_agents:
  - plan-checker: gate-critical
  - strategic-mentor: advisory
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.

output_contract: multi-step

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-step skill with no such block. Skills that predate the standard are grandfathered in plugins/vt-base/lib/output-contract-baseline.txt and 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 some context: fork sub-agents) opts out with output_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.

license: MIT

preconditions

Type: string or array

Required conditions that must be met before the skill can execute.

preconditions: ".specify/memory/constitution.md must exist"

triggers

Type: string or array

Conditions or keywords that suggest this skill should be invoked.

triggers: "review, code quality, security check"

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:

  1. 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.

  2. 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.

  3. 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.

  4. 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