BC Gov Agent Skills
A shared catalogue of agent skill profiles

SKILL.md Spec

Every skill in this repo is described by a SKILL.md manifest, validated by the PR check. This page summarises what the validator enforces. The authoritative document lives at spec/SKILL_SPEC.md.

The PR check runs scripts/validate_skill.py against every changed skill. Run the same checks locally with uv run python scripts/validate_skill.py --all (or just one skill: uv run python scripts/validate_skill.py skills/<name>/SKILL.md).

Directory layout

A skill lives in its own directory under one of two roots. Both are validated against this spec; only skills/ is part of the public catalogue.

skills/<skill-name>/            # contributed skills (public catalogue)
.github/skills/<skill-name>/    # the repo's own meta-skills (internal)
├── SKILL.md        # required: the manifest
├── scripts/        # optional, flat — one level deep
├── references/     # optional, flat
└── assets/         # optional, flat

1. Frontmatter (required)

The SKILL.md MUST begin with a YAML frontmatter block. Two fields are mandatory:

FieldTypeNotes
namestringUnique, kebab-case identifier. Must match the skill's directory name.
descriptionstringWhat the skill does and when it should trigger. This is the only metadata an agent sees when routing, so keep it specific.

name rules

  • Kebab-case (^[a-z0-9]+(-[a-z0-9]+)*$): lowercase letters and digits in hyphen-separated groups, no leading, trailing, or consecutive hyphens.
  • At most 64 characters.
  • Must exactly match the skill's directory name, so manifest, folder, and npm package all line up.

description rules

  • At most 1024 characters.
  • No angle brackets (< or >): they get misread as markup where the manifest is injected.
  • Routing depends on it, so be specific about when the skill fires.

Allowed frontmatter keys

Only these keys are accepted (any other key is rejected by the validator): name, description, owner, tags, license, allowed-tools, compatibility, metadata. Of the optional ones, owner and tags are recommended.

There is no version field. The merge-to-main state of the repo is the released state, and npx skills add reads the repo directly. Don't add a version field to SKILL.md or anywhere else in the skill.

Example

---
name: example-skill
description: One line on what this does and when it fires.
owner: your-team
tags: [example]
---

2. Body (required)

After the frontmatter, the body MUST contain — in this order — an H1 title followed by all seven ## sections. Each section must have at least one line of content.

# <Skill Name>

## Use When
- <specific situation>

## Don't Use When
- <adjacent case> → <other skill>

## Workflow
1. <step + tool>
2. ...

## Rules
- Always <X>
- Never <Y>  (Why: <non-obvious reason>)

## Examples
- "<user phrasing>" → <action>

## Edge Cases
- If <lookup empty> → <fallback>

## References
See [references/REFERENCE.md](references/REFERENCE.md) for <heavy detail>

Keep it short: 500 lines max

A SKILL.md is loaded into the agent's context up front, so it must stay skimmable. The manifest is capped at 500 lines (the whole file, frontmatter included). When a skill needs deeper material — long procedures, lookup tables, worked examples, API detail — put it in a references/ file the agent pulls on demand, and link it from the ## References section.

Keep bundled resources flat: one level deep

Skills may ship scripts/, references/, and assets/ directories beside the SKILL.md. These must stay exactly one level deep: flat files only, no nested subdirectories. Use references/REFERENCE.md, not references/api/v1/REFERENCE.md. A flat layout keeps on-demand resources predictable for the agent to locate.

3. What the PR check enforces

For each changed skill, the validator confirms all of the following. If this list and the validator script (scripts/validate_skill.py) ever disagree, the script wins. If you see a failure on a PR, this list maps directly to the checks:

  1. The SKILL.md starts with a closed YAML frontmatter block that parses as a mapping.
  2. name and description are present and non-empty.
  3. name is kebab-case, at most 64 characters, and matches the skill's directory name.
  4. description is at most 1024 characters and contains no angle brackets.
  5. No unexpected frontmatter keys are present (only name, description, owner, tags, license, allowed-tools, compatibility, metadata).
  6. The body has an H1 title.
  7. All seven required sections are present: Use When, Don't Use When, Workflow, Rules, Examples, Edge Cases, References.
  8. None of those required sections is empty.
  9. The whole SKILL.md is at most 500 lines.
  10. Any bundled scripts/, references/, or assets/ directory is flat (no nested subdirectories).
  11. No cross-skill duplicates. When more than one skill is being validated, the check refuses two skills sharing the same name, the same description, or the same normalised body (the part after the H1 title and one-line summary). Catches copy-pasted manifests before they ship. Skip with --no-duplicates when you intentionally want to compare a single file.

Gotchas the validator can't always pinpoint

Run it locally

uv run python scripts/validate_skill.py skills/<your-skill>/SKILL.md

# or validate every skill
uv run python scripts/validate_skill.py --all

# or via the Makefile
make validate