#!/usr/bin/env bash # leo21c-mcp-guard.sh 的迴歸測試(ISEP#69)。 HOOK="$1" rm -f /tmp/.leo21c-mcp-ok 2>/dev/null # 起手清乾淨,避免上一輪殘留戳記污染這輪 mk(){ python3 -c "import json,sys;print(json.dumps({'tool_name':sys.argv[1],'tool_input':{}}))" "$1"; } PASS=0; FAIL=0 t(){ # t <期望 block|pass> <說明> —— 除了明說放行那幾格,其餘每格開跑前先確保沒有殘留戳記 mk "$3" | "$HOOK" >/dev/null 2>&1; rc=$? got=$([ $rc -eq 2 ] && echo block || echo pass) if [ "$got" = "$1" ]; then echo " ✅ $2"; PASS=$((PASS+1)) else echo " ❌ $2 —— 期望 $1,實得 $got"; FAIL=$((FAIL+1)); fi } LEO="00402d88-5e2f-4125-b971-8bdac50d7456" YOULIN="d0eaf65b-583e-464e-aacc-00527ac05c4b" UNKNOWN="11111111-2222-3333-4444-555555555555" echo "── 該擋(打向 leo21c 真庫)──" t block "唯讀查詢打 leo21c" "mcp__${LEO}__kbdb_search" t block "get_map 打 leo21c" "mcp__${LEO}__kbdb_get_map" t block "寫入打 leo21c" "mcp__${LEO}__kbdb_create_record" t block "推工作流打 leo21c" "mcp__${LEO}__arcrun_push_workflow" echo "── 該放行(打向 youlin 測試場)──" t pass "唯讀查詢打 youlin" "mcp__${YOULIN}__kbdb_search" t pass "寫入打 youlin" "mcp__${YOULIN}__kbdb_create_record" t pass "查 template 打 youlin" "mcp__${YOULIN}__kbdb_list_templates" t pass "arcrun 讀清單打 youlin" "mcp__${YOULIN}__arcrun_list_workflows" echo "── 不該擋:arcrun_whoami 本身(不管打哪條線)──" t pass "whoami 打 leo21c" "mcp__${LEO}__arcrun_whoami" t pass "whoami 打 youlin" "mcp__${YOULIN}__arcrun_whoami" t pass "whoami 打未知 UUID" "mcp__${UNKNOWN}__arcrun_whoami" echo "── 不該擋:非 kbdb/arcrun 的 MCP 工具、非 MCP 工具 ──" t pass "無關的 MCP 工具" "mcp__${LEO}__some_other_tool" t pass "一般工具名" "Bash" t pass "另一個一般工具" "kbdb_search" echo "── 該擋(清單以外的未知 UUID —— 對照表可能過期,大聲失敗)──" t block "未知 UUID 的 kbdb_search" "mcp__${UNKNOWN}__kbdb_search" t block "未知 UUID 的寫入" "mcp__${UNKNOWN}__kbdb_create_record" echo "── 明說要打真庫:戳記放行(單次)──" rm -f /tmp/.leo21c-mcp-ok touch /tmp/.leo21c-mcp-ok t pass "戳記在,打 leo21c 放行一次" "mcp__${LEO}__kbdb_search" # 上面 t() 已經在下一次呼叫前 rm -f 戳記,這裡驗證戳記確實是單次 touch /tmp/.leo21c-mcp-ok mk "mcp__${LEO}__kbdb_search" | "$HOOK" >/dev/null 2>&1 mk "mcp__${LEO}__kbdb_search" | "$HOOK" >/dev/null 2>&1; rc2=$? if [ $rc2 -eq 2 ]; then echo " ✅ 戳記用完即消失(第二次仍被擋)"; PASS=$((PASS+1)) else echo " ❌ 戳記用完即消失 —— 期望第二次被擋,實得 pass"; FAIL=$((FAIL+1)); fi rm -f /tmp/.leo21c-mcp-ok 2>/dev/null echo "── 明說放行要留痕 ──" LOGDIR="${CLAUDE_PROJECT_DIR:-$(pwd)}/.claude/hooks" mkdir -p "$LOGDIR" rm -f "$LOGDIR/leo21c-mcp-guard.log" touch /tmp/.leo21c-mcp-ok mk "mcp__${LEO}__kbdb_search" | "$HOOK" >/dev/null 2>&1 if [ -f "$LOGDIR/leo21c-mcp-guard.log" ] && grep -q "明說放行" "$LOGDIR/leo21c-mcp-guard.log"; then echo " ✅ 明說放行有寫進 log"; PASS=$((PASS+1)) else echo " ❌ 明說放行沒有留痕"; FAIL=$((FAIL+1)) fi rm -f "$LOGDIR/leo21c-mcp-guard.log" /tmp/.leo21c-mcp-ok 2>/dev/null echo echo "結果:通過 $PASS / 失敗 $FAIL" [ $FAIL -eq 0 ] || exit 1