skill-audit/agent-audit's Step 1 resolved vale-wrap.sh/.vale.ini via `git rev-parse --show-toplevel`, which returns whichever repo the skill happens to run in. Inside ai-development that works; in any external repo that installs kyberforge@holocron as a plugin, it resolves to that repo's own root, which has no .vale.ini — the prefilter silently fell back to full LLM judgment. ADR-0013 named this as a deliberately deferred gap. Vale's config/styles/wrapper now ship inside the plugin itself: a canonical copy in agent-audit/assets/vale/ (Kyberforge + KyberforgeCopilot, the superset agent-audit needs) and a smaller duplicate in skill-audit/assets/vale/ (Kyberforge only) — per the no-cross-skill-path rule already established for plugin cache-installs. Both skills resolve these relative to their own directory, same as scripts/validate.sh already does. A new root .pre-commit-hooks.yaml exposes both copies plus skill-size-check so any external repo can enforce the same rules via `repo: <this-repo-url>, rev: <tag>` in its own pre-commit config, independent of Claude Code entirely — the same mechanism covers CI. This repo's own pre-commit hook now consumes the identical plugin-bundled copies via repo: local (not a third root copy, and not a pinned self-reference, which would lint working-tree edits against the last tagged release instead of the change being made). Split into vale-audit-prefilter-skill/-agent hooks after confirming, by diffing the full corpus against both old and new config before deleting the old files, that one combined hook pointed at only one copy silently 0-file- skips the other file type. scripts/check-vale-style-sync.sh guards the two copies against drift, wired at pre-push alongside check-manifests. ADR: 0014
92 lines
3.5 KiB
Bash
Executable File
92 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
SCRIPT="$REPO_ROOT/scripts/check-vale-style-sync.sh"
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
pass() { echo " PASS: $1"; PASS=$((PASS + 1)); }
|
|
fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); }
|
|
|
|
# Helper: make a fixture repo with skill-audit/agent-audit's Vale copies, in sync by default.
|
|
make_fixture() {
|
|
local dir
|
|
dir="$(mktemp -d)"
|
|
local skill_audit="$dir/plugins/kyberforge/skills/skill-audit"
|
|
local agent_audit="$dir/plugins/kyberforge/skills/agent-audit"
|
|
mkdir -p "$skill_audit/scripts" "$skill_audit/assets/vale/styles/Kyberforge"
|
|
mkdir -p "$agent_audit/scripts" "$agent_audit/assets/vale/styles/Kyberforge"
|
|
|
|
echo '#!/usr/bin/env bash' > "$skill_audit/scripts/vale-wrap.sh"
|
|
echo 'echo wrap' >> "$skill_audit/scripts/vale-wrap.sh"
|
|
cp "$skill_audit/scripts/vale-wrap.sh" "$agent_audit/scripts/vale-wrap.sh"
|
|
|
|
echo 'extends: existence' > "$skill_audit/assets/vale/styles/Kyberforge/Rule.yml"
|
|
cp "$skill_audit/assets/vale/styles/Kyberforge/Rule.yml" "$agent_audit/assets/vale/styles/Kyberforge/Rule.yml"
|
|
|
|
echo "$dir"
|
|
}
|
|
|
|
# --- 1. Exits 0 when the two copies are in sync ---
|
|
echo ""
|
|
echo "--- exits 0 when skill-audit and agent-audit copies are in sync ---"
|
|
FIXTURE="$(make_fixture)"
|
|
trap 'rm -rf "$FIXTURE"' EXIT
|
|
if bash "$SCRIPT" "$FIXTURE" > /dev/null 2>&1; then
|
|
pass "exits 0 when copies are in sync"
|
|
else
|
|
fail "exited non-zero against in-sync copies"
|
|
fi
|
|
|
|
# --- 2. Exits 1 when vale-wrap.sh differs between the two copies ---
|
|
echo ""
|
|
echo "--- exits 1 when vale-wrap.sh differs ---"
|
|
FIXTURE2="$(make_fixture)"
|
|
trap 'rm -rf "$FIXTURE" "$FIXTURE2"' EXIT
|
|
echo 'echo different' >> "$FIXTURE2/plugins/kyberforge/skills/skill-audit/scripts/vale-wrap.sh"
|
|
if bash "$SCRIPT" "$FIXTURE2" > /dev/null 2>&1; then
|
|
fail "exited 0 when vale-wrap.sh copies differ — expected exit 1"
|
|
else
|
|
pass "exits non-zero when vale-wrap.sh copies differ"
|
|
fi
|
|
|
|
# --- 3. Exits 1 when a style rule differs between the two copies ---
|
|
echo ""
|
|
echo "--- exits 1 when a Kyberforge style rule differs ---"
|
|
FIXTURE3="$(make_fixture)"
|
|
trap 'rm -rf "$FIXTURE" "$FIXTURE2" "$FIXTURE3"' EXIT
|
|
echo 'level: error' >> "$FIXTURE3/plugins/kyberforge/skills/agent-audit/assets/vale/styles/Kyberforge/Rule.yml"
|
|
if bash "$SCRIPT" "$FIXTURE3" > /dev/null 2>&1; then
|
|
fail "exited 0 when a style rule differs — expected exit 1"
|
|
else
|
|
pass "exits non-zero when a Kyberforge style rule differs between copies"
|
|
fi
|
|
|
|
# --- 4. Exits 1 when a rule file exists in only one copy ---
|
|
echo ""
|
|
echo "--- exits 1 when a rule file is missing from one copy ---"
|
|
FIXTURE4="$(make_fixture)"
|
|
trap 'rm -rf "$FIXTURE" "$FIXTURE2" "$FIXTURE3" "$FIXTURE4"' EXIT
|
|
echo 'extends: existence' > "$FIXTURE4/plugins/kyberforge/skills/agent-audit/assets/vale/styles/Kyberforge/Extra.yml"
|
|
if bash "$SCRIPT" "$FIXTURE4" > /dev/null 2>&1; then
|
|
fail "exited 0 when a rule file exists in only one copy — expected exit 1"
|
|
else
|
|
pass "exits non-zero when a rule file is missing from one copy"
|
|
fi
|
|
|
|
# --- 5. Exits 0 (no-op) when kyberforge isn't present in the target repo ---
|
|
echo ""
|
|
echo "--- exits 0 when kyberforge skills are absent (no-op) ---"
|
|
FIXTURE5="$(mktemp -d)"
|
|
trap 'rm -rf "$FIXTURE" "$FIXTURE2" "$FIXTURE3" "$FIXTURE4" "$FIXTURE5"' EXIT
|
|
if bash "$SCRIPT" "$FIXTURE5" > /dev/null 2>&1; then
|
|
pass "exits 0 as a no-op when skill-audit/agent-audit don't exist"
|
|
else
|
|
fail "exited non-zero when skill-audit/agent-audit are simply absent"
|
|
fi
|
|
|
|
echo ""
|
|
echo "Results: $PASS passed, $FAIL failed"
|
|
[[ $FAIL -eq 0 ]]
|