lib/tests/run-review-guards.sh — 5 whole-surface guards that RED if a banned pattern subsists anywhere, auto-run by make test (run-*.sh glob): G1 trailer (A1), G2 false CLAUDE.md attribution (A5), G3 strict-YAML frontmatter (A4), G4 reconcile hermeticity (job3 B1), G5 hook-drift installed==emit (A2). This is the check that would have caught A1/A4/A5/A2 at make-test time instead of an adversarial review — the series' recurring failure was fixing one instance and leaving twins. G3/G5 degrade to SKIP if pyyaml/emit-hook absent (portability). Teeth verified: a planted trailer in a real agent REDs G1. Review fil rouge.
78 lines
3.6 KiB
Bash
78 lines
3.6 KiB
Bash
#!/usr/bin/env bash
|
|
# run-review-guards.sh — anti-"partial-fix" regression guards.
|
|
#
|
|
# Genesis: .audit/review-release-1.0.0.md fil rouge. The 9-job series repeatedly
|
|
# fixed ONE instance of a banned pattern and left the twins (A1 trailer, A4 YAML,
|
|
# A5 false attribution, A2 hook drift). Each guard below greps the WHOLE surface
|
|
# for a pattern and REDs if any occurrence subsists — the check that would have
|
|
# caught A1/A4/A5/A2 at make-test time instead of an adversarial review.
|
|
set -uo pipefail
|
|
|
|
GREP=/usr/bin/grep # LRN-074: pin grep
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO="$(cd "$HERE/../.." && pwd)"
|
|
cd "$REPO"
|
|
|
|
pass=0; fail=0; skip=0
|
|
ok() { echo "GREEN ✓ $*"; pass=$((pass+1)); }
|
|
no() { echo "RED ✗ $*"; fail=$((fail+1)); }
|
|
warn() { echo "SKIP ~ $*"; skip=$((skip+1)); }
|
|
|
|
echo "=== review-guards: anti-partial-fix surface checks ==="
|
|
|
|
# G1 — banned commit-attribution trailers must not live in our own config surface
|
|
# (the ban is [[no-commit-attribution]]; skills-external/ = gstack submodule, excluded).
|
|
# This guard file is excluded: it names the pattern literally as its own search term.
|
|
if hits=$($GREP -rInE --exclude=run-review-guards.sh 'Co-Authored-By|Claude-Session' agents/ lib/ hooks/ templates/ skills/ 2>/dev/null); then
|
|
echo "$hits"; no "G1 trailer: banned attribution trailer present in tracked config surface"
|
|
else
|
|
ok "G1 trailer: zero Co-Authored-By/Claude-Session in agents|lib|hooks|templates|skills"
|
|
fi
|
|
|
|
# G2 — false CLAUDE.md attribution (asserting a user policy CLAUDE.md does not contain)
|
|
if hits=$($GREP -rInE 'per user.{0,5}CLAUDE\.md|User CLAUDE\.md default' agents/ skills/ 2>/dev/null); then
|
|
echo "$hits"; no "G2 attribution: false 'per user CLAUDE.md' policy reference present"
|
|
else
|
|
ok "G2 attribution: zero false CLAUDE.md policy references in agents|skills"
|
|
fi
|
|
|
|
# G3 — every agent frontmatter must be strict-YAML valid (degrade if pyyaml absent)
|
|
if python3 -c 'import yaml' 2>/dev/null; then
|
|
if python3 - "$REPO" <<'PY'
|
|
import glob, os, sys, yaml
|
|
root=sys.argv[1]; bad=0
|
|
for f in sorted(glob.glob(os.path.join(root,'agents','*.md'))):
|
|
try: yaml.safe_load(open(f).read().split('---')[1])
|
|
except Exception as e: print(" FAIL", os.path.relpath(f,root), str(e).splitlines()[0]); bad+=1
|
|
sys.exit(1 if bad else 0)
|
|
PY
|
|
then ok "G3 strict-YAML: all agents/*.md frontmatter parse"
|
|
else no "G3 strict-YAML: an agent frontmatter fails yaml.safe_load"
|
|
fi
|
|
else
|
|
warn "G3 strict-YAML: python3+pyyaml unavailable — skipped"
|
|
fi
|
|
|
|
# G4 — the reconcile test must stay hermetic (fixtures, never the live registry) [job3 B1]
|
|
if $GREP -q '\.claude/memory' lib/tests/run-reconcile.sh 2>/dev/null; then
|
|
no "G4 hermetic: run-reconcile.sh reads the live .claude/memory registry"
|
|
else
|
|
ok "G4 hermetic: run-reconcile.sh reads fixtures only, not the live registry"
|
|
fi
|
|
|
|
# G5 — installed pre-commit hook must match the generator (catches the A2 silent drift:
|
|
# editing _gitflow_emit_pre_commit without re-installing). Degrade if emit-hook absent.
|
|
if emitted=$(bash lib/gitflow.sh emit-hook 2>/dev/null) && [ -n "$emitted" ]; then
|
|
if [ -f .githooks/pre-commit ] && diff -q <(printf '%s\n' "$emitted") .githooks/pre-commit >/dev/null 2>&1; then
|
|
ok "G5 hook-drift: installed .githooks/pre-commit == generator emit-hook"
|
|
else
|
|
no "G5 hook-drift: installed hook diverges from generator (run 'gitflow.sh install-hook')"
|
|
fi
|
|
else
|
|
warn "G5 hook-drift: gitflow.sh emit-hook unavailable — skipped"
|
|
fi
|
|
|
|
echo
|
|
echo "================ $pass GREEN / $fail RED / $skip SKIP (review-guards) ================"
|
|
[ "$fail" -eq 0 ]
|