fix(lint): tighten the SKILL.md word ceiling to 2770
MAX_WORDS=2900 was calibrated to the corpus median density and carried no
margin: at the densest observed 7.22 chars/word (~1.81 tokens/word) it permits
~5,240 tokens against the 5,000 it proxies for. 2770 holds the worst observed
density under the ceiling. The largest SKILL.md is 2,489 words, so the change
costs nothing today — 281 words of margin — and the header comment now argues
the new calibration rather than swapping the digits.
Both enforcement points move together, and a new test asserts they agree, since
a SKILL.md passing its own audit while the commit hook blocks it is the
disagreement this pair exists to prevent.
CONTEXT.md is deliberately left ungated: it is 2,816 words, and gating it would
block the build. Recorded here so the omission reads as a decision rather than
an oversight.
skill-audit's manual-fallback path listed only the line ceiling, so an agent
taking that path passed an oversized SKILL.md the hook then rejected. The word
ceiling is now named alongside it. agent-audit is deliberately unchanged: the
size hook scopes to SKILL.md only and agent-audit's validate.sh has no word
gate, so claiming it there would be false.
The Vale research doc still showed the MDX {/* vale off */} form under a
Markdown heading, contradicting CONTEXT.md and vale-run's troubleshooting
reference — that form suppresses nothing in plain .md. Fixed in both places it
appeared.
tests/run-tests.sh used mapfile (bash 4.0+) with unguarded array expansion,
though AGENTS.md tells contributors to run it and macOS ships bash 3.2. It now
collects via a while-read loop over process substitution and guards every
expansion. The newline-delimited find|sort pipeline is kept rather than -print0
with sort -z, whose BSD portability is the weaker link, and which matches
mapfile -t's previous behaviour exactly.
Refs: #85
ADR: 0013
This commit is contained in:
@@ -35,14 +35,24 @@ fi
|
||||
|
||||
run_bats
|
||||
|
||||
mapfile -t SCRIPTS < <(
|
||||
# Collected with a `while read` loop rather than `mapfile` — macOS ships
|
||||
# /bin/bash 3.2, which has no `mapfile`. Process substitution (not a pipe)
|
||||
# keeps the loop in this shell so the appends survive. `sort` is still fed
|
||||
# newline-delimited output, exactly as before.
|
||||
SCRIPTS=()
|
||||
while IFS= read -r script; do
|
||||
SCRIPTS+=("$script")
|
||||
done < <(
|
||||
find "$SEARCH_ROOT" -name "test-*.sh" \
|
||||
-not -path "*/.git/*" \
|
||||
-not -path "*/.claude/worktrees/*" \
|
||||
| sort
|
||||
)
|
||||
|
||||
for script in "${SCRIPTS[@]}"; do
|
||||
# bash before 4.4 treats "${arr[@]}" on an empty array as unbound under
|
||||
# `set -u`, so every array expansion here uses the ${arr[@]+"${arr[@]}"} guard,
|
||||
# including the SKIPPED/FAILED loops already fenced by a count check.
|
||||
for script in ${SCRIPTS[@]+"${SCRIPTS[@]}"}; do
|
||||
rel="${script#"$SEARCH_ROOT/"}"
|
||||
echo "=== $rel ==="
|
||||
rc=0
|
||||
@@ -60,13 +70,13 @@ done
|
||||
echo "=== Summary: $PASSED passed, ${#SKIPPED[@]} skipped, ${#FAILED[@]} failed ==="
|
||||
if [[ ${#SKIPPED[@]} -gt 0 ]]; then
|
||||
echo "Skipped scripts:"
|
||||
for s in "${SKIPPED[@]}"; do
|
||||
for s in ${SKIPPED[@]+"${SKIPPED[@]}"}; do
|
||||
echo " $s"
|
||||
done
|
||||
fi
|
||||
if [[ ${#FAILED[@]} -gt 0 ]]; then
|
||||
echo "Failed scripts:"
|
||||
for s in "${FAILED[@]}"; do
|
||||
for s in ${FAILED[@]+"${FAILED[@]}"}; do
|
||||
echo " $s"
|
||||
done
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user