Skip to the content.

Skill validation

An agent skill validator answers three different questions, and they fail at different moments.

python scripts/sqs.py check ./my-skill      # all five static modules
python scripts/sqs.py spec ./my-skill       # specification conformance alone
python scripts/sqs.py structure ./my-skill  # links, orphans, budgets
python scripts/sqs.py fix ./my-skill --apply

1. Will a loader take it

The Agent Skills specification requires name and description in the YAML frontmatter, a name of lowercase letters, digits and single inner hyphens, at most 64 characters, matching the folder, and a description at most 1024 characters.

What actually happens is split, and that split is the reason skill validation matters: a lenient client warns and loads the skill anyway, while a strict validator and publication reject it. So the skill works on your machine and fails the moment it leaves.

The suite reports these as SP001-SP019. The ones worth knowing:

2. Will every pointer still resolve

This is the class that breaks today, in silence. A skill points into references/, the file was renamed, and nothing crashes: the agent skips the step, and from outside it looks like the work came out weaker than usual.

Run sqs.py structure after any rename. That is the single moment this class of defect is created.

3. Does it read like an instruction

A skill can be perfectly valid and still be a bad skill. These rules (QL001-QL019) are heuristics, and each one names a file and a line so you can judge it:

Each rule carries a detection confidence and a false-positive risk, printed by sqs.py explain <CODE>. --min-confidence high keeps the filesystem and parse facts and drops the prose heuristics, which is the gate you can leave switched on in CI.

Reading and acting on the report

⛔ SP004  `name: video-tools` does not match the folder `video` (SKILL.md)
⚠️  ST006  SKILL.md is 21370 B > the 15000 B budget (SKILL.md)
·   QL006  as needed - lines 191, 295 (SKILL.md:191)
  1. sqs.py explain <CODE> for the reasoning, then the fix.
  2. sqs.py fix --apply for the mechanical repairs - the ones with exactly one right answer. It deliberately will not shorten an over-long description: there is no single right shortening, and picking one for you deletes a trigger you needed.
  3. The rest by hand.

For findings that are correct-and-intended there are four scopes of escape hatch: sqs-allow: CODE on a line, sqs-allow-file: CODE in a file header, sqs.config.json for the tree, and .sqsignore for a subtree that is not skill payload at all.

See also