check-resources.sh 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #!/usr/bin/env bash
  2. # Offline resource checks — runs in PR CI, may block.
  3. #
  4. # Exercises the skill verifier/scanner scripts in their OFFLINE/structural mode
  5. # (no network) and asserts basic protocol compliance (SKILL-RESOURCE-PROTOCOL.md):
  6. # every shipped verifier responds to --help with exit 0 and passes its own
  7. # offline self-check against the skill's current content.
  8. #
  9. # The network-dependent --live drift checks run in the scheduled freshness
  10. # workflow, never here — a rate-limit must never block an unrelated PR (§7).
  11. #
  12. # Exit: 0 all checks pass, 1 a check failed.
  13. set -uo pipefail
  14. ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
  15. cd "$ROOT" || exit 1
  16. # Pick a working python (Windows Store python3 stub exits 49 on --version).
  17. PY="python3"
  18. if ! "$PY" --version >/dev/null 2>&1; then PY="python"; fi
  19. fail=0
  20. pass() { echo " ok $*"; }
  21. bad() { echo " FAIL $*"; fail=1; }
  22. run() { # description, expected-exit, command...
  23. local desc="$1" want="$2"; shift 2
  24. "$@" >/dev/null 2>&1; local got=$?
  25. if [ "$got" -eq "$want" ]; then pass "$desc (exit $got)"; else bad "$desc (want $want, got $got)"; fi
  26. }
  27. echo "== claude-api-ops: model-table verifier"
  28. run "model-table --offline consistent" 0 "$PY" skills/claude-api-ops/scripts/check-model-table.py --offline
  29. run "model-table --help" 0 "$PY" skills/claude-api-ops/scripts/check-model-table.py --help
  30. echo "== terraform-ops: action-ref verifier"
  31. run "action-refs --offline well-formed" 0 bash skills/terraform-ops/scripts/check-action-refs.sh --offline
  32. run "action-refs --help" 0 bash skills/terraform-ops/scripts/check-action-refs.sh --help
  33. echo "== claude-code-ops: hooks.json validator"
  34. run "hooks-lint clean on repo hooks.json" 0 "$PY" skills/claude-code-ops/scripts/validate-hooks-json.py hooks/hooks.json
  35. run "hooks-lint --help" 0 "$PY" skills/claude-code-ops/scripts/validate-hooks-json.py --help
  36. echo "== playwright-ops: flake-triage"
  37. run "flake-triage --help" 0 "$PY" skills/playwright-ops/scripts/triage-flakes.py --help
  38. echo "== ffmpeg-ops: command/resource verifier"
  39. run "ffmpeg-ops --offline consistent" 0 bash skills/ffmpeg-ops/scripts/verify-commands.sh --offline
  40. run "ffmpeg-ops --help" 0 bash skills/ffmpeg-ops/scripts/verify-commands.sh --help
  41. echo "== ytdlp-ops: version/staleness verifier"
  42. run "ytdlp-ops --offline consistent" 0 bash skills/ytdlp-ops/scripts/check-ytdlp-version.sh --offline
  43. run "ytdlp-ops --help" 0 bash skills/ytdlp-ops/scripts/check-ytdlp-version.sh --help
  44. echo "== mapbox-ops: fact/staleness verifier"
  45. run "mapbox-ops --offline consistent" 0 "$PY" skills/mapbox-ops/scripts/check-mapbox-facts.py --offline
  46. run "mapbox-ops --help" 0 "$PY" skills/mapbox-ops/scripts/check-mapbox-facts.py --help
  47. echo "== fleet-worker: doctor (preflight + staleness) verifier"
  48. run "fleet-doctor --offline consistent" 0 bash skills/fleet-worker/scripts/fleet-doctor.sh --offline
  49. run "fleet-doctor --help" 0 bash skills/fleet-worker/scripts/fleet-doctor.sh --help
  50. echo "== loop-ops: pricing-sync verifier"
  51. run "pricing-sync --offline in sync" 0 "$PY" skills/loop-ops/scripts/check-pricing-sync.py --offline
  52. run "pricing-sync --help" 0 "$PY" skills/loop-ops/scripts/check-pricing-sync.py --help
  53. echo "== loop-ops: worked example is gate-clean (dogfood)"
  54. LOOP_EX="skills/loop-ops/assets/examples/pr-watch/loop.config.yaml"
  55. run "example audits clean" 0 bash skills/loop-ops/scripts/loop-check.sh "$LOOP_EX"
  56. run "example doctors clean (offline)" 0 bash skills/loop-ops/scripts/loop-doctor.sh --offline "$LOOP_EX"
  57. echo "== r-ops: R-stack staleness verifier"
  58. run "r-facts --offline consistent" 0 "$PY" skills/r-ops/scripts/check-r-facts.py --offline
  59. run "r-facts --help" 0 "$PY" skills/r-ops/scripts/check-r-facts.py --help
  60. echo "== threejs-ops: three.js fact/staleness verifier"
  61. run "three-facts --offline consistent" 0 "$PY" skills/threejs-ops/scripts/check-three-facts.py --offline
  62. run "three-facts --help" 0 "$PY" skills/threejs-ops/scripts/check-three-facts.py --help
  63. echo "== isometric-ops: projection-constant/staleness verifier"
  64. run "iso-facts --offline consistent" 0 "$PY" skills/isometric-ops/scripts/check-iso-facts.py --offline
  65. run "iso-facts --help" 0 "$PY" skills/isometric-ops/scripts/check-iso-facts.py --help
  66. echo "== protocol: every new verifier is executable + compiles"
  67. for s in skills/claude-api-ops/scripts/check-model-table.py \
  68. skills/claude-code-ops/scripts/validate-hooks-json.py \
  69. skills/playwright-ops/scripts/triage-flakes.py \
  70. skills/mapbox-ops/scripts/check-mapbox-facts.py \
  71. skills/loop-ops/scripts/check-pricing-sync.py \
  72. skills/r-ops/scripts/check-r-facts.py \
  73. skills/threejs-ops/scripts/check-three-facts.py \
  74. skills/isometric-ops/scripts/check-iso-facts.py; do
  75. "$PY" -m py_compile "$s" 2>/dev/null && pass "py_compile $(basename "$s")" || bad "py_compile $(basename "$s")"
  76. done
  77. bash -n skills/terraform-ops/scripts/check-action-refs.sh 2>/dev/null \
  78. && pass "bash -n check-action-refs.sh" || bad "bash -n check-action-refs.sh"
  79. bash -n skills/ffmpeg-ops/scripts/verify-commands.sh 2>/dev/null \
  80. && pass "bash -n verify-commands.sh" || bad "bash -n verify-commands.sh"
  81. bash -n skills/ytdlp-ops/scripts/check-ytdlp-version.sh 2>/dev/null \
  82. && pass "bash -n check-ytdlp-version.sh" || bad "bash -n check-ytdlp-version.sh"
  83. bash -n skills/fleet-worker/scripts/fleet-doctor.sh 2>/dev/null \
  84. && pass "bash -n fleet-doctor.sh" || bad "bash -n fleet-doctor.sh"
  85. echo "== terminal design: verifier framing adopts term.sh and is ASCII-pure"
  86. # Each verifier renders its human framing on stderr; under TERM_ASCII=1 every
  87. # glyph must fall back to its registered ASCII proxy (design principle #3).
  88. purity() { # desc, cmd...
  89. local desc="$1"; shift
  90. local errout
  91. errout="$(TERM_ASCII=1 FORCE_COLOR=1 "$@" 2>&1 1>/dev/null)"
  92. if printf '%s' "$errout" | LC_ALL=C grep -q '[^[:print:][:cntrl:]]'; then
  93. bad "$desc framing emits non-ASCII under TERM_ASCII=1"
  94. else pass "$desc framing pure ASCII under TERM_ASCII=1"; fi
  95. }
  96. purity "action-refs" bash skills/terraform-ops/scripts/check-action-refs.sh --offline
  97. purity "model-table" "$PY" skills/claude-api-ops/scripts/check-model-table.py --offline
  98. purity "hooks-lint" "$PY" skills/claude-code-ops/scripts/validate-hooks-json.py hooks/hooks.json
  99. __tf="$(mktemp)"; printf '{"suites":[]}' > "$__tf"
  100. purity "flake-triage" "$PY" skills/playwright-ops/scripts/triage-flakes.py "$__tf"
  101. rm -f "$__tf"
  102. purity "fleet-doctor" bash skills/fleet-worker/scripts/fleet-doctor.sh --offline
  103. purity "pricing-sync" "$PY" skills/loop-ops/scripts/check-pricing-sync.py --offline
  104. purity "r-facts" "$PY" skills/r-ops/scripts/check-r-facts.py --offline
  105. grep -q '_lib/term.sh' skills/terraform-ops/scripts/check-action-refs.sh \
  106. && pass "check-action-refs sources term.sh" || bad "check-action-refs missing term.sh"
  107. grep -q '_lib/term.sh' skills/fleet-worker/scripts/fleet-doctor.sh \
  108. && pass "fleet-doctor sources term.sh" || bad "fleet-doctor missing term.sh"
  109. for s in skills/claude-api-ops/scripts/check-model-table.py \
  110. skills/claude-code-ops/scripts/validate-hooks-json.py \
  111. skills/playwright-ops/scripts/triage-flakes.py \
  112. skills/loop-ops/scripts/check-pricing-sync.py \
  113. skills/r-ops/scripts/check-r-facts.py; do
  114. grep -q 'class Term' "$s" && pass "$(basename "$s") carries inline Term" \
  115. || bad "$(basename "$s") missing inline Term"
  116. done
  117. echo
  118. if [ "$fail" -eq 0 ]; then echo "resource checks: clean"; exit 0; fi
  119. echo "resource checks: failures above"; exit 1