兩支閘改看「指令要動的那個 repo」,不看 hook 自己的環境/cwd(inkstone/ISEP#109 → comment 6629)

① line-needs-own-worktree.sh:出路 `WORKTREE_OK=1 git -C … checkout …` 改認指令字串裡的字面前綴
   (舊版讀 hook 自己的環境變數,PreToolUse hook 跟指令不是同一個行程,那行永遠走不通)。
   判準是位置不是字:前綴必須掛在會移動 HEAD 的那條 git 指令上。
   lib/checkout_target_dir.py 加 `--escape NAME=1`;push_target_dir._classify 在 strip_env 時
   把前綴留在 verb 事件裡(find_push_target 行為不變,主線閘 10+19 條照綠)。
② github-contact-guard.sh:remote 名在「這條指令實際會推的那個 repo」裡解(沿用 lib/push_target_dir.py
   解 cd 鏈/-C/子殼),解不出來才退回 cwd。判準仍是 remote URL 主機,不是「有 -C 就放行」。

測試:A24 59→69(E 群把閘印的那一行原樣餵回去;舊閘 3 條紅)、
      A39 14→26(payload 帶 cwd、cwd≠目標 repo;舊閘 7 條紅=4 誤攔+3 漏擋)。
盤點表:61 支/85 條,改判準不加閘,當場數的。
版本:待總管定版。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178ef1fGw3XeZtpN7LaZrm4
This commit is contained in:
isep-hand
2026-09-07 06:31:45 +00:00
parent bcf7c05a7b
commit 49a7145e70
9 changed files with 242 additions and 28 deletions
@@ -213,6 +213,38 @@ else
printf ' ❌ (59) lib/checkout_target_dir.py 不見了\n'; FAIL=$((FAIL+1))
fi
echo
echo "── E 群:出路要真的走得通(inkstone/ISEP#109 → comment 65872026-09-07 實撞)──"
# 為什麼這群非有不可:閘訊息教的出路是 `WORKTREE_OK=1 git -C … checkout …`
# 而舊版讀的是 **hook 自己的環境變數**。PreToolUse hook 在指令執行之前跑,
# 指令字串裡的 `WORKTREE_OK=1` 是給 git 的前綴賦值,hook 的行程裡根本沒有它
# ⇒ 那條出路在 Claude Code 這個 harness 下永遠走不通(總管當天三次照貼三次被擋)。
# 🔴 這群的測資是「閘自己印出來的那一行」,原樣餵回去——驗的是出路跑不跑得動,
# 不是閘擋不擋(mistakes.md「閘擋對了,但它印出來的那條出路跑不動」)。
# 判準是**位置**不是字:那個賦值必須是「會移動 HEAD 的那條 git 指令」自己的前綴。
t 0 "(60) 指令字串裡帶 WORKTREE_OK=1 前綴、hook 的環境裡**沒有**它 ⇒ 放行" \
"WORKTREE_OK=1 git checkout -b feat/esc" "$REPO"
t 2 "(61) 先擋一次,拿它印出來的出路當下一條的測資" "git checkout main" "$REPO"
ESC_LINE=$(printf '%s' "$LAST_ERR" | grep -F 'WORKTREE_OK=1 git -C' | head -1 | sed 's/^[[:space:]]*//; s/<分支>/main/')
N=$((N+1))
if [ -n "$ESC_LINE" ]; then printf ' ✅ (62) 抽得出那一行:%s\n' "$ESC_LINE"; PASS=$((PASS+1))
else printf ' ❌ (62) 訊息裡抽不出 WORKTREE_OK=1 git -C … 那一行\n'; FAIL=$((FAIL+1)); ESC_LINE="WORKTREE_OK=1 git -C $REPO checkout main"; fi
t 0 "(63) 閘印出來的那一行**原樣餵回去**(只填分支、人站在別處)⇒ 放行——6587 那天走不通的就是這條" \
"$ESC_LINE" "$PLAIN"
t 2 "(64) 只是印了那個字:echo WORKTREE_OK=1; git checkout main ⇒ 照擋(看位置不看字)" \
"echo WORKTREE_OK=1; git checkout main"
t 2 "(65) 前綴掛在別的指令上:WORKTREE_OK=1 echo hi && git checkout main ⇒ 照擋" \
"WORKTREE_OK=1 echo hi && git checkout main"
t 2 "(66) 值不是 1WORKTREE_OK=0 git checkout main ⇒ 照擋" \
"WORKTREE_OK=0 git checkout main"
t 2 "(67) 寫在 commit 訊息裡再切 ⇒ 照擋(引號裡的字不是前綴)" \
"git commit -qm 'WORKTREE_OK=1 git checkout main' ; git checkout main"
t 0 "(68) cd 進去再掛前綴:cd <repo> && WORKTREE_OK=1 git checkout main ⇒ 放行" \
"cd $REPO && WORKTREE_OK=1 git checkout main" "$PLAIN"
t 0 "(69) 在自己的 worktree 裡也掛了前綴 ⇒ 本來就放行,前綴不礙事" \
"WORKTREE_OK=1 git checkout -b feat/x2" "$OWN"
clean
echo
echo "══ $PASS/$N 通過${FAIL:+$FAIL 個失敗} ══"