The 'Validate frontmatter' step interpolated step output directly into a
double-quoted shell string, allowing a fork PR that adds a file named
e.g. agents/$(curl ...).md to execute arbitrary commands on the runner.
- Pass the file list via env: and reference as "$FILES" so the shell
never re-evaluates the contents
- Pass PR number via env: for consistency (no ${{ }} inside run:)
- Gate the job on same-repo PRs only, since fork PRs are auto-closed by
close-external-prs.yml anyway
Impact was bounded (fork PRs get a read-only token with no secrets), but
this closes the RCE-on-runner vector entirely.
The workflow was passing deleted files to the validation script, which
failed when trying to read them. Add --diff-filter=AMRC to only process
Added, Modified, Renamed, and Copied files.
Adds a GitHub Actions workflow that validates frontmatter in agent,
skill, and command .md files changed by a PR. Checks:
- Agents: name and description are present and parseable
- Skills: description is present (required for Skill tool discovery)
- Commands: description is present and parseable
The workflow only runs when PRs touch files in agents/, skills/, or
commands/ directories, and only validates the changed files.