job4: seam design-tool-gate.sh

Env-var-only seams (§3.2), zero logic change (diff is only the seam
lines): PROFILE_SH gains DESIGN_GATE_PROFILE_SH override; CLAUDE_BIN
replaces the 5 bare `claude` invocation sites (ensure_claude_on_path's
reachability check + the plugin/mcp branches of tool_active — 2x
`command -v claude` + `claude plugin list` + `claude mcp list`). The
`echo "... claude mcp list  claude plugin list"` hint in the
READY-BUT-UNVERIFIED message stays literal (advisory text for a human,
not an invocation).

Unlocks (BACKLOG, not built here): a hermetic gate suite via
DESIGN_GATE_PROFILE_SH + CLAUDE_BIN injection, promoting J4-21.

Verified: bash -n clean, shellcheck clean, `design-tool-gate.sh design`
against the real repo unchanged ("READY"), full `make test` exit 0.
This commit is contained in:
Bastien Chanot
2026-07-06 21:46:19 +02:00
parent 04da103ed6
commit 5511c51a8e
+7 -6
View File
@@ -42,7 +42,8 @@
set -euo pipefail set -euo pipefail
REPO="$(cd -P "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" REPO="$(cd -P "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PROFILE_SH="$REPO/lib/profile.sh" PROFILE_SH="${DESIGN_GATE_PROFILE_SH:-$REPO/lib/profile.sh}"
CLAUDE_BIN="${CLAUDE_BIN:-claude}"
PROFILES_DIR="$REPO/lib/profiles" PROFILES_DIR="$REPO/lib/profiles"
SKILLS_DIR="$REPO/skills" SKILLS_DIR="$REPO/skills"
PROFILE="${1:-design}" PROFILE="${1:-design}"
@@ -59,7 +60,7 @@ PROFILE_FILE="$PROFILES_DIR/$PROFILE.profile"
# dirs and prepend. nvm keeps old node versions after an upgrade, so pick the # dirs and prepend. nvm keeps old node versions after an upgrade, so pick the
# newest that actually ships claude (sort -V), not the first glob match. # newest that actually ships claude (sort -V), not the first glob match.
ensure_claude_on_path() { ensure_claude_on_path() {
command -v claude >/dev/null 2>&1 && return command -v "$CLAUDE_BIN" >/dev/null 2>&1 && return
local cand local cand
for cand in \ for cand in \
"$HOME/.claude/local/claude" \ "$HOME/.claude/local/claude" \
@@ -98,15 +99,15 @@ tool_active() {
if [ -e "$SKILLS_DIR/$name" ]; then echo active; else echo inactive; fi if [ -e "$SKILLS_DIR/$name" ]; then echo active; else echo inactive; fi
;; ;;
plugin) plugin)
if ! command -v claude >/dev/null 2>&1; then echo unknown; return; fi if ! command -v "$CLAUDE_BIN" >/dev/null 2>&1; then echo unknown; return; fi
if claude plugin list 2>/dev/null \ if "$CLAUDE_BIN" plugin list 2>/dev/null \
| awk -v p="^[[:space:]]*❯ ${name}@" '$0 ~ p {f=1; next} f && /Status:/ {print; exit}' \ | awk -v p="^[[:space:]]*❯ ${name}@" '$0 ~ p {f=1; next} f && /Status:/ {print; exit}' \
| grep -q "✔ enabled" | grep -q "✔ enabled"
then echo active; else echo inactive; fi then echo active; else echo inactive; fi
;; ;;
mcp) mcp)
if ! command -v claude >/dev/null 2>&1; then echo unknown; return; fi if ! command -v "$CLAUDE_BIN" >/dev/null 2>&1; then echo unknown; return; fi
if claude mcp list 2>/dev/null | grep -q "^${name}"; then echo active; else echo inactive; fi if "$CLAUDE_BIN" mcp list 2>/dev/null | grep -q "^${name}"; then echo active; else echo inactive; fi
;; ;;
cli) cli)
if command -v "$name" >/dev/null 2>&1; then echo active; else echo inactive; fi if command -v "$name" >/dev/null 2>&1; then echo active; else echo inactive; fi