Skip to content

feat(ci): validate skill frontmatter on pull requests (1/4) - #126

Draft
miscreantmoogly wants to merge 8 commits into
mainfrom
validate-skills/1-frontmatter
Draft

miscreantmoogly wants to merge 8 commits into
mainfrom
validate-skills/1-frontmatter

Conversation

@miscreantmoogly

@miscreantmoogly miscreantmoogly commented Oct 8, 2026 •

Copy link
Copy Markdown

Stacked PR 1 of 4. Draft while the proposed rules are reviewed. PRs 2–4 build on this one; review and merge in order.

Description

Adds validate-skills, a pull request check for the rules a skill must meet before it can be published. Every rule applies to every skill in skills/, not only the ones a pull request touches. A rule that existing skills don't meet yet starts as a warning, and becomes an error after a cleanup PR brings every skill into line.

This PR adds the frontmatter rules:

  • plain YAML only;
  • name equal to the folder name;
  • limits on description, title and summary;
  • metadata values as text;
  • author as GitHub usernames;
  • a MAJOR.MINOR.PATCH version.

It also covers the optional deprecated, agent_types and aws-devops-agent-skills.* fields, and adds three warnings:

  • Missing metadata.summary. It becomes required once every skill has one.
  • No agent type. A skill's agent types come from metadata.agent_types when set, and otherwise from its aws-devops-agent-skills.agent-types values through display_mapping in agent-types.json. A skill with neither would load for all agents (GENERIC), so it warns.
  • Dimension values outside vocabulary.json.

Files:

  • .github/scripts/skill_checks.py: the rules, as pure functions over an in-memory skill folder.
  • .github/scripts/validate_skills.py: the command.
    • Reads skills from Git objects.
    • Errors from any skill fail the check; warnings show only for skills the PR touches.
    • Annotations point at the file and line.
    • Exit code 2 means the check couldn't run, and is never reported as the PR's fault.
  • .github/scripts/skill-rules/:
    • agent-types.json and vocabulary.json, the rule data;
    • conformance-cases.json, language-neutral pass/fail cases that the script runs before checking any skill, and that any other validator or publisher of these skills can run too;
    • requirements.txt, PyYAML pinned by hash.
  • .github/workflows/validate-skills.yml:
    • read-only, no paths filter, actions pinned by SHA;
    • runs the unit tests, then the check;
    • advisory until an admin makes validate-skills a required check.
  • Version fixes: analytics-opensearch-expertise (2.6 → 2.6.1) and database-rds-devops (1.0 → 1.0.1), each with a CHANGELOG entry.
  • Docs: a "Skill Publishing Rules" section in CONTRIBUTING.md, and notes in .claude/CLAUDE.md.

Like the repository's other checks, a PR runs its own copy of this one. CODEOWNERS on /.github/ (PR 4) is what stops a PR from editing the check to pass.

Result across the 34 skills on main: 0 errors, with warnings for:

  • a missing summary (every skill);
  • no agent type (4 skills);
  • vocabulary (5 values on 3 skills).

Type of change

  • Update to an existing skill, agent, or MCP server
  • Documentation or infrastructure change

Testing

  • python3 -m unittest discover -s tests -v: 74 tests pass. They cover the rules on in-memory skills, and the command on throwaway Git repos: exit codes, annotations, touched-only warnings, submodules, self-check failures, a missing Git object exiting 2, and newlines in values that can't start a workflow command.
  • python3 .github/scripts/validate_skills.py --self-check-only: every conformance case passes.
  • python3 .github/scripts/validate_skills.py --base-ref origin/main: 34 skills, 0 errors.
  • pip install --require-hashes -r .github/scripts/skill-rules/requirements.txt installs into a clean venv.

License confirmation

  • By submitting this pull request, I confirm that my contribution is made under the terms of the Apache License 2.0.

@ams-thakkar

Copy link
Copy Markdown
Contributor

Holding this one, and #125 likewise: @aadimch and @miscreantmoogly have each built the same check independently, and the two are not compatible as they stand — most pointedly, metadata.deprecated is specified oppositely (quoted "true" here, unquoted true in #125), and each documents its own form in CONTRIBUTING.md.

I have asked the two of you to agree on which set to keep.

Checks the frontmatter of one skill folder in memory: plain YAML only, name
equal to the folder, description and title limits, metadata as text values,
author as GitHub usernames, a MAJOR.MINOR.PATCH version, and the optional
summary, deprecated, agent_types and dimension fields. Dimension values outside
skill-rules/vocabulary.json are warnings.
validate_skills.py reads every skill folder from Git objects at the head
commit, runs the publishing rules on each, and reports errors as annotations
with file and line. Errors from any skill fail the check; warnings appear only
for skills the pull request touches. Exit code 2 means the check could not run.

Before checking any skill it runs skill-rules/conformance-cases.json, a
language-neutral set of pass/fail skill folders that any other validator or
publisher of these skills can run too, and stops if a case gives the wrong
result.
analytics-opensearch-expertise read 2.6 and database-rds-devops read 1.0.
Skill publishing requires a three-part version, and changing SKILL.md
changes the published content, so each gets a patch bump and a CHANGELOG
entry.
Adds the validate-skills workflow: read-only, no paths filter, actions pinned
by commit SHA, PyYAML installed with --require-hashes. It runs the check's
unit tests, then the check against the pull request's base branch. Advisory
until an admin adds validate-skills to the required status checks.
- Match every pattern with fullmatch: $ also matches before a trailing
  newline, which a YAML block scalar such as version: | produces.
- Report frontmatter nested too deeply for the YAML composer as a finding.
- Fail closed when a rule data file holds a string where a list belongs.
- Validate git cat-file output, and turn any unexpected exception into exit
  code 2, so a broken clone is never reported as the pull request's fault.
- Escape newlines in plain log lines and the step summary, so a path or
  value can't start a workflow command.
- Check the whole tree without a base when the workflow is called with no
  pull request.
…ummary

Every rule applies to every skill. A skill's agent types now come from
metadata.agent_types when set, otherwise from its
aws-devops-agent-skills.agent-types display values through the new
display_mapping in agent-types.json, otherwise GENERIC, which loads it for
all agents and is reported as a warning. The mapping must cover every
display value in vocabulary.json.

A missing metadata.summary is a warning for every skill until existing
skills have one, when it becomes required. The vocabulary gains Amazon
Data Firehose and Streaming Data, used by firehose-operation-review.
@miscreantmoogly
miscreantmoogly force-pushed the validate-skills/1-frontmatter branch from d5aae9e to a63fd3f Compare October 9, 2026 17:35
@miscreantmoogly
miscreantmoogly added this pull request to stack #134 October 9, 2026 20:09

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants