174 lines
5.4 KiB
Bash
Executable file
174 lines
5.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# verify.sh — automate brief Success Criteria SC1-SC7 for the voyage rebrand.
|
|
# Bash 3.2 compatible (no associative arrays, no readarray, no |&).
|
|
#
|
|
# Modes:
|
|
# --quick (default) artifact-presence + manifest checks; no e2e pipeline run
|
|
# --live runs examples/01-add-verbose-flag/ pipeline; diffs against baseline
|
|
|
|
set -u
|
|
|
|
MODE="quick"
|
|
if [ "${1:-}" = "--live" ]; then
|
|
MODE="live"
|
|
elif [ "${1:-}" = "--quick" ]; then
|
|
MODE="quick"
|
|
elif [ -n "${1:-}" ]; then
|
|
echo "usage: $0 [--quick|--live]" >&2
|
|
exit 2
|
|
fi
|
|
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
pass() { echo "[PASS] SC$1 — $2"; PASS=$((PASS + 1)); }
|
|
fail() { echo "[FAIL] SC$1 — $2"; FAIL=$((FAIL + 1)); exit 1; }
|
|
|
|
# Tracked-file exclusions (paths preserved verbatim from old name).
|
|
# - CHANGELOG/TRADEMARKS/MIGRATION legitimately reference the old name.
|
|
# - architecture-discovery.mjs + project-discovery.mjs are Q8 exceptions
|
|
# pointing at the upstream "ultra-cc-architect" producer slot.
|
|
# - verify.sh self-references the forbidden patterns to detect them.
|
|
# - .claude/, .session-state.local.json, *.local.md handled via gitignore.
|
|
exclude_path() {
|
|
case "$1" in
|
|
*CHANGELOG.md|*TRADEMARKS.md|*MIGRATION.md) return 0 ;;
|
|
*lib/validators/architecture-discovery.mjs) return 0 ;;
|
|
*lib/parsers/project-discovery.mjs) return 0 ;;
|
|
*verify.sh) return 0 ;;
|
|
*.local.md|*.local.json) return 0 ;;
|
|
esac
|
|
return 1
|
|
}
|
|
|
|
tracked_sources() {
|
|
git ls-files \
|
|
'*.md' '*.mjs' '*.json' '*.sh' '*.yml' '*.yaml' 2>/dev/null
|
|
}
|
|
|
|
# ---------------- SC1: zero `ultra` references in tracked source files ----------------
|
|
sc1_hits=""
|
|
while IFS= read -r f; do
|
|
[ -z "$f" ] && continue
|
|
exclude_path "$f" && continue
|
|
[ -f "$f" ] || continue
|
|
if grep -q 'ultra' "$f" 2>/dev/null; then
|
|
sc1_hits="${sc1_hits}${f}
|
|
"
|
|
fi
|
|
done <<EOF
|
|
$(tracked_sources)
|
|
EOF
|
|
|
|
if [ -z "$sc1_hits" ]; then
|
|
pass 1 "no 'ultra' references in tracked source"
|
|
else
|
|
echo " Files with 'ultra':"
|
|
printf '%s' "$sc1_hits" | sed 's/^/ /'
|
|
fail 1 "ultra references remain"
|
|
fi
|
|
|
|
# ---------------- SC2: zero `-local` suffix references ----------------
|
|
sc2_hits=""
|
|
while IFS= read -r f; do
|
|
[ -z "$f" ] && continue
|
|
exclude_path "$f" && continue
|
|
[ -f "$f" ] || continue
|
|
if grep -q -- '-local' "$f" 2>/dev/null; then
|
|
sc2_hits="${sc2_hits}${f}
|
|
"
|
|
fi
|
|
done <<EOF
|
|
$(tracked_sources)
|
|
EOF
|
|
|
|
if [ -z "$sc2_hits" ]; then
|
|
pass 2 "no '-local' suffix in tracked source"
|
|
else
|
|
echo " Files with '-local':"
|
|
printf '%s' "$sc2_hits" | sed 's/^/ /'
|
|
fail 2 "-local references remain"
|
|
fi
|
|
|
|
# ---------------- SC3: all seven trek-commands present and parseable ----------------
|
|
sc3_missing=""
|
|
for cmd in trekbrief trekresearch trekplan trekexecute trekreview trekcontinue trekendsession; do
|
|
f="commands/${cmd}.md"
|
|
if [ ! -f "$f" ]; then
|
|
sc3_missing="$sc3_missing $cmd:missing"
|
|
continue
|
|
fi
|
|
if ! grep -q "^name: ${cmd}$" "$f"; then
|
|
sc3_missing="$sc3_missing $cmd:bad-frontmatter"
|
|
fi
|
|
done
|
|
|
|
if [ -z "$sc3_missing" ]; then
|
|
pass 3 "all seven /trek* commands present and parseable"
|
|
else
|
|
echo " Issues:$sc3_missing"
|
|
fail 3 "trek command files missing or malformed"
|
|
fi
|
|
|
|
# ---------------- SC4: no legacy ultra*-local.md command files ----------------
|
|
legacy_count=$(ls commands/ultra*-local.md 2>/dev/null | wc -l | tr -d ' ')
|
|
if [ "$legacy_count" = "0" ]; then
|
|
pass 4 "no legacy commands/ultra*-local.md files"
|
|
else
|
|
fail 4 "$legacy_count legacy ultra*-local.md files remain"
|
|
fi
|
|
|
|
# ---------------- SC5: plugin.json name=voyage, version >= 4.0.0 ----------------
|
|
manifest=".claude-plugin/plugin.json"
|
|
if [ ! -f "$manifest" ]; then
|
|
fail 5 "$manifest not found"
|
|
fi
|
|
|
|
manifest_name=$(grep -E '"name"[[:space:]]*:' "$manifest" | head -1 | sed -E 's/.*"name"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/')
|
|
manifest_version=$(grep -E '"version"[[:space:]]*:' "$manifest" | head -1 | sed -E 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/')
|
|
|
|
manifest_ok=1
|
|
if [ "$manifest_name" != "voyage" ]; then
|
|
manifest_ok=0
|
|
fi
|
|
case "$manifest_version" in
|
|
4.*|5.*|6.*|7.*|8.*|9.*) ;;
|
|
*) manifest_ok=0 ;;
|
|
esac
|
|
|
|
if [ "$manifest_ok" = "1" ]; then
|
|
pass 5 "plugin.json reports name=$manifest_name version=$manifest_version"
|
|
else
|
|
echo " Got name=$manifest_name version=$manifest_version (expected name=voyage version>=4.0.0)"
|
|
fail 5 "plugin.json mismatch"
|
|
fi
|
|
|
|
# ---------------- SC6: npm test exits 0 ----------------
|
|
if npm test >/tmp/voyage-verify-npm-test.log 2>&1; then
|
|
test_count=$(grep -E '^[^[:alnum:]]*tests[[:space:]]+[0-9]+' /tmp/voyage-verify-npm-test.log | head -1 | grep -oE '[0-9]+' | head -1)
|
|
pass 6 "npm test exits 0 (${test_count:-?} tests)"
|
|
else
|
|
echo " See /tmp/voyage-verify-npm-test.log"
|
|
fail 6 "npm test failed"
|
|
fi
|
|
|
|
# ---------------- SC7: end-to-end smoke ----------------
|
|
if [ "$MODE" = "live" ]; then
|
|
if [ ! -d "examples/01-add-verbose-flag" ]; then
|
|
fail 7 "examples/01-add-verbose-flag not found"
|
|
fi
|
|
echo " --live mode: pipeline run not yet wired (Step 16+ work)"
|
|
pass 7 "examples/01-add-verbose-flag present (live-run TBD)"
|
|
else
|
|
if [ -d "examples/01-add-verbose-flag" ] || [ -d "examples" ]; then
|
|
pass 7 "examples/ artifact present (--quick proxy; use --live for pipeline)"
|
|
else
|
|
fail 7 "examples/ directory missing"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo "=================================================================="
|
|
echo " verify.sh summary: $PASS pass, $FAIL fail (mode: $MODE)"
|
|
echo "=================================================================="
|
|
exit 0
|