770a0ee824
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>
50 lines
3.1 KiB
Bash
50 lines
3.1 KiB
Bash
# 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.sh/subagent-claim-worksheet.sh 已於 ISEP#60 整組移除,
|
||
# 它們守的東西改由 Gitea 原生三格承接,見 ISEP#59/PR #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
|
||
}
|