# Agent Skill Linter

> Use when validating an agent skill for spec compliance and publishing readiness.

- Skill: `william-yeh/agent-skill-linter` (Agent Skill, multi-file: 11 files)
- Install (CLI): `npx skillmds@latest add william-yeh/agent-skill-linter`
- Raw SKILL.md: https://api.skillmd.com/api/skills/william-yeh/agent-skill-linter/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: william-yeh (https://skillmd.com/u/william-yeh)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/william-yeh/agent-skill-linter

---


# Agent Skill Linter

Checks agent skills for spec compliance and publishing readiness.

## Expected Layouts

Two layouts are supported, auto-detected by presence of `.claude-plugin/plugin.json` at the target:

- **Single skill** — lint target is the `skill/` subdir (or repo root for legacy repos). Pointing at the repo root of a `skill/` layout is fine: the linter redirects to `skill/` and says so on stderr.
- **Plugin** — lint target is the plugin root; manifest + each `skills/<name>/` checked.

> See `references/layouts.md` for layout diagrams, file-by-file conventions, and per-mode detection rules.

## Triage Workflow

**Target:** the skill directory to lint — current directory (`.`) or a path provided by the user.

### Step 1 — Get the full picture

```bash
./scripts/skill-lint.py check <target>
```

Review the output for errors and warnings; confirm the full picture before proceeding to Step 2.

### Step 2 — Fix Errors first

**Rule 1** errors (SKILL.md spec compliance) block publishing. Fix before anything else. Its Claude Code extension-field finding is a warning, handled in Step 4.

### Step 3 — Auto-fix Warnings

```bash
./scripts/skill-lint.py check <target> --fix
```

For fixable rules without CLI, use the templates in `references/fix-templates.md`.

Confirm no auto-fixable warnings remain before continuing to Step 4.

### Step 4 — Resolve remaining Warnings manually

CSO description prefix (Rule 11), Python invocations (Rule 13), README-tier sections in SKILL.md (Rule 19), Claude Code extension fields in frontmatter (Rule 1 warning: keep them if the skill is Claude Code-only, drop them to publish cross-platform) — see the rule table below.

Confirm all remaining warnings are resolved (or explicitly accepted) before proceeding to Step 5.

### Step 5 — Semantic review: CSO signal

Rule 11 catches structural patterns but not meaning. Read the `description` and `name` frontmatter and ask: **do they function purely as routing signals?**

> See `references/semantic-rules.md` — Rules 12 and 18 for examples.

Flag the description if it:
- Enumerates what the skill checks, handles, or supports
- Reads as a feature summary or workflow overview
- Contains elaboration labels (`Triggers on:`, `Use cases:`, `Checks:`) or multiple sentences
- Could be trimmed to one clause without losing routing precision

Flag the name if it reads as a noun phrase rather than an action — prefer gerunds (`creating-skills`, `processing-pdfs`) over noun forms (`skill-creator`, `pdf-processor`). Short well-known names (`pdf`, `commit`) are fine.

A good description names the trigger condition only. Everything else belongs in the skill body.

Confirm the description and name function as pure routing signals before moving to Step 6.

### Step 6 — Semantic review: starter prompts

Rule 7 detects whether prompts exist, not whether they're useful. Read the Usage section starter prompts and ask: **do they reflect genuine, distinct trigger scenarios?**

Flag them if they:
- Are vague or generic (e.g. `Use this skill`, `Run the linter`)
- All describe the same scenario with minor wording variation
- Don't reflect the range of contexts a real user would encounter

Confirm starter prompts cover genuinely distinct use cases before proceeding to Step 7.

### Step 7 — Semantic review: content overlap

The linter does not check this. Ask: **is the same information conveyed in different words across SKILL.md and README?**

> See `references/semantic-rules.md` — Rule 8 for examples.

Flag paraphrased repetition. SKILL.md should be agent-focused (triage workflow, rules); README should be human-focused (installation, usage examples).

Confirm no paraphrased repetition remains before moving to Step 8.

### Step 8 — Semantic review: progressive disclosure

Rule 15 flags known reference-tier keywords, but not all reactive content has a recognizable heading. Ask: **would an agent look up this section reactively rather than read it upfront?**

> See `references/semantic-rules.md` — Rule 16 for examples.

Flag sections for `references/` if they:
- Are reference material regardless of their heading name (e.g. "Background", "How It Works")
- Are dense or conditional — even if short and not caught by Rule 15
- Are step-specific detail blocks that bulk up the main workflow without being needed upfront

Also ask: **when a section is conditional ("After…", "Once…", "If…"), does its heading or first line name a concrete trigger event the agent can observe?**

> See `references/semantic-rules.md` — Rule 27 for examples.

Flag conditional sections whose trigger is vague — "After reviewing the output", "Once you understand the context" — and would leave the agent guessing when to enter the section.

Confirm all reactive content has been moved to `references/` and all conditional sections name an observable trigger before proceeding to Step 9.

### Step 9 — Semantic review: multi-step workflow quality

Only apply this step when the skill has a multi-step workflow (3+ `### Step N` headings).

Read each step body and ask: **does every substantive step state how the agent knows it is done?**

> See `references/semantic-rules.md` — Rule 22 for examples.

Flag a step if its body describes only *what to do* with no exit condition, no gate phrase, no "proceed only when" signal. Trivially short steps (a single line) need no explicit gate.

Also ask: **does the workflow include at least one step that checks actual tool output, not just verbal claims?**

> See `references/semantic-rules.md` — Rule 23 for examples.

Flag the workflow if every step prescribes actions but none tells the agent to read what the tool actually returned.

Also ask: **if the workflow loops on tool output, does it name a retry cap and a fallback?**

> See `references/semantic-rules.md` — Rule 26 for examples.

Flag the workflow if it instructs the agent to retry, iterate, or wait for a tool to succeed but has no exit condition beyond "until it works".

Confirm all three questions are satisfied before proceeding to Step 10.

### Step 10 — Semantic review: plain prose

Rule 28 catches cheap tells in human-facing documents (README, user guide). Read each one as its reader — a developer who knows agent skills but has never seen this project — and ask: **does it say what the skill does and who it is for, in short active sentences, with no marketing fluff or AI-flavored filler?**

> See `references/semantic-rules.md` — Rule 28 for the checklist and the delegation note.

If `critiquing-articles` is among your available skills, invoke its AI-flavor audit on each human-facing document with this genre note: *this is a README; bullet lists, bold-colon items, install steps, and code blocks are normal; discount em-dash density below three per paragraph; discount mainland-lexicon hits that sit inside examples of the tool's own input; judge prose paragraphs only.* Otherwise apply the inline checklist in the reference.

Judge in whichever natural language the document is written. If the document is Traditional Chinese and the audit reports mainland-lexicon hits, mention `localizing-taiwan-chinese` as an optional follow-up; do not run it unasked.

Propose rewrites and apply them only after the user agrees. Confirm every human-facing document reads as plain prose before proceeding to Step 11.

### Step 11 — Address Info items as polish

Body length (Rule 9), non-standard dirs (Rule 10), skill isolation (Rule 17).

## What It Checks

| # | Rule | Severity | Auto-fix |
|---|------|----------|----------|
| 1 | SKILL.md spec compliance (via skills-ref); Claude Code extension fields (`disable-model-invocation`, `model`, `hooks`…) warn instead | Error / Warning | — |
| 2 | LICENSE exists, Apache-2.0 or MIT, current year | Warning | Partial |
| 3 | `metadata.author` in SKILL.md frontmatter | Warning | Yes |
| 4 | README badges (CI, license, Agent Skills) | Warning | Yes |
| 5 | `.github/workflows/` has CI workflow | Warning | Yes |
| 6 | README has Installation section | Warning | Yes |
| 7 | README has Usage section with starter prompts + CLI subsection | Warning | Partial + Step 6 |
| 9 | SKILL.md body < 500 lines | Info | — |
| 10 | Non-standard directories flagged | Info | — |
| 11 | CSO: description starts with "Use when..." | Warning | Step 5 |
| 13 | Python invocation consistency (`uv run python` in uv projects) | Warning | — |
| 14 | Progressive disclosure: embedded templates (4-backtick fences) → `references/` | Warning | Yes |
| 15 | Progressive disclosure: reference-tier headings (Troubleshooting, FAQ, Advanced…) → `references/` | Warning | Yes + Step 8 |
| 17 | Skill isolation: SKILL.md at repo root alongside non-skill artifacts (silent once SKILL.md is in `skill/`) | Info | — |
| 19 | Division of labor: README-tier sections (Installation, Features, Getting Started…) in SKILL.md | Warning | — |
| 20 | Triage workflow has 3+ steps but no semantic review step (e.g. "Ask: does it…") | Info | Step 5–9 |
| 21 | Python entry-point scripts in `scripts/` lack PEP 723 inline dependency metadata | Warning | — |
| 24 | Plugin manifest `.claude-plugin/plugin.json` exists, parses, has `name` + `version` | Error | — |
| 25 | Skill scripts importing non-stdlib code declare a dep source (PEP 723, plugin-root pyproject.toml, or sibling dir) | Error | — |
| 28 | Plain prose in human-facing docs (README, user guide): marketing superlatives, buried or throat-clearing lead, long sentences/paragraphs, em-dash chains | Info | Step 10 |

Rules 24 and 25 only fire in plugin mode (when `.claude-plugin/plugin.json` is present at the lint target).

## CLI Reference

```bash
./scripts/skill-lint.py check .                            # Auto-detect: skill, skill/ subdir, or plugin
./scripts/skill-lint.py check ./my-skill --fix             # Single-skill, auto-fix
./scripts/skill-lint.py check ./my-plugin                  # Plugin: validates manifest +
                                                           # iterates skills/<name>/
./scripts/skill-lint.py check ./my-skill --format json     # JSON output for CI
```

Exit code 1 on errors, 0 otherwise.

