diff --git a/hooks/design-toolchain-reminder.sh b/hooks/design-toolchain-reminder.sh index b69bc9e..a43be4d 100755 --- a/hooks/design-toolchain-reminder.sh +++ b/hooks/design-toolchain-reminder.sh @@ -25,6 +25,12 @@ prompt="$(printf '%s' "$input" \ 2>/dev/null || true)" [ -z "$prompt" ] && prompt="$input" +# Harness-generated turns (subagent/task notifications) are not user +# requests — never fire on them (CLAUDE.md trigger = a design/UI *request*). +case "$prompt" in + ''*) exit 0 ;; +esac + lc="$(printf '%s' "$prompt" | tr '[:upper:]' '[:lower:]')" # UI/design build and review signals (FR + EN). Word boundaries (\b) avoid diff --git a/lib/tests/design-toolchain-reminder.test.sh b/lib/tests/design-toolchain-reminder.test.sh index a7d59a1..959882f 100644 --- a/lib/tests/design-toolchain-reminder.test.sh +++ b/lib/tests/design-toolchain-reminder.test.sh @@ -6,7 +6,7 @@ pass=0; fail=0 check() { if [ "$2" = "$3" ]; then pass=$((pass+1)); else fail=$((fail+1)); printf 'FAIL %s: got[%s] want[%s]\n' "$1" "$2" "$3"; fi; } # fire() -> "fire" if the hook emits the reminder, else "quiet". -fire() { if printf '{"prompt":"%s"}' "$1" | bash "$H" | grep -q "design-toolchain"; then +fire() { if printf '{"prompt":"%s"}' "$1" | bash "$H" | grep -q 'full toolchain'; then echo fire; else echo quiet; fi; } # --- Dropped/neutralized tokens must be QUIET (non-UI senses) --- @@ -19,6 +19,10 @@ check D6-frontend "$(fire 'frontend architecture')" quiet check D7-palette "$(fire 'a palette of options')" quiet check D8-dash-file "$(fire 'ecc_dashboard.py')" quiet +# --- Harness-generated inputs must be QUIET even with UI tokens --- +check D9-tasknotif "$(fire ' x add css header fonts')" quiet +check D10-notif-file "$(fire ' design-motion-principles keyframe done')" quiet + # --- Real UI signals must still FIRE --- check F1-button "$(fire 'add a button')" fire check F2-navbar "$(fire 'the navbar layout')" fire