diff --git a/scripts/check_model_freshness.py b/scripts/check_model_freshness.py index 5d32c309..39cc679a 100644 --- a/scripts/check_model_freshness.py +++ b/scripts/check_model_freshness.py @@ -35,7 +35,9 @@ import os import re import sys -EXCLUDED_DIRS = { +# Excludes both directory names (pruned during walk) and individual filenames +# (e.g. CHANGELOG.md) — membership is checked against dirnames AND filenames. +EXCLUDED_NAMES = { ".git", ".codex", ".gemini", ".hermes", ".vibe", "node_modules", "docs", # generated mirror; fix the source instead "audit", # audit records quote stale IDs on purpose, that is their job @@ -157,9 +159,9 @@ def scan_file(path, repo_root, allowlist): def collect(repo_root): targets = [] for dirpath, dirnames, filenames in os.walk(repo_root): - dirnames[:] = [d for d in dirnames if d not in EXCLUDED_DIRS] + dirnames[:] = [d for d in dirnames if d not in EXCLUDED_NAMES] for fn in filenames: - if fn in EXCLUDED_DIRS or fn in SELF_FILES: + if fn in EXCLUDED_NAMES or fn in SELF_FILES: continue if fn.endswith(SCAN_EXTENSIONS): targets.append(os.path.join(dirpath, fn)) diff --git a/scripts/derive_counters.py b/scripts/derive_counters.py index cb8b2754..c87060eb 100644 --- a/scripts/derive_counters.py +++ b/scripts/derive_counters.py @@ -3,7 +3,7 @@ Walks the canonical tree (excluding sync copies, docs site, audit workspace, and VCS/CI internals) and derives the headline numbers that README.md, -CLAUDE.md, and .claude-plugin/marketplace.json claim: +CLAUDE.md, marketplace.json, mkdocs.yml, and .codex-plugin/plugin.json claim: skills count of SKILL.md files plugins_on_disk count of **/.claude-plugin/plugin.json manifests @@ -19,11 +19,13 @@ Modes: (default) print a human-readable table --json print the derived counters as JSON --check exit 1 listing mismatches if the headline counters claimed in - README.md, root CLAUDE.md ("Current Scope" line), and - marketplace.json metadata.description disagree with derived - values. Also validates the README "Skills Overview" per-domain - table: every domain row's count must equal the SKILL.md count in - its linked folder, and every on-disk domain must have a row. CI gate G3. + README.md, root CLAUDE.md ("Current Scope" / "Status:" lines), + marketplace.json metadata.description, mkdocs.yml + site_description, or .codex-plugin/plugin.json descriptions + disagree with derived values. Also validates the README + "Skills Overview" per-domain table: every domain row's count + must equal the SKILL.md count in its linked folder, and every + on-disk domain must have a row. CI gate G3. Stdlib only. No writes ever. """ @@ -360,7 +362,7 @@ def main() -> int: parser.add_argument( "--check", action="store_true", - help="exit 1 if README.md / CLAUDE.md / marketplace.json claims drift from derived values", + help="exit 1 if claims in README.md / CLAUDE.md / marketplace.json / mkdocs.yml / .codex-plugin drift from derived values", ) args = parser.parse_args()