stem-bio-ai / scripts /validate_skill_structure.sh
Codex
sync hf space snapshot
6a1cba7
#!/usr/bin/env bash
# STEM BIO-AI Skill Package Structure Validator
# Usage: bash validate_skill_structure.sh [SKILL_ROOT]
# Validates the STEM BIO-AI skill package is complete and well-formed
set -euo pipefail
SKILL_ROOT="${1:-.}"
ERRORS=0
WARNINGS=0
print_help() {
echo "STEM BIO-AI Skill Package Structure Validator"
echo ""
echo "Usage: bash validate_skill_structure.sh [SKILL_ROOT]"
echo ""
echo " SKILL_ROOT Path to stem-ai skill directory (default: current directory)"
echo ""
echo "Validates: directory structure, required files, frontmatter, version consistency."
}
if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
print_help
exit 0
fi
check_file() {
local path="$1"
local required="$2"
if [ -f "$SKILL_ROOT/$path" ]; then
echo " [OK] $path"
elif [ "$required" = "required" ]; then
echo " [FAIL] $path -- REQUIRED but missing"
ERRORS=$((ERRORS + 1))
else
echo " [WARN] $path -- recommended but missing"
WARNINGS=$((WARNINGS + 1))
fi
}
check_dir() {
local path="$1"
if [ -d "$SKILL_ROOT/$path" ]; then
echo " [OK] $path/"
else
echo " [FAIL] $path/ -- REQUIRED directory missing"
ERRORS=$((ERRORS + 1))
fi
}
check_contains() {
local path="$1"
local pattern="$2"
local label="$3"
if grep -Fq "$pattern" "$SKILL_ROOT/$path" 2>/dev/null; then
echo " [OK] $label"
else
echo " [FAIL] $label"
ERRORS=$((ERRORS + 1))
fi
}
echo "=== STEM BIO-AI Skill Package Validation ==="
echo "Root: $SKILL_ROOT"
echo ""
echo "--- Root Files ---"
check_file "SKILL.md" "required"
check_file "README.md" "required"
check_file "LICENSE" "required"
check_file "CHANGELOG.md" "required"
check_file "CONTRIBUTING.md" "recommended"
check_file ".gitignore" "recommended"
echo ""
echo "--- Required Directories ---"
check_dir "spec"
check_dir "discrimination"
check_dir "templates"
check_dir "scripts"
check_dir "references"
echo ""
echo "--- Core Spec ---"
CORE=$(find "$SKILL_ROOT/spec/" -name "STEM-AI_v*_CORE.md" 2>/dev/null | sort -V | tail -1)
if [ -n "$CORE" ]; then
echo " [OK] Core spec: $CORE"
else
echo " [FAIL] No STEM-AI_v*_CORE.md found in spec/"
ERRORS=$((ERRORS + 1))
fi
CORE_BASENAME=$(basename "$CORE" 2>/dev/null || true)
CORE_VERSION=$(echo "$CORE_BASENAME" | sed -n 's/^STEM-AI_v\([0-9.]*\)_CORE\.md$/\1/p')
echo ""
echo "--- Version Drift Checks ---"
if [ -n "$CORE_VERSION" ]; then
echo " [INFO] Active core version: $CORE_VERSION"
check_contains "templates/audit_report.md" "v$CORE_VERSION" "audit report template references v$CORE_VERSION"
check_contains "templates/claim_matrix.md" "v$CORE_VERSION" "claim matrix template references v$CORE_VERSION"
check_contains "templates/method_appendix.md" "v$CORE_VERSION" "method appendix references v$CORE_VERSION"
check_contains "templates/errata_log.md" "v$CORE_VERSION" "errata log references v$CORE_VERSION"
check_contains "CONTRIBUTING.md" "spec/STEM-AI_v${CORE_VERSION}_CORE.md" "contributing guide references current core spec"
else
echo " [FAIL] Could not derive core version from spec filename"
ERRORS=$((ERRORS + 1))
fi
MICA_YAML_SPEC=$(sed -n 's/^mica_spec: "\([0-9.]*\)"$/\1/p' "$SKILL_ROOT/memory/mica.yaml" 2>/dev/null | head -1)
MICA_JSON=$(find "$SKILL_ROOT/memory/" -name "stem-ai.mica.v*.json" 2>/dev/null | sort -V | tail -1)
MICA_JSON_SPEC=$(sed -n 's/^ "mica_spec": "\([0-9.]*\)",$/\1/p' "$MICA_JSON" 2>/dev/null | head -1)
if [ -n "$MICA_YAML_SPEC" ] && [ -n "$MICA_JSON_SPEC" ]; then
if [ "$MICA_YAML_SPEC" = "$MICA_JSON_SPEC" ]; then
echo " [OK] MICA spec aligned ($MICA_YAML_SPEC)"
else
echo " [FAIL] MICA spec mismatch: yaml=$MICA_YAML_SPEC json=$MICA_JSON_SPEC"
ERRORS=$((ERRORS + 1))
fi
else
echo " [WARN] Could not read MICA spec version from yaml/json"
WARNINGS=$((WARNINGS + 1))
fi
echo ""
echo "--- Discrimination Files ---"
check_file "discrimination/H1-H6_examples.md" "required"
check_file "discrimination/T2_examples.md" "required"
check_file "discrimination/CA_severity_examples.md" "required"
check_file "discrimination/B3_COI_guide.md" "required"
check_file "discrimination/G1-G5_examples.md" "required"
echo ""
echo "--- Templates ---"
check_file "templates/audit_report.md" "required"
check_file "templates/claim_matrix.md" "required"
check_file "templates/executive_summary.md" "required"
check_file "templates/evidence_ledger.md" "recommended"
check_file "templates/method_appendix.md" "recommended"
check_file "templates/document_control.md" "recommended"
check_file "templates/errata_log.md" "recommended"
echo ""
echo "--- Scripts ---"
check_file "scripts/local_analysis_scan.sh" "required"
check_file "scripts/ca_detection_scan.sh" "required"
check_file "scripts/snapshot_provenance.sh" "required"
echo ""
echo "--- References ---"
check_file "references/tier_decision_table.md" "recommended"
check_file "references/risk_taxonomy.md" "recommended"
check_file "references/clinical_adjacent_triggers.md" "recommended"
echo ""
echo "=== Validation Summary ==="
echo "Errors: $ERRORS"
echo "Warnings: $WARNINGS"
if [ "$ERRORS" -gt 0 ]; then
echo "RESULT: FAIL -- $ERRORS required items missing"
exit 1
else
echo "RESULT: PASS ($WARNINGS warnings)"
exit 0
fi