#!/usr/bin/env bash # test-sc4-phase9-coverage.sh — Verifies SC4 (Phase 9 critique-iterate coverage) # # Four checks: # (1) references/05-critique-iterate.md exists and carries the four # sub-phase headings '## 9a'..'## 9d'. # (2) SKILL.md carries the '## Phase 9 — Critique-iterate' section heading, # at least 5 'Phase 9' occurrences, and '### 9a'..'### 9d'. # (3) Every references/presets/*.md carries a critique-iterate hint block. # ANCHOR NOTE: the hint block's heading letter is PER FILE — four presets # end at '## (e)' and got '## (f) Critique-iterate hint'; four end at # '## (f)' and got '## (g) Critique-iterate hint'. The canonical # machine-checkable anchor is therefore the LETTER-FREE substring # 'Critique-iterate hint'. Never anchor on the letter: a test grepping # '## (g)' would fail on four files, and the "fix" would be to break the # letter sequence in shipped content. # (4) references/05-critique-iterate.md carries >=1 Anthropic-domain citation. # # Anthropic-domain URL regex (same as test-sc3-citations.sh): # https?://(docs\.anthropic\.com|anthropic\.com|github\.com/anthropics # |claude\.com|support\.claude\.com|platform\.claude\.com) # # Usage: bash tests/test-sc4-phase9-coverage.sh # Exit codes: 0 = pass; 1 = at least one FAIL set -euo pipefail LC_ALL=en_US.UTF-8 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' PLUGIN_ROOT="$(cd "$(dirname "$0")/.." && pwd)" PASS=0 FAIL=0 WARN=0 pass() { printf "${GREEN} ✓ %s${NC}\n" "$1"; PASS=$((PASS + 1)); } fail() { printf "${RED} ✗ %s${NC}\n" "$1"; FAIL=$((FAIL + 1)); } warn() { printf "${YELLOW} ⚠ %s${NC}\n" "$1"; WARN=$((WARN + 1)); } SKILL_DIR="$PLUGIN_ROOT/skills/claude-design-facilitator" CRITIQUE_REF="$SKILL_DIR/references/05-critique-iterate.md" SKILL_FILE="$SKILL_DIR/SKILL.md" PRESET_DIR="$SKILL_DIR/references/presets" ANTHROPIC_REGEX='https?://(docs\.anthropic\.com|anthropic\.com|github\.com/anthropics|claude\.com|support\.claude\.com|platform\.claude\.com)' echo "=== test-sc4-phase9-coverage ===" echo "Plugin root: $PLUGIN_ROOT" echo "" # ------------------------------------------------------- # (1) 05-critique-iterate.md exists with 9a..9d sub-phases # ------------------------------------------------------- echo "--- (1) shared critique-iterate reference ---" if [ ! -f "$CRITIQUE_REF" ]; then fail "references/05-critique-iterate.md missing" else pass "references/05-critique-iterate.md exists" for sub in 9a 9b 9c 9d; do if grep -q "^## $sub" "$CRITIQUE_REF"; then pass "05-critique-iterate.md: '## $sub' heading present" else fail "05-critique-iterate.md: '## $sub' heading missing" fi done fi echo "" # ------------------------------------------------------- # (2) SKILL.md Phase 9 section # ------------------------------------------------------- echo "--- (2) SKILL.md Phase 9 section ---" if [ ! -f "$SKILL_FILE" ]; then fail "SKILL.md missing" else if grep -qF '## Phase 9 — Critique-iterate' "$SKILL_FILE"; then pass "SKILL.md: '## Phase 9 — Critique-iterate' heading present" else fail "SKILL.md: '## Phase 9 — Critique-iterate' heading missing" fi P9_COUNT="$(grep -oF 'Phase 9' "$SKILL_FILE" | wc -l | tr -d '[:space:]')" if [ -z "$P9_COUNT" ]; then P9_COUNT=0; fi if [ "$P9_COUNT" -ge 5 ]; then pass "SKILL.md: $P9_COUNT 'Phase 9' occurrence(s) (need >=5)" else fail "SKILL.md: only $P9_COUNT 'Phase 9' occurrence(s) (need >=5)" fi for sub in 9a 9b 9c 9d; do if grep -q "^### $sub" "$SKILL_FILE"; then pass "SKILL.md: '### $sub' heading present" else fail "SKILL.md: '### $sub' heading missing" fi done fi echo "" # ------------------------------------------------------- # (3) Every preset carries a critique-iterate hint block # Anchored on the LETTER-FREE substring (see header note). # ------------------------------------------------------- echo "--- (3) per-preset critique-iterate hint blocks ---" if [ ! -d "$PRESET_DIR" ]; then fail "references/presets/ directory missing" else PRESET_COUNT=0 while IFS= read -r preset_file; do [ -z "$preset_file" ] && continue PRESET_COUNT=$((PRESET_COUNT + 1)) relname="$(basename "$preset_file")" if grep -qF 'Critique-iterate hint' "$preset_file"; then pass "presets/$relname: 'Critique-iterate hint' block present" else fail "presets/$relname: 'Critique-iterate hint' block missing" fi done < <(find "$PRESET_DIR" -maxdepth 1 -name '*.md' -type f | sort) if [ "$PRESET_COUNT" -eq 0 ]; then fail "references/presets/ contains zero .md files — nothing was checked" else pass "presets examined: $PRESET_COUNT" fi fi echo "" # ------------------------------------------------------- # (4) 05-critique-iterate.md citation coverage # ------------------------------------------------------- echo "--- (4) citation coverage for 05-critique-iterate.md ---" if [ ! -f "$CRITIQUE_REF" ]; then fail "references/05-critique-iterate.md missing — cannot check citations" else CITE_COUNT="$(grep -cE "$ANTHROPIC_REGEX" "$CRITIQUE_REF" || true)" if [ -z "$CITE_COUNT" ]; then CITE_COUNT=0; fi if [ "$CITE_COUNT" -ge 1 ]; then pass "05-critique-iterate.md: $CITE_COUNT Anthropic-domain URL citation(s)" else fail "05-critique-iterate.md: zero Anthropic-domain URL citations" fi fi echo "" echo "=== Summary ===" printf "Pass: %d Fail: %d Warn: %d\n" "$PASS" "$FAIL" "$WARN" if [ "$FAIL" -gt 0 ]; then exit 1 fi exit 0