fix(gates): check body-level routing targets, not just descriptions #140
Reference in New Issue
Block a user
Delete Branch "fix/124-body-level-routing-targets"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
The ADR-0020 boundary resolver only ever read a SKILL.md's description for routing targets. A target named in the body — a dispatch table row, a "run X" step — was checked by nothing. Two real instances shipped before either was caught by reading rather than by a gate:
bin/write-docsrouted twice to a deletedto-prdskill, andbin/triagetold an agent to run a nonexistent/setup-matt-pocock-skills(both fixed in03abcff; that fix was the symptom, this gate is the actual ask per #124).How
Added a separate, narrower extractor —
body_targets()/unresolved_body_targets()in the sharedlib-boundary-resolver.sh— rather than reusing the description resolver at wider scope. The description gate's sentence-level heuristics (BOUNDARY_MARKER, the follower test, in-sentence corroboration) are tuned for a one-to-three-sentence routing clause and misfire on dispatch-table/procedure prose in both directions, so the body gate reads only explicit route notation (/name, backticked-or-slash-prefixed-> name/→ name) — already the description gate's own unconditionally-blocking tier.Three guards were added after running the extractor over the real 39-skill corpus and reading every hit rather than assuming the design was correct:
`/fork`(forge, citing Claude Code's own/forkcommand) and`/name`(skill-author, a placeholder) are not routes.ARROW_MARKED(backticked/slash-prefixed) is used, notNOTATION_ARROW's bare form, so ordinary process-chain prose ("prop -> new ref -> re-render", caveman) is not read as a route.<is a closing tag (</what-to-do>, grill-with-docs), not/namenotation.Wired into both consumers that must agree by contract:
scripts/skill-size-check.sh(the pre-commit hook) andfactory-audit'slib-checks-skill.sh(the audit). Verified identical findings across both over the whole corpus.Testing
tests/test-adr0020-targets.shgains a dedicated "body-level routing targets (issue #124)" section pinning the two live true positives and all three guards.bash tests/run-tests.sh --strict): 21/21 test files, 423/423 assertions passing.docs/spec/gates.mdand ADR-0020 get a matching amendment (dated 2026-09-22).factory-audit'sSKILL.mdversion bumped 1.0.4 → 1.0.5 per ADR-0022 (scripts it owns changed).Fixes #124
🤖 Generated with Claude Code
https://claude.ai/code/session_01EGHFJextYtVQseaHPDDhxB