Imported from shipshitdev/skills (
.agents/skills/skill-validator/SKILL.md). Install upstream withnpx skills add shipshitdev/skills --skill skill-validator. Copyright stays with the author.
Skill Validator
Validate SKILL.md files against the Agent Skills specification and Claude Code extensions.
When to Run
- After creating a new skill
- After modifying a skill's SKILL.md frontmatter
- Before committing skill changes
- During periodic repo audits
Validation Rules
Required Fields (Agent Skills Spec)
Every SKILL.md must have YAML frontmatter with:
name— kebab-case, matches directory namedescription— 1-3 sentences, under 1024 chars, starts with verb or domain noun
Metadata Block
version and tags must be inside metadata:, never top-level:
# CORRECT
metadata:
version: "1.0.0"
tags: "react, performance, optimization"
# WRONG — top-level version
version: 1.0.0
# WRONG — tags as YAML list
metadata:
tags:
- react
- performance
Forbidden Fields
These are not part of any spec:
auto_activate/auto_trigger— removed in 2026-04 migrationrisk— not in Agent Skills or Claude Code specs
Claude Code Extensions (Optional)
Valid extension fields (must match allowed_fields in scripts/validate-skill-sync.sh):
| Field | Purpose |
|---|---|
when_to_use |
Extra trigger phrases appended to description |
disable-model-invocation |
Prevent auto-triggering (for destructive skills) |
user-invocable |
false hides from the / menu |
allowed-tools |
Auto-approve allowlist (not a sandbox — unlisted tools stay callable) |
disallowed-tools |
Removes tools from the pool while active (the actual block mechanism) |
argument-hint |
Autocomplete hint for expected arguments |
compatibility |
Environment prerequisites (packages, network, target agent) |
context |
fork for subagent isolation |
agent |
Subagent type when context: fork |
hooks |
Lifecycle hooks scoped to the skill |
paths |
⚠️ Broken upstream (#49835) — flag if present |
shell |
bash (default) or powershell |
Forbidden Fields (updated)
auto_activate/auto_trigger— removed in 2026-04 migrationrisk— not in any specmetadata.triggers— duplicate activation metadata; put trigger phrases indescriptionorwhen_to_usemodel/effort— recognized by Claude Code but owned by app/session configuration, not public reusable skills- Any top-level field not in the tables above → "Unsupported top-level frontmatter field"
Content Rules
- No hardcoded
/workspace/paths - No tool names in instructions (say "search for" not "use Grep")
- Imperative/infinitive style ("Configure X" not "You should configure X")
- Code blocks use real backtick fences, not escaped
\``` - No concrete model names in body,
references/, orscripts/— reject tier+version IDs (claude-3-7-sonnet-20250219,claude-opus-4.5,gpt-5.5), dated snapshots, and bare family names used as routing keys. Exception: orchestrator skills may name capability tiers in prose. See skill-standards.md → Model references. - No harness-owned execution parameters in skills, commands, or routine templates. Apply execution-boundary.md.
- Routine templates follow
routine-standards.md. Run
python3 scripts/audit-routines.pyto detect duplicate bodies and app-parameter leakage without printing prompt or configuration values. - Provenance (derived skills only): when
metadata.sourceis set,metadata.last_syncedand a README## Upstreamsection are required (enforced bycheck_provenance()). In-house skills need no provenance fields.
Validation Process
- Read the SKILL.md frontmatter
- Check
namematches parent directory name - Check
descriptionexists and is under 1024 chars - Check
descriptionpluswhen_to_useis under 1536 chars - Check
plugin.jsondescription is present and under 100 chars - Check
version/tagsare NOT top-level (must be insidemetadata:) - Check for forbidden fields (
auto_activate,auto_trigger,risk,model,effort, any field not in the extension tables) - Check for escaped backtick fences in content
- Validate frontmatter value types:
allowed-toolsis a scalar,metadata.versionandmetadata.tagsare quoted scalars, andmetadatais a map - Reject duplicate
metadata.triggers; keep activation guidance indescriptionorwhen_to_use - Check for hardcoded paths (
/workspace/, project-specific paths) - Grep body +
references/+scripts/for concrete model names (claude-*,gpt-*,sonnet/opus/haikuused as IDs); allow only capability-tier prose in orchestrator skills - Warn when skills, commands, or templates set harness-owned execution parameters
- Warn when a side-effecting skill lacks both
disable-model-invocation: trueand an explicitConfirmation Requiredgate - Check prose routing references across the body, excluding frontmatter and code fences, and flag missing local skills
- Check provenance for derived skills: if
metadata.sourceis set, requiremetadata.last_syncedand a README## Upstreamsection - Run
bunx markdownlint-clion the file - Run
./scripts/validate-skill-sync.shfor cross-validation
Quick Validation Command
# Single skill
bunx markdownlint-cli skills/<name>/SKILL.md skills/<name>/references/*.md
# All skills
bunx markdownlint-cli --ignore bundles --ignore dist "**/*.md"
# Sync validation
./scripts/validate-skill-sync.sh