兩支閘改看「指令要動的那個 repo」,不看 hook 自己的環境/cwd:worktree 出路走得通、D20 看 push 實際目標(inkstone/ISEP#109→6629、#125) #145

Merged
claude-code merged 2 commits from feat/109-gate-sees-target-repo into main 2026-09-07 06:40:09 +00:00
Member

【身份】isep-hand/inkstone/ISEP/feat/109-gate-sees-target-repo

票:inkstone/ISEP#109(comment 6629 派工;6587 是第一支的實撞);順手關掉 inkstone/ISEP#125 的缺陷 A 與 D/E(驗收表 A–F 進測試)。

改了什麼(兩支閘同一種病:看的是 hook 自己的環境/cwd,不是指令要動的那個 repo)

09-07 撞到的 改法 判準
line-needs-own-worktree.sh 出路 WORKTREE_OK=1 git -C … checkout … 照貼三次三次被擋 指令字串裡的字面前綴(lib/checkout_target_dir.py --escape WORKTREE_OK=1);環境變數那條路保留 位置不是字:前綴必須掛在會移動 HEAD 的那條 git 指令上——echo WORKTREE_OK=1; git checkout、掛在別的指令上、值不是 1、寫在 commit 訊息裡,四種照擋
同上(#125 D/E) heredoc 寫文件、內含 cd <目錄> && git checkout X 示範被擋 lib/strip_heredoc.py 剝 body 再解析(D20 閘同一支 helper) 真的切(#125-F)仍 2
github-contact-guard.sh 薄殼 cwd git -C <InkStoneCo> push origin x 被判「origin 指向 GitHub」 remote 名在這條指令實際會推的那個 repo 裡解(沿用 lib/push_target_dir.py:cd 鏈/-C/子殼不外洩),解不出來才退回 cwd 仍是 remote URL 主機這個唯一識別碼,不是「有 -C 就放行」——站在 Gitea 那份 -C 到薄殼推 GitHub 照擋(舊版這個方向其實漏擋

push_target_dir._classifystrip_env 時把前綴留在 verb 事件裡;find_push_target 行為不變(推 main 那道閘 10+19 條照綠)。
沒加閘:ls hooks/*.sh | wc -l=61、grep -c '"command":' hooks/hooks.json=85,改完當場數的;盤點表三格集合對帳(A1/A2)皆空。

測過的(全部貼原始輸出在票上 comment)

  • bash hooks/tests/line-needs-own-worktree.test.sh77/77(59→77:E 群把閘印的那一行原樣餵回去;F 群=#125 A–F)。修之前拿新測試跑舊閘:(60)(63)(68) 三條紅
  • bash scripts/test-github-contact-guard.sh26/26(14→26:payload 帶 cwd、cwd≠目標 repo)。舊閘 7 條紅=4 誤攔+3 漏擋
  • main-and-prod-push-guard 10/10、cross-repo 19/19;check-version-consistency.sh 0.26.0;claude plugin validate .
  • 真路徑實跑(cwd=/home/user/inkstoneco 薄殼,origin=github.com):git -C …/InkStoneCo push origin x → exit 0;git push origin x → exit 2 並印出「/home/user/inkstoneco 的 remote「origin」指向 GitHub」;git -C …/ISEP checkout main(CHILD=1)→ 2,把它印的那行填上分支原樣餵回 → 0(舊版同一行 → 2)

沒做/另報

  • tokenize 層把換行當空白吞:…EOF⏎git checkout main 從第一版起就看不到(舊閘 exit=0,漏擋不是誤攔),寫成 (76) 已知邊界測試;修它會連帶改推 main 那道閘的偵測範圍,與 (53) 同層,另報
  • not-my-branch-guard.shNOT_MY_BRANCH_OK=1 同樣只讀環境變數(第 28 行),沒動、沒實測

版本:待總管定版(改了會被載入的 hook 與 lib)。

🤖 Generated with Claude Code

https://claude.ai/code/session_0178ef1fGw3XeZtpN7LaZrm4

【身份】isep-hand/inkstone/ISEP/feat/109-gate-sees-target-repo 票:inkstone/ISEP#109(comment 6629 派工;6587 是第一支的實撞);順手關掉 inkstone/ISEP#125 的缺陷 A 與 D/E(驗收表 A–F 進測試)。 ## 改了什麼(兩支閘同一種病:看的是 hook 自己的環境/cwd,不是指令要動的那個 repo) | 閘 | 09-07 撞到的 | 改法 | 判準 | |---|---|---|---| | `line-needs-own-worktree.sh` | 出路 `WORKTREE_OK=1 git -C … checkout …` 照貼三次三次被擋 | 認**指令字串裡**的字面前綴(`lib/checkout_target_dir.py --escape WORKTREE_OK=1`);環境變數那條路保留 | 位置不是字:前綴必須掛在會移動 HEAD 的那條 git 指令上——`echo WORKTREE_OK=1; git checkout`、掛在別的指令上、值不是 1、寫在 commit 訊息裡,四種照擋 | | 同上(#125 D/E) | heredoc 寫文件、內含 `cd <目錄> && git checkout X` 示範被擋 | 先 `lib/strip_heredoc.py` 剝 body 再解析(D20 閘同一支 helper) | 真的切(#125-F)仍 2 | | `github-contact-guard.sh` | 薄殼 cwd `git -C <InkStoneCo> push origin x` 被判「origin 指向 GitHub」 | remote 名在**這條指令實際會推的那個 repo** 裡解(沿用 `lib/push_target_dir.py`:cd 鏈/`-C`/子殼不外洩),解不出來才退回 cwd | 仍是 remote URL 主機這個唯一識別碼,**不是「有 -C 就放行」**——站在 Gitea 那份 `-C` 到薄殼推 GitHub 照擋(舊版這個方向其實**漏擋**) | `push_target_dir._classify` 在 `strip_env` 時把前綴留在 verb 事件裡;`find_push_target` 行為不變(推 main 那道閘 10+19 條照綠)。 沒加閘:`ls hooks/*.sh | wc -l`=61、`grep -c '"command":' hooks/hooks.json`=85,改完當場數的;盤點表三格集合對帳(A1/A2)皆空。 ## 測過的(全部貼原始輸出在票上 comment) - `bash hooks/tests/line-needs-own-worktree.test.sh` → **77/77**(59→77:E 群把閘印的那一行原樣餵回去;F 群=#125 A–F)。修之前拿新測試跑舊閘:(60)(63)(68) 三條紅 - `bash scripts/test-github-contact-guard.sh` → **26/26**(14→26:payload 帶 cwd、cwd≠目標 repo)。舊閘 **7 條紅=4 誤攔+3 漏擋** - `main-and-prod-push-guard` 10/10、cross-repo 19/19;`check-version-consistency.sh` ✅ 0.26.0;`claude plugin validate .` ✅ - 真路徑實跑(cwd=`/home/user/inkstoneco` 薄殼,origin=github.com):`git -C …/InkStoneCo push origin x` → exit 0;`git push origin x` → exit 2 並印出「`/home/user/inkstoneco` 的 remote「origin」指向 GitHub」;`git -C …/ISEP checkout main`(CHILD=1)→ 2,把它印的那行填上分支原樣餵回 → 0(舊版同一行 → 2) ## 沒做/另報 - tokenize 層把**換行**當空白吞:`…EOF⏎git checkout main` 從第一版起就看不到(舊閘 exit=0,漏擋不是誤攔),寫成 (76) 已知邊界測試;修它會連帶改推 main 那道閘的偵測範圍,與 (53) 同層,另報 - `not-my-branch-guard.sh` 的 `NOT_MY_BRANCH_OK=1` 同樣只讀環境變數(第 28 行),沒動、沒實測 **版本:待總管定版**(改了會被載入的 hook 與 lib)。 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0178ef1fGw3XeZtpN7LaZrm4
claude-code added 2 commits 2026-09-07 06:36:12 +00:00
① 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
#125 缺陷 D/E(09-02 兩次實地命中):用 heredoc 寫一份內含 `cd <目錄> && git checkout X` 示範的
說明文件,整條指令沒有 git 操作卻被擋。沿用 lib/strip_heredoc.py(D20 閘同一支)先剝 body 再解析。
A–F 六條照票上期望值進 hooks/tests/(A–E 0、F 2)。
(76) 把 tokenize 層「換行被當空白吞掉」寫成已知邊界測試(舊閘同樣 exit=0,漏擋不是誤攔,與 (53) 同層,另報)。
A24:69→77。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178ef1fGw3XeZtpN7LaZrm4
claude-code merged commit f13eed7ca2 into main 2026-09-07 06:40:09 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: inkstone/ISEP#145