diff --git a/cli/harness/hooks/arcrun-guard.sh b/cli/harness/hooks/arcrun-guard.sh index e279d31..cf7388a 100644 --- a/cli/harness/hooks/arcrun-guard.sh +++ b/cli/harness/hooks/arcrun-guard.sh @@ -28,10 +28,46 @@ block() { # ── 硬擋:未經人類同意的暴露動作(明確越界,mindset §5)────────────── # 非互動環境下 CC 自己跑「部署對外 webhook / push recipe」= 替人類決定公開。 +# +# 壓測 §9.5 修正(A6):舊版 grep "acr push" 連「在 echo/heredoc 裡**提到** push 字串」 +# 都擋 → CC 連「把可貼上的指令印給使用者看」都做不到,反而違反 §0.5「擋下必指正路」鐵則。 +# 故先判斷此命令是「展示指令」還是「真的執行 push」,只擋後者。 +# +# 誠實限制(mindset §7):shell 命令層**無法 100% 乾淨區分**「執行」與「展示」 +# (例:`echo "跑 acr push"` 與 `acr push` 對單純 grep 都命中)。以下是**啟發式**, +# 目的是降低誤殺、讓「印出正路指令」這條合法用途能通,不是完美防護。邊角情況可能漏判, +# 但漏判方向是「偏向放行展示」——而真正的暴露(執行)仍受 TTY/env 把關。 if echo "$CMD" | grep -qE "acr (push|recipe push)\b"; then - if [ ! -t 0 ] && [ "${ARCRUN_HUMAN_CONFIRMED:-}" != "1" ]; then - block "在非互動環境自動執行暴露動作(acr push / recipe push 會讓東西可被外部呼叫)" \ - "把這動作交給人類在終端機執行,或先讓使用者明示同意。不要替使用者決定公開。" + # 目標(壓測 §9.5):擋「真的執行 push」,放行「把 push 指令印給使用者看」。 + # + # 作法:把 heredoc 主體(cat/印出用的多行文字)先抽掉,剩下的才是「實際會被 shell 執行的命令列」, + # 再看 push 是否出現在那裡的「命令位置」(行首 / ; & | && || 之後)。 + # 執行 → 命中:`acr push x`、`cd f && acr push x`、`echo done; acr push x` + # 展示 → 不命中:`echo "跑 acr push x"`、`cat <\`。或使用者先在對話明示同意後親自於終端機執行。不要替使用者決定公開。" + fi fi fi