feat(kyberforge): enforce the ADR-0020 context contract for skills and agents

Skill name+description pairs are preloaded into every session, costing
~6,200 tokens across 39 skills before any skill is invoked. The authoring
rules mandated that growth: skill-author:104 and description-quality.md:21
both required padding, while skill-author:102 (the deflating rule) had no
FAIL condition behind it.

Gates (blocking, no baseline file):
- description 250 chars SUGGESTION / 400 FAIL, measured on the folded
  YAML value
- body-only 600 words SUGGESTION / 900 FAIL, independent of the unchanged
  whole-file 2770-word / 500-line spec backstop
- every boundary-clause routing target must resolve to a real skill or
  agent; catches skill-improve, neuledge-context and gitea-labels
- agents take the description gates but deliberately no body gate; a test
  pins that absence

Vale: DescriptionOpener widened to ^This\b, new CompositionNote rule
banning architecture notes from descriptions. 10 hits, 0 false positives.

Kyberforge's own four skills retrofitted: descriptions 3,364 -> 938 chars
(-72%), bodies 8,306 -> 2,487 words (-70%), all via the apm-workflow
dispatch pattern. Fixes the skill-improve dangling route and the
agent-author misroute to manual review.

Also fixes a pre-existing false positive where any line-initial 'read '
was flagged as interactive input, which had already caused two scripts to
be rewritten around it.

Refs: ADR-0020
This commit is contained in:
2026-08-14 21:13:13 +00:00
parent 1c6eababb0
commit 4a5c3c0cff
104 changed files with 6272 additions and 1880 deletions

View File

@@ -145,6 +145,81 @@ kyberforge-vale-audit-skill|skills/demo/SKILL.md|helps with
kyberforge-vale-audit-agent|agents/demo.md|utilize
EOF
# --- 1b. Every rule in the shipped style is asserted to FIRE, not merely to
# exist. A Vale rule can be well-formed, load without a diagnostic, and match
# nothing at all: `extends: existence` CONCATENATES multiple `raw:` entries
# rather than alternating them, so a rule written as a list of alternatives
# silently becomes one impossible expression, lints every file clean and exits
# 0 — indistinguishable from a corpus with no violations. `Kyberforge.CompositionNote`
# was written that way first and passed all 43 skill and agent files before the
# defect was found by hand. Each rule gets its own fixture pass, with the token
# it must quote attributed to the file that raised it, so one rule's alert can
# never stand in for another's.
echo ""
echo "--- each Kyberforge description rule fires through both shipped hooks ---"
write_desc_fixtures() {
local skill_desc="$1" agent_desc="$2"
cat > "$CONSUMER/skills/demo/SKILL.md" <<EOF
---
name: demo
description: >
$skill_desc across two
physical lines of one folded block scalar.
---
Body.
EOF
cat > "$CONSUMER/agents/demo.md" <<EOF
---
name: demo
description: >
$agent_desc across two
physical lines of one folded block scalar.
---
Body.
EOF
git -C "$CONSUMER" add -A
}
run_rule_case() {
local label="$1" hook_id="$2" fixture="$3" token="$4"
local log="$WORK/rule-$label.log"
set +e
(cd "$CONSUMER" && pre-commit run "$hook_id" --all-files > "$log" 2>&1)
local rc=$?
set -e
if grep -q "Skipped" "$log"; then
fail "$hook_id matched no files for $label, so it proved nothing"
sed 's/^/ /' "$log"
elif [[ $rc -eq 0 ]]; then
fail "$hook_id passed $fixture despite its flagged '$token' — $label matches nothing"
sed 's/^/ /' "$log"
elif alerts_for "$fixture" < "$log" | grep -qF "'$token'"; then
pass "$label fires through $hook_id and quotes '$token' under $fixture"
else
fail "$hook_id failed, but no $label alert quoting '$token' was filed under $fixture"
sed 's/^/ /' "$log"
fi
}
# CompositionNote: a distinct banned token per file shape.
write_desc_fixtures \
"Use when the caller wants a demo skill that composes other skills" \
"Use when the caller wants a cross-cutting demo agent"
run_rule_case "Kyberforge.CompositionNote" kyberforge-vale-audit-skill skills/demo/SKILL.md "composes"
run_rule_case "Kyberforge.CompositionNote" kyberforge-vale-audit-agent agents/demo.md "cross-cutting"
# DescriptionOpener: the widened pattern catches every non-imperative "This..."
# opener, not only the literal "This skill"/"This agent" pair it was anchored to
# before. Both fixtures open with "This is", the form two shipped descriptions
# used mid-sentence and which the old pattern could not express.
write_desc_fixtures \
"This is a demo skill for callers who want one" \
"This is a demo agent for callers who want one"
run_rule_case "Kyberforge.DescriptionOpener" kyberforge-vale-audit-skill skills/demo/SKILL.md "This"
run_rule_case "Kyberforge.DescriptionOpener" kyberforge-vale-audit-agent agents/demo.md "This"
# --- 2. Clean files pass — the hooks gate, they don't just always fail ---
echo ""
echo "--- all three hooks pass clean files in an external consumer repo ---"