Repository navigation
Description
name: "Bug Report"
about: "Report a reproducible defect"
title: "[Bug]: "
labels: ["type:bug", "area:scripts", "priority:high", "status:needs-triage"]
assignees: []
Describe the bug
scripts/validation/validate-skills.js never asserts that a SKILL.md has a body. It is 36 lines and checks two things: that the folder name is lowercase-kebab, and that a SKILL.md exists at the top level or nested one level down. A file containing nothing but its frontmatter satisfies both and passes.
That is how 66 files shipped empty. skills/*/SKILL.md reached develop holding only YAML frontmatter — 7 to 8 lines each — and were restored by #3680. The restoration fixed the files; the validator that should have caught them was never changed.
To Reproduce
Create a skill whose SKILL.md is frontmatter and nothing else, then run the validator from the directory that holds it:
mkdir -p /path/to/scratch/skills/demo-skill
printf -- '---\nname: demo-skill\ndescription: A skill with frontmatter and nothing else.\n---\n' \
> /path/to/scratch/skills/demo-skill/SKILL.md
cd /path/to/scratch
node /path/to/repo/scripts/validation/validate-skills.jsObserved:
Skill validation passed.
Exit status 0. A skill that conveys nothing beyond its description is reported as valid.
Expected behavior
validate-skills.js exits non-zero for a SKILL.md that has no body, naming the file — the same way it already names a missing file at line 25.
WordPress Environment
Not applicable. This is a Node.js repository script with no WordPress dependency.
Device and Browser Info
Not applicable. Reproduced on Node.js v24.21.0.
Additional Context
Scope. skills/*/SKILL.md and agents/*/skills/*/SKILL.md. validate-skills.js:9-28 only walks the top-level skills/ directory, so agent-nested skills are not examined at all today.
What "has a body" should mean. Everything after the closing --- of the frontmatter, with at least one non-blank line, excluding the canonical footer block that scripts/agents/includes/header-footer.js appends. dedupe-footers.js --check already identifies those blocks, and #3682 added npm run validate:footers:shape, so the shape tooling exists; this check should reuse it rather than reimplement it.
Why the check was never added. Unknown. The validator has no test file of its own, so a gap in its coverage is invisible to the suite. That is the actual defect behind the 66 empty files: not one mistake, but an untested validator.
Linked Stories/Tasks/PRs
- fix(skills): restore 66 emptied SKILL.md bodies from verified in-tree copies #3680 — restored the 66 emptied
skills/*/SKILL.mdfiles, now merged and closed. This issue is the missing guard, not the restoration. - fix(plugins): restore 29 plugin SKILL.md bodies lost to the 2026-05-28 footer truncation #3685 — restored 29
plugins/**/SKILL.mdfiles on the same pattern, now merged and closed. - Audit & fix: content gaps, duplication, stub files, and frontmatter validation #573 — tracks stub files as a known defect class, open. Its acceptance criteria are about completing content, not about detecting emptiness automatically.
- audit: skills content - three pre-existing defects in docx redaction, GA4 privacy rule, and wp:main examples #3686 — audits content defects in skills already restored, open. Different scope.
- task: conform all skills to the Agent Skills SKILL.md spec #3467 — rewrites the
SKILL.mdrules for the Agent Skills spec and adds a validator inscripts/validation/for frontmatter fields. That work does not assert body presence, and this check belongs alongside it rather than inside it. Whoever picks up task: conform all skills to the Agent Skills SKILL.md spec #3467 should reconcile the two so there is one validator, not two.
Milestones & Timeline
No deadline. The 66 affected files are fixed; this is the guard that stops the next occurrence.
Definition of Ready (DoR)
- Defect reproduced against the validator on
develop - Affected scope identified
- Related work searched and cited, so this is not a duplicate
Definition of Done (DoD)
-
validate-skills.jsexits non-zero for aSKILL.mdwhose only content is frontmatter, naming the file - A
SKILL.mdwhose body is exactly the canonical footer block is reported as having no body - A
SKILL.mdwith a body of prose only is reported as valid - Every existing skill under
skills/andagents/*/skills/passes, or each failure is triaged on its own merits - A test file exists for
validate-skills.js— there is none today, which is how the gap survived - The check runs in CI, not only locally
Metadata
Metadata
Assignees
Type
Fields
Priority
Activity
linear-code commentedon Oct 1, 2026
GIT-2503
fix(skills): validate SKILL.md frontmatter against the Agent Skills spec
fix(skills): validate SKILL.md frontmatter against the Agent Skills spec
fix(skills): validate SKILL.md frontmatter against the Agent Skills spec
feat(skills): validate every skill, subagent and agents file by its c…
fix(skills): recognise every configured footer in the empty-body gate
fix(skills): stop footer matching eating instructions, and check fron…
eleshar commentedon Oct 2, 2026
Resolved by #3717, which is merged-pending a code-owner approval. Recorded here so the issue is not re-litigated while that waits.
Every item in the Definition of Done is now implemented and verified against
673cb9d9:SKILL.md, naming the file[body]finding names file, rule and class; testfails a frontmatter-only skill (#3707)stripFooter()cuts the whole trailing block, not one line at a time<path>#<rule>#<subject>scripts/validation/__tests__/validate-skills.test.jsskill-specjob runsnpm run validate:skillsTwo things worth recording, because both were defects found during review rather than in the original report.
"A body of prose only is reported valid" was the subtle one. An earlier attempt at the footer check used a flat list of footer openings and matched them in bare text, so ordinary instructions beginning with a generic opener — "Update when the API version changes." — were stripped and reported as an empty body. That fails correct skills, which is worse than the false negative it fixed. It now follows the distinction already drawn in
scripts/agents/includes/footer-policy.js: high-confidence openers match bare text, generic ones only match when emphasised. Ten tests fail if that regresses.The vocabulary was guessed and had to be corrected. The 16 phrases configured in
.github/footers.ymlappear nowhere in the repository; the footers actually written are theDEFAULT_FOOTERS. And 35 files carry an emphasisedBuilt by LightSpeedWP…with no brick emoji, which the high-confidence opener cannot match. Both were found by reading the repository rather than the config.Scope note: this landed in #3717 rather than as a standalone fix, because #3467 was rewriting the same validator and this issue asks for one validator rather than two. #3717 also covers the agent-nested scope called out here, which the old 36-line script never walked.
The 754 baselined findings are the remaining conformance work and belong to #3467. This issue is the guard, and the guard is in place.
feat(skills): validate every skill, subagent and agents file against …
eleshar commentedon Oct 2, 2026
Delivered by #3717, merged into
developas b028d5d. Verified on mergeddevelop: the gate passes (754 baselined, 0 new, 0 stale) andscripts/validation/__tests__/validate-skills.test.jsruns 135 tests. Theskill-specCI job now runsnpm run validate:skillson every pull request and push.