ci(skill-check): scan the docs a contributor reads
The check asserts that every make target named in a doc exists, and its scanned set was .pi/ plus CLAUDE.md. Since #50, CONTRIBUTING.md is the document a *human* goes to for a build command, and it names 21 targets that nothing verified; README.md names none today and is in for the same reason. The script's own header sentence is the argument — a renamed target sends a person off the same cliff it sends an agent off. The file list is now one `docs` variable used twice, because the failure message carried a second copy of it and a second list is a second thing to forget. The `[ -d .pi ]` guard went with it: gating the whole run on .pi/ would make the human-facing half conditional on the agent-facing one, and an empty list is the same "nothing to scan" exit without the coupling. The lefthook glob is that scanned set now rather than {Makefile,.pi/**/*.md} — #220's smaller half, and it did not fire on CLAUDE.md either, which the script had read for months. Verified by planting a bad target rather than by reading the diff: both matched forms in each of the four scanned surfaces, each naming the right file; the same two plants pass on the pre-change script; unfenced prose still does not match; and the hook fires on a staged CONTRIBUTING.md under the new glob where the old one skipped it. The count is unchanged at 47 — the set is a union — so coverage is the only thing that moved. Closes #220
This commit is contained in:
+21
-4
@@ -14,6 +14,11 @@
|
||||
# missing: CLAUDE.md names 27 targets and nothing verified one of them,
|
||||
# so the file the agents trust most was the file least checked.
|
||||
#
|
||||
# README.md and CONTRIBUTING.md are in it too, and the header sentence
|
||||
# above is why: a person who has *not* read the Makefile goes looking in
|
||||
# the contributor-facing doc, so a renamed target sends them off the
|
||||
# same cliff it sends an agent off. CONTRIBUTING.md names 21 targets.
|
||||
#
|
||||
# **AGENTS.md is a symlink to CLAUDE.md.** This repo is worked on by
|
||||
# two agent harnesses that read different files by convention — Claude
|
||||
# Code reads CLAUDE.md, others read AGENTS.md — and two harnesses
|
||||
@@ -43,7 +48,19 @@ if [ -e AGENTS.md ] || [ -L AGENTS.md ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -d .pi ] || exit 0
|
||||
# The scan is over the docs that are actually there: a checkout without
|
||||
# .pi/ still has README.md and CONTRIBUTING.md to check, and gating the
|
||||
# whole run on .pi/ would have made the human-facing half conditional on
|
||||
# the agent-facing one. This list is used twice — once to read the
|
||||
# mentions out and once to say which file a missing target came from —
|
||||
# because a second list is a second thing to forget.
|
||||
# `ls` exits non-zero when *any* of its arguments is missing while still
|
||||
# printing the ones that are there, and under `set -e` that would sink
|
||||
# the assignment rather than scanning what exists, so swallow it.
|
||||
docs="$({ find .pi -name '*.md' 2>/dev/null
|
||||
ls CLAUDE.md README.md CONTRIBUTING.md 2>/dev/null || true; })"
|
||||
|
||||
[ -n "$docs" ] || exit 0
|
||||
|
||||
# `make -pq` prints the database including every rule, without running
|
||||
# anything. It exits non-zero when a target is out of date, and under
|
||||
@@ -68,7 +85,7 @@ targets="$({ make -pqRr 2>/dev/null || true; } |
|
||||
# AGENTS.md is deliberately not in this list: it is a symlink to
|
||||
# CLAUDE.md, asserted above, so scanning it would report every failure
|
||||
# twice under two names.
|
||||
mentioned="$({ find .pi -name '*.md' 2>/dev/null; echo CLAUDE.md; } |
|
||||
mentioned="$(printf '%s\n' "$docs" |
|
||||
xargs awk '
|
||||
FNR == 1 { fence = 0 }
|
||||
/^```/ { fence = !fence; next }
|
||||
@@ -93,10 +110,10 @@ for t in $mentioned; do
|
||||
done
|
||||
|
||||
if [ -n "$missing" ]; then
|
||||
echo "skill-check: the agent docs name make targets that do not exist:" >&2
|
||||
echo "skill-check: the docs name make targets that do not exist:" >&2
|
||||
for t in $missing; do
|
||||
echo " make $t" >&2
|
||||
grep -rln "make $t" .pi CLAUDE.md --include='*.md' | sed 's/^/ /' >&2
|
||||
printf '%s\n' "$docs" | xargs grep -ln "make $t" | sed 's/^/ /' >&2
|
||||
done
|
||||
echo "Fix the docs, or restore the target." >&2
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user