diff --git a/tools/skill-validator.md b/tools/skill-validator.md index 9566e1132..06edf3c8a 100644 --- a/tools/skill-validator.md +++ b/tools/skill-validator.md @@ -10,7 +10,7 @@ Before running inference-based validation, run the deterministic validator: node tools/validate-skills.js --json path/to/skill-dir ``` -This checks 14 rules deterministically: SKILL-01, SKILL-02, SKILL-03, SKILL-04, SKILL-05, SKILL-06, SKILL-07, WF-01, WF-02, PATH-02, STEP-01, STEP-06, STEP-07, SEQ-02. +This checks 12 rules deterministically: SKILL-01, SKILL-02, SKILL-03, SKILL-04, SKILL-05, SKILL-06, SKILL-07, PATH-02, STEP-01, STEP-06, STEP-07, SEQ-02. Review its JSON output. For any rule that produced **zero findings** in the first pass, **skip it** during inference-based validation below — it has already been verified. If a rule produced any findings, the inference validator should still review that rule (some rules like SKILL-04 and SKILL-06 have sub-checks that benefit from judgment). Focus your inference effort on the remaining rules that require judgment (PATH-01, PATH-03, PATH-04, PATH-05, WF-03, STEP-02, STEP-03, STEP-04, STEP-05, SEQ-01, REF-01, REF-02, REF-03). @@ -98,24 +98,6 @@ If no findings are generated (from either pass), the skill passes validation. --- -### WF-01 — Only SKILL.md May Have `name` in Frontmatter - -- **Severity:** HIGH -- **Applies to:** all `.md` files except `SKILL.md` -- **Rule:** The `name` field belongs only in `SKILL.md`. No other markdown file in the skill directory may have `name:` in its frontmatter. -- **Detection:** Parse frontmatter of every non-SKILL.md markdown file and check for `name:` key. -- **Fix:** Remove the `name:` line from the file's frontmatter. -- **Exception:** `bmad-agent-tech-writer` — has sub-skill files with intentional `name` fields (to be revisited). - -### WF-02 — Only SKILL.md May Have `description` in Frontmatter - -- **Severity:** HIGH -- **Applies to:** all `.md` files except `SKILL.md` -- **Rule:** The `description` field belongs only in `SKILL.md`. No other markdown file in the skill directory may have `description:` in its frontmatter. -- **Detection:** Parse frontmatter of every non-SKILL.md markdown file and check for `description:` key. -- **Fix:** Remove the `description:` line from the file's frontmatter. -- **Exception:** `bmad-agent-tech-writer` — has sub-skill files with intentional `description` fields (to be revisited). - ### WF-03 — workflow.md Frontmatter Variables Must Be Config or Runtime Only - **Severity:** HIGH diff --git a/tools/validate-skills.js b/tools/validate-skills.js index 997f8449a..8ab5bc2ad 100644 --- a/tools/validate-skills.js +++ b/tools/validate-skills.js @@ -1,7 +1,7 @@ /** * Deterministic Skill Validator * - * Validates 14 deterministic rules across all skill directories. + * Validates 12 deterministic rules across all skill directories. * Acts as a fast first-pass complement to the inference-based skill validator. * * What it checks: @@ -12,8 +12,6 @@ * - SKILL-05: name matches directory basename * - SKILL-06: description quality (length, "Use when"/"Use if") * - SKILL-07: SKILL.md has body content after frontmatter - * - WF-01: workflow.md frontmatter has no name - * - WF-02: workflow.md frontmatter has no description * - PATH-02: no installed_path variable * - STEP-01: step filename format * - STEP-06: step frontmatter has no name/description @@ -390,43 +388,6 @@ function validateSkill(skillDir) { } } - // --- WF-01 / WF-02: non-SKILL.md files must NOT have name/description --- - // TODO: bmad-agent-tech-writer has sub-skill files with intentional name/description - const WF_SKIP_SKILLS = new Set(['bmad-agent-tech-writer']); - for (const filePath of allFiles) { - if (path.extname(filePath) !== '.md') continue; - if (path.basename(filePath) === 'SKILL.md') continue; - if (WF_SKIP_SKILLS.has(dirName)) continue; - - const relFile = path.relative(skillDir, filePath); - const content = safeReadFile(filePath, findings, relFile); - if (content === null) continue; - const fm = parseFrontmatter(content); - if (!fm) continue; - - if ('name' in fm) { - findings.push({ - rule: 'WF-01', - title: 'Only SKILL.md May Have name in Frontmatter', - severity: 'HIGH', - file: relFile, - detail: `${relFile} frontmatter contains \`name\` — this belongs only in SKILL.md.`, - fix: "Remove the `name:` line from this file's frontmatter.", - }); - } - - if ('description' in fm) { - findings.push({ - rule: 'WF-02', - title: 'Only SKILL.md May Have description in Frontmatter', - severity: 'HIGH', - file: relFile, - detail: `${relFile} frontmatter contains \`description\` — this belongs only in SKILL.md.`, - fix: "Remove the `description:` line from this file's frontmatter.", - }); - } - } - // --- PATH-02: no installed_path --- for (const filePath of allFiles) { // Only check markdown and yaml files