Standards Linter
| Field | Value |
|---|---|
| Type | Skill Resource |
| Source | ~/.copilot/skills/skill-forge/references/standards-linter.md |
| Description | Not specified |
Source Content
Standards Linter
How scripts/standards_linter.py gates every skill in this repo to the consolidation plan’s standards.
What it checks
Run python3 scripts/standards_linter.py <skill-dir> before every commit:
| Check | Severity | Fix |
|---|---|---|
| Frontmatter present and valid YAML | error | Ensure --- opening and closing around key-value pairs |
name field present | error | Add name: <folder-name> (must match directory name exactly) |
description field present | error | Add a paragraph describing what triggers the skill |
name matches directory name exactly | error | Rename directory or edit frontmatter to match |
description under ~1,200 characters | error | Trim; move detail to references/ |
| All relative links in SKILL.md resolve | error | Check referenced files exist; fix typos in paths |
| SKILL.md under 500 lines | error (for large skills) | Push detail into references/ |
| Routing table present (if >2 references) | warning | Add “Route by task” table; see skill-authoring.md |
| Every referenced path exists on disk | error | references/foo.md must be a real file |
scripts/ entrypoint exists and executable | error | Check your validation script is in scripts/ and has execute bit set |
| No cross-skill invocation language | warning | Don’t write “invoke the X skill” outside agent files and AGENTS.md |
Exit codes
0— skill passes all checks.1— one or more checks failed (see the error output for details).
Running the linter
On a single skill:
python3 scripts/standards_linter.py /path/to/skill-dirOutput:
✅ name matches directory: helm✅ description present (856 chars)✅ all 14 referenced references/scripts/templates paths exist✅ SKILL.md is 278 lines (under 500)✅ routing table detected (12 rows)✅ scripts/ entrypoint (scripts/lint_chart.sh) is executableOn multiple skills:
for skill in ~/.copilot/skills/*/; do python3 scripts/standards_linter.py "$skill" || exit 1doneThe routing table rule
Any skill with more than two references/ paths should have a “Route by task” table in its SKILL.md. The linter warns if a skill has 3+ references but no visible routing table.
Example of a good routing table (from technical-writing):
| You're… | Read | Gate with || --- | --- | --- || Drawing a diagram only | `references/mermaid.md` + `references/mermaid/` | `scripts/mermaid_lint.py` || Fixing Markdown mechanics only | `references/markdown.md` | `scripts/markdown_lint.py` || Writing or editing a full document | `references/pipeline.md` — mode, template, workflow | `scripts/lint.py --git-changed` |The routing table signals that this is a front door skill — the reader can quickly navigate to what they need instead of scrolling through a monolithic SKILL.md.
The script entrypoint rule
If a skill has a scripts/ directory, the linter checks that:
- An entrypoint exists:
check.sh,lint.py, or similar. - It is executable (has the
+xbit). - It is documented in SKILL.md as the validation/gating step.
Example from technical-writing/SKILL.md:
| You're… | Read | Gate with || --- | --- | --- || Validating anything already written | - | `scripts/lint.py --git-changed` (or explicit files) |The entrypoint should accept a target path and exit 0 on success, non-zero on failure.
Frontmatter caps
descriptionlength: Max ~1,200 characters. Longer descriptions hurt trigger accuracy because the LLM pays less attention to tail text. Move detail intoreferences/.- SKILL.md line count: Max 500 lines. This is a gating rule enforced by the linter and the consolidation plan.
Reference-link integrity
The linter parses Markdown links in SKILL.md (ignoring code spans and fenced blocks — those are examples, not real links) and checks:
- Broken link (relative path that does not resolve) → error; blocks the skill from passing validation.
- Escaping link (points outside the skill folder, e.g.,
../adr/references/index.md) → warning; does not block but flags portability risk for isolated--dircopies.
Cross-skill invocation
The linter looks for phrases like “invoke the X skill” or “use the Y skill” outside of agent files and AGENTS.md. These are warnings: front-door skills should not call each other — any cross-domain handoff happens at the agent level, or as a plain “see also” pointer with no invocation language.
How the linter is run
This repo’s task lint fan-out includes lints:skills:
task lint → lints:skills → python3 ~/.copilot/skills/skill-forge/scripts/standards_linter.py ~/.copilot/skills/*Every commit via the post-commit hook runs this, so the repo’s skills always stay valid.