Files
ISEP/hooks/lib/path-resolve.sh
T
Leo 770a0ee824 移除自造的待驗單機制,改由 Gitea 原生三格承接(inkstone/ISEP#60)
subagent-claim-worksheet.sh(SubagentStop 產待驗單)與 claim-verify-police.sh
(Stop 攔收工)這一套整組移除。它們守的東西違反 D58(不要硬做平台不支援的機制)
——「待驗單」只是一張沒有狀態、沒有持有人的 markdown,必然退化成雜訊。

改由 inkstone/ISEP#59/PR #58 的三個 Gitea 原生欄位承接同樣的情境:
子票相依(存在嗎/做完了嗎)、s/* tag(卡在哪)、指派(誰該動)。

- hooks/hooks.json:移除 Stop/SubagentStop 兩條註冊
- hooks/lib/path-resolve.sh:拿掉已刪檔案的註解引用
- docs/hooks-inventory.md、README.md:更新閘數量(48→46 檔、59→57 條註冊)
- docs/governance/sdd-gitea-governance.md:E12/E14 標記現況,新增 §8.4 說明
  移交對象;PR #58 未 merge 前這兩條實質仍是待建,誠實標記
- .claude-plugin/plugin.json:0.5.0 → 0.6.0(版本沒動=plugin update 是 no-op)

未動 docs/governance/DIVERGENCE-v0.5.0-to-v0.6.0.md——那是 2026-08-20 的
時間點快照(意見書),修改它等於竄改歷史記錄,不在本票範圍。

未動 InkStoneCo/.claude/pending-verification/{done,done-20260826,verified}/
三個歸檔目錄——它們是 InkStoneCo repo 裡的已提交檔案,跨 repo 且需要
InkStoneCo 自己的 git 流程處理,超出本票(ISEP repo)範圍,留給總管判斷。

測試:scripts/test-*.sh 全數 6 支通過;hooks/tests/*.test.sh 與 pristine
origin/main 基準比對,失敗特徵完全一致(環境既有問題,非本次改動引入);
claude plugin validate . 通過。check-version-consistency.sh 目前會報不一致
(0.6.0 vs tag v0.5.0)——這是預期的,等總管收斂 release 打 v0.6.0 tag 時解決。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 12:38:31 +08:00

50 lines
3.1 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# hooks/lib/path-resolve.sh — 共用:判斷一個檔案路徑「歸不歸某個 git repo 管」。
# 不是獨立掛的閘(沒進 hooks.json),給其他 PreToolUse 閘 `source` 用的函式庫。
#
# 背景(inkstone/InkStoneCo#22):sdd-guard.sh 曾經把 scratchpad 暫存檔
# `/private/tmp/.../scratchpad/foo.py`)誤判成「repo 裡的 code 變動」而擋下——
# 因為它只會「猜專案根($CLAUDE_PROJECT_DIR 或 cwd)+往上找 3-specs」,
# 猜錯或猜不到時,找不到 3-specs 就一律當「找不到 SDD」擋下,連「這條路徑根本不在
# 任何 repo 裡、SDD 這件事天生管不到它」都沒判斷過。
#
# path_in_git_worktree 提供一個不必先猜對專案根的判法:直接問 git
# 「這個路徑在不在某個 repo 的工作樹裡」。不必窮舉暫存區的路徑關鍵字(/tmp、scratchpad…),
# 任何真的不在 git repo 裡的路徑,一律視同「這是暫存/非受管檔案」。
#
# 同一個 `${CLAUDE_PROJECT_DIR:-$(pwd)}` 猜根目錄寫法,實測(2026-08-20)還出現在:
# component-guard.sh、factory-idle-guard.sh、github-contact-guard.sh、
# history-first-guard.sh、main-and-prod-push-guard.sh、no-ticket-no-dispatch.sh、
# not-my-branch-guard.sh、release-tag-guard.sh、skill-deploy-drift-guard.sh、
# stage-before-prod-guard.sh、unpushed-police.sh、wiki-first-police.sh。
# 另有 empty-handed-stop-guard.sh、issue-status-autoflip.sh 直接寫 `$CLAUDE_PROJECT_DIR`
# (無 `:-` fallback)——
# claim-verify-police.shsubagent-claim-worksheet.sh 已於 ISEP#60 整組移除,
# 它們守的東西改由 Gitea 原生三格承接,見 ISEP#59PR #58
# 這批在該變數未設時行為又不一樣,同一個病的另一種長相。
# 這些全部沒有本檔「先確認到底在不在 repo 裡」的判斷;本檔先在 sdd-guard.sh 落地,
# 其餘要不要跟進、要不要改用這支共用函式,另案處理,不在本票(#22)範圍內一次改完。
#
# 用法:
# source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/path-resolve.sh"
# if ! path_in_git_worktree "$FILE_PATH"; then
# # 不在任何 git repo 裡 ⇒ 這支閘通常管不到,多半該放行
# fi
# path_in_git_worktree <path>
# 回傳 0=這個路徑落在某個 git 工作樹裡;1=不在任何 git repo 裡(含路徑本身不存在的情況)。
# 做法:從路徑的目錄部分開始,往上找到「第一個真的存在的祖先目錄」,
# 對那個目錄問 `git rev-parse --is-inside-work-tree`。
# 為什麼要往上找存在的祖先,不能直接對 dirname 問:
# 要在 repo 裡建一個還沒建立的子目錄下的新檔案時,dirname 也不存在,
# 若不往上找,`git -C <不存在的目錄>` 會直接失敗 ⇒ 誤判成「不在 repo 裡」
# ⇒ 放行了本來該擋的東西(fail-open 的洞,不是這支函式該製造的)。
path_in_git_worktree() {
local p="$1" d
d=$(dirname -- "$p")
while [ ! -d "$d" ] && [ "$d" != "/" ]; do
d=$(dirname -- "$d")
done
[ -d "$d" ] || return 1
git -C "$d" rev-parse --is-inside-work-tree >/dev/null 2>&1
}