From eb9c29300844b97a62046df830c4814e2dca4a1b Mon Sep 17 00:00:00 2001 From: fOuttaMyPaint Date: Sat, 18 Jul 2026 21:27:45 -0400 Subject: [PATCH] ci: enforce the README example count in validate-counts The job enforced skills/rules/templates/snippets but not examples, so the '20 examples' figure in the README could silently go stale when example 21 lands. Counts example directories by README.md presence (robust against stray dirs), mirrors the existing substring check, and was proven to fail on a deliberate mismatch before shipping. Co-Authored-By: Claude Fable 5 --- .github/workflows/validate.yml | 9 ++++++++- AGENTS.md | 6 +++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 60b60be..a69a8ec 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -244,6 +244,11 @@ jobs: f for f in os.listdir('snippets') if f.endswith('.py') ]) + example_count = len([ + d for d in os.listdir('examples') + if os.path.isdir(os.path.join('examples', d)) + and os.path.exists(os.path.join('examples', d, 'README.md')) + ]) readme = open('README.md').read() if f'{skill_count} skills' not in readme: @@ -255,11 +260,13 @@ jobs: errors.append(f'README template count mismatch (expected "{template_count} {template_word}" substring)') if f'{snippet_count} snippets' not in readme: errors.append(f'README snippet count mismatch (expected "{snippet_count} snippets" substring)') + if f'{example_count} examples' not in readme: + errors.append(f'README example count mismatch (expected "{example_count} examples" substring)') if errors: for e in errors: print(f'::error::{e}', file=sys.stderr) sys.exit(1) - print(f'Counts verified: {skill_count} skills, {rule_count} rules, {template_count} {template_word}, {snippet_count} snippets') + print(f'Counts verified: {skill_count} skills, {rule_count} rules, {template_count} {template_word}, {snippet_count} snippets, {example_count} examples') PYEOF diff --git a/AGENTS.md b/AGENTS.md index ca0f8d5..2e2cd40 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -119,9 +119,9 @@ way, and a one-paragraph rationale. 30 to 80 lines is the right size. ## CI/CD workflows - `validate.yml` runs file structure checks plus a `validate-counts` job that - asserts the README aggregate counts (12 skills, 6 rules, 2 templates, 17 - snippets) match filesystem reality. The counts language in `README.md` is - load-bearing: the job greps for it. + asserts the README aggregate counts (skills, rules, templates, snippets, + and examples) match filesystem reality. The counts language in `README.md` + is load-bearing: the job greps for it. - `validate.yml` also runs a `validate-manifest` job that checks `.cursor-plugin/plugin.json` against reality: every listed path must exist, every skill, rule, snippet, template, and example on disk must be listed,