Round-3 review of PR #85 found the "enforcing" pre-commit hook enforced nothing. Vale's exit code keys on error-level alerts alone: five of the six rules were level: warning, so they exited 0, and pre-commit hides output from a passing hook — the alerts were invisible and blocked nothing. ADR-0013 rejected a report-only trial tier and then shipped one by accident. Flatten every rule to level: error. Vale's own exit code is then correct, so the hook entry drops to a bare vale-wrap.sh call and the graded error->FAIL / warning->SUGGESTION mapping disappears from both audit skills: every alert is a FAIL, in the gate and the audit alike. No ignorable tier, matching shellcheck, the test suite and conventional-pre-commit. Delete Kyberforge.VagueQualifier. Measured against the 41 skill/agent files as they stood before the rule ever ran: 2 hits. One marginal ("very different" -> "fundamentally different"), one an unfixable false positive — caveman/SKILL.md quotes "of course" as an example of filler, a mention not a use — which forced the only Vale suppression comments in the repo. Those four lines go with it; two of them were dead anyway, suppressing a frontmatter-scoped rule on a body line. Held-out prose (273 files) fired 15 times, 9 inside out-of-scope research examples and the rest one word in two idioms in a single doc. SentenceOpenerThereIs survives: 22 held-out hits, both in-corpus hits clean rewrites, zero suppressions. Widen .vale.ini's globs to [**/SKILL.md], [**/agents/*.md] and [**/*.agent.md]. The plugins/*/-prefixed globs scoped nothing — Vale's * crosses /, so they already matched docs/research/examples/**/agents/*.md and assets/templates/SKILL.md, the two paths CONTEXT.md claimed they excluded. Scoping is and was the hook's files: regex. The old globs also hid a silent false negative: a skill outside plugins/ matched no section, so Vale reported 0 files and exited 0, which both audits read as clean. They now treat a 0-file run as NOT RUN and fall back to full judgment. Also: - vale-wrap.sh resolves relative --config values and file arguments against the caller's cwd, as vale does, instead of the repo root, which hard-errored from a subdirectory and silently skipped flattening for file args that did not resolve from the root. Absolute paths inside the cwd are relativized so reports cite resolvable paths, not scratch ones. - vale-run's exit-code model was documented backwards ("exits non-zero whenever it finds an alert at or above MinAlertLevel") and would have led anyone following it to build a gate that passes everything. Its Markdown suppression syntax was MDX-only and does not suppress in .md; corrected in the skill and its troubleshooting reference, with backtick/fence exemption documented as the first resort. - skill-size-check.sh fails only above 500 lines, agreeing with skill-audit's validate.sh <= 500 pass. - ADR-0013 and CONTEXT.md amended to match, recording why graded severities cannot gate. Verified: 9 test scripts / 15 vale-wrap cases pass; vale-audit-prefilter, skill-size-check and shellcheck pass --all-files; check-manifests and claude plugin validate --strict clean. New tests fail against the old script (3 of them) and pass against the new one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
9.5 KiB
name, description, allowed-tools, metadata
| name | description | allowed-tools | metadata | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| skill-audit | Use when the user wants to review a skill they wrote, says "audit this skill", "check if my skill follows best practices", "review my SKILL.md", or wants to know if a skill is ready to ship — even if they don't use the word "audit". Also invoke proactively after directly hand-editing a skill's files outside skill-author — an unaudited hand-edit is the same risk as unreviewed code. Audits a skill directory against the agentskills.io specification — structural checks plus qualitative review of description quality, body discipline, patterns, formatting, file structure, scripts, and internal consistency, plus a provenance chain check. Produces a compact findings report (findings only, no PASS noise) with Why and Fix per finding, suitable for agent handoff to /skill-improve or human auditability. Do not use to fix application code bugs or perform general code review unrelated to skill quality. Do not use when the user wants improvements applied — use /skill-improve instead. | Bash Read |
|
Gotchas
- Do not output PASS/FAIL per check while auditing — gather findings internally and surface them only in the Step 4 report. Narrating each check as you go is the default failure mode here.
Step 1 — Structural validation
bash scripts/validate.sh <skill-dir>
bash scripts/validate-provenance.sh <skill-dir>
"$(git rev-parse --show-toplevel)/scripts/vale-wrap.sh" --config "$(git rev-parse --show-toplevel)/.vale.ini" <skill-dir>/SKILL.md
Note any structural FAILs — they will appear in the report as a ### Structure dimension. If the script cannot execute (python3 unavailable, Bash denied, or permission error), perform structural checks manually: name format, name matches directory, description length ≤1024 chars, SKILL.md ≤500 lines, no unfilled FILL IN: placeholders, scripts executable and free of interactive prompts.
Note any Provenance FAILs and INFO findings from validate-provenance.sh — they surface in the report as a ### Provenance dimension (separate from ### Structure). The script embeds full FAIL/INFO format with Why and Fix per finding; surface them verbatim.
vale-wrap.sh resolves its own path and .vale.ini via git rev-parse --show-toplevel; pass the absolute paths shown above so the invocation holds from any cwd. It applies .vale.ini's Kyberforge style — a deterministic prefilter for a subset of the Description/Patterns/Body dimensions below, not a replacement for Step 3. Every Vale alert is a FAIL — all rules are graded error — so report each one citing its rule ID (e.g. Kyberforge.DescriptionOpener). Skip and fall back to Step 3 judgment if vale or .vale.ini is unavailable. If Vale reports 0 files scanned, treat the pass as NOT RUN — not as clean — and fall back to full Step 3 judgment for the dimensions it would have covered.
Step 2 — Read all skill files
Read every file in the skill directory: SKILL.md, README.md (if present), all files in scripts/, references/, assets/, and tests/. Skip binary files only. Do not skip text files — internal consistency checks require the full picture.
Step 3 — Qualitative audit
Work through each dimension internally. Collect findings only; report them in Step 4. Cite file and line number for every finding.
Description
Vale's Kyberforge.DescriptionOpener ("This skill..." openers) and Kyberforge.VagueWording (filler like "helps with", "utilize") alerts from Step 1 — both FAILs — cover imperative phrasing and known vague-wording filler directly; report them as findings without re-deriving by judgment. The rest is still a judgment call:
- Specificity beyond the filler blocklist: are capabilities stated precisely ("parses OpenAPI specs") or genuinely vaguely ("handles files")?
- Indirect triggers: does it cover cases where the user doesn't name the domain directly?
- Near-miss exclusions: are "Do not use when..." clauses present if a near-miss skill could steal activations?
- Length: under 1024 characters?
If a description finding is borderline or the distinction between PASS and FAIL is unclear, read references/description-quality.md.
Body discipline
For each sentence in the body, apply: "Would the agent get this wrong without this sentence?" Flag any that answer "no" as padding.
- Defaults not menus: every decision point gives one default + one escape hatch, not a list of options
- Why rationale: include/exclude rules explain why, not just what
- Control calibration: prescriptive for fragile or critical sequences (e.g. a script invocation where flag order or exact arguments must not change); flexible where multiple approaches are valid
Vale's Kyberforge.SentenceOpenerThereIs alert from Step 1 (FAIL — sentences starting with "There is"/"There are") covers pattern-matchable body-wide filler directly; report it as a finding without re-deriving by judgment.
If uncertain whether a sentence is padding or whether a control decision is correctly calibrated, read references/body-discipline.md.
Patterns
Check each pattern is appropriate and correctly formed:
- Gotchas: placed near the top; each entry is a specific fact that defies a reasonable assumption — not a general tip
- Prescriptive sequence: inner code fences escaped as
\``` when nested inside a markdown block - Checklists: used for multi-step workflows, not single steps
- Conditional references: specific trigger stated ("If X, read
references/file.md") — not a generic "see references/". Vale'sKyberforge.PaddingPhrasealert from Step 1 flags the generic phrasing directly; other malformed conditional-reference forms still require judgment. - Output templates: present when the agent must produce a specific format; absent otherwise
File structure
- Permitted directories:
scripts/,references/,assets/,tests/; flag any other unlisted directory as FAIL — the spec allows additional dirs but this skill permits only these four to keep skills focused scripts/contains only executable code agents can run; test files (.bats,*_test.*,test_*.sh) inscripts/are a FAIL — they belong intests/- No non-spec files at the skill root (e.g. META.md, extra config files outside permitted directories)
- Optional directories contain real content — not just unfilled placeholder READMEs
README.mdpresent and accurately describes the skill and its files- No cross-plugin path references in SKILL.md, scripts/, references/, or assets/ — paths using
../,../../, or absolute repo paths (e.g.plugins/<plugin>/skills/<other-skill>/) break when the plugin is installed to a cache; flag any found references/sources.mdis exempt from the cross-plugin path check —Research doc:fields are development-only provenance pointers, not runtime references; they intentionally reference paths outside the skill directory and are expected to be non-resolvable after plugin install;validate-provenance.shhandles this gracefully by silently skipping upstream checks when those paths don't resolvetests/is exempt from the cross-plugin path check — test files are dev-only and may reference repo-level test infrastructure (e.g. a sharedtests/test_helper/). This dependency must be declared intests/README.md; flag if tests exist buttests/README.mdis absent or does not document the dependency
Formatting
- Heading levels consistent: H2 for main sections, H3 for subsections
- Code blocks fenced with a language tag where applicable (
bash,markdown,python) - Consistent whitespace: blank line between sections, consistent list indentation
- No broken relative paths in file references
Scripts
- No interactive TTY prompts (
read,input(),readline) --helpexposed with concise usage- Data to stdout, diagnostics to stderr
- Idempotent ("create if not exists")
- Meaningful exit codes documented in
--help --dry-runpresent for destructive operations
Internal consistency
- SKILL.md steps match what scripts actually do
README.mdfile table lists every file that exists — no missing entries, no stale entries- Placeholder READMEs in
scripts/,references/,assets/consistent with what SKILL.md says about each directory
Step 4 — Report
Open with a coverage line listing every dimension checked:
Checked: structure · description · body-discipline · patterns · file-structure · formatting · scripts · internal-consistency · provenance
Then output only dimensions that have findings, grouped under H3 headings, FAILs before SUGGESTIONs within each dimension. Omit clean dimensions entirely — their absence confirms they passed.
For each finding:
FAIL/SUGGESTION <finding> — file:line
Why: <why this is a problem>
Fix: <exact change — quote before/after where applicable>
Close with a result block:
## Result
PASS
PASS (N suggestions)
PASS · P info
PASS (N suggestions) · P info
FAIL (N fails · M suggestions)
FAIL (N fails · M suggestions) · P info
Run /skill-improve to address findings.
INFO findings are observational — do not affect PASS/FAIL. Omit · P info when there are no INFO findings. Omit the /skill-improve line when there are no findings at all. Do not apply fixes — report and propose only.