#!/bin/sh # Tests for the agents/ directory the plugin ships, and doctor's shadow check. # # skills#51: pr-gatekeeper blocked dispatch#75 five times, every block a real # escape verified by execution — and the agent definition lived only at # ~/.claude/agents/pr-gatekeeper.md on one host. Unversioned, unreviewable, one # rm from gone. Doctrine now depends on it (local-dev AGENT.md rule 8), so the # file has to be in the repo. # # These assertions observe FILE CONTENT and doctor's OUTPUT. They cannot and do # not claim the agent reviews well — naming them otherwise would be the exact # defect rule 9 exists for. set -u ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) AGENT="$ROOT/agents/pr-gatekeeper.md" DOCTOR="$ROOT/bin/doctor" pass=0 fail=0 WORK=${TMPDIR:-/tmp}/agents_test.$$ ok() { pass=$((pass + 1)); printf 'ok: %s\n' "$1"; } no() { fail=$((fail + 1)); printf 'FAIL: %s\n' "$1"; } # --- the file is in the repo ------------------------------------------------ if [ -f "$AGENT" ]; then ok 'agents/pr-gatekeeper.md exists in the checkout' else no 'agents/pr-gatekeeper.md exists in the checkout' printf '\n%s passed, %s failed\n' "$pass" "$fail" exit 1 fi # --- frontmatter is present and well-formed --------------------------------- head -1 "$AGENT" | grep -q '^---$' \ && ok 'the file opens with a frontmatter fence' \ || no 'the file opens with a frontmatter fence' for field in name description tools; do if sed -n '2,/^---$/p' "$AGENT" | grep -q "^$field:"; then ok "frontmatter declares $field" else no "frontmatter declares $field" fi done fm_name=$(sed -n '2,/^---$/p' "$AGENT" | sed -n 's/^name: *//p' | head -1) if [ "$fm_name" = "pr-gatekeeper" ]; then ok 'the frontmatter name equals the filename stem' else no "the frontmatter name equals the filename stem (got '$fm_name')" fi # --- the practices that actually found the defects -------------------------- # # Each string below is traceable to a specific round of dispatch#75 or to the # incident the agent itself caused. A grep is a weak check — it proves the # phrase is present, not that the procedure is followed — so the test is named # for the phrase, not for the behaviour. check_phrase() { if grep -qi -- "$1" "$AGENT"; then ok "the file names: $2" else no "the file names: $2" fi } check_phrase 'verify by execution' 'verify by execution, not by reading the implementation' check_phrase 'flip' 'flip-testing' check_phrase 'read the survivors' 'read the survivors of a differential' check_phrase 'exit code' 'grade a linter on its exit code' check_phrase 'never the buffer' 'a probe prints a count, never the buffer' check_phrase 'claims more than' 'a test name must not claim more than it proves' # --- doctor flags a host-local copy that shadows the shipped one ------------ setup() { rm -rf "$WORK" mkdir -p "$WORK/home/.claude/agents" "$WORK/ck/skills/x" "$WORK/ck/agents" printf 'x\n' > "$WORK/ck/skills/x/SKILL.md" printf -- '---\nname: pr-gatekeeper\n---\n' > "$WORK/ck/agents/pr-gatekeeper.md" } setup printf -- '---\nname: pr-gatekeeper\n---\n' > "$WORK/home/.claude/agents/pr-gatekeeper.md" out=$(HOME="$WORK/home" DOCTOR_CHECKOUT="$WORK/ck" sh "$DOCTOR" 2>&1) if printf '%s' "$out" | grep -q 'pr-gatekeeper'; then ok 'doctor reports a host-local agent that shadows a shipped one' else no "doctor reports a host-local agent that shadows a shipped one (got: $out)" fi setup out=$(HOME="$WORK/home" DOCTOR_CHECKOUT="$WORK/ck" sh "$DOCTOR" 2>&1) if printf '%s' "$out" | grep -q 'pr-gatekeeper'; then no "doctor is silent when no host-local copy exists (got: $out)" else ok 'doctor is silent when no host-local copy exists' fi rm -rf "$WORK" printf '\n%s passed, %s failed\n' "$pass" "$fail" [ "$fail" -eq 0 ]