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:
2026-08-09 17:23:51 +00:00
parent f6eb0d295e
commit 302f6d0c19
8 changed files with 80 additions and 23 deletions

View File

@@ -20,13 +20,15 @@ set -euo pipefail
# ~4-characters-per-token English approximation that is 1.49 / 1.70 / 1.69 /
# 1.81 tokens per word.
#
# MAX_WORDS=2900 is therefore calibrated to the corpus MEDIAN, not to its worst
# case, and carries no margin: 2900 x 1.70 = ~4,900 tokens for a median-density
# file, but 2900 x 1.81 = ~5,240 tokens for the densest file in the corpus. So
# what this gate actually guarantees is "under 5,000 tokens for a file of
# typical prose density"; a prose-dense SKILL.md can sit at exactly MAX_WORDS
# and still be a few hundred tokens over the agentskills.io ceiling. Holding
# the worst observed ratio under 5,000 tokens would need MAX_WORDS ~2770.
# MAX_WORDS=2770 is therefore calibrated to the corpus WORST case rather than
# its median: 2770 words at the densest observed 7.22 chars/word is ~20,000
# characters, or ~5,000 tokens at the 4-characters-per-token approximation. So
# what this gate guarantees is "under 5,000 tokens even for the densest prose
# the corpus has produced" — the earlier median-calibrated MAX_WORDS=2900 let
# such a file sit at exactly the ceiling and still spend ~5,240 tokens. A
# median-density file at 2770 words spends ~4,700 tokens, so typical prose
# gives up ~130 words of headroom to close that gap. The largest SKILL.md in
# the repo is 2,489 words, so no current file is affected.
#
# It is a one-sided proxy in the useful direction — nothing under the word
# ceiling is wildly over the token ceiling — but it is not exact BPE
@@ -34,7 +36,7 @@ set -euo pipefail
# any of these numbers as still current.
MAX_LINES=500
MAX_WORDS=2900
MAX_WORDS=2770
FAIL=0
for f in "$@"; do