ISEP 0.1.0:環境設定收成一個 plugin,本機與雲端共用一份

leo 2026-08-20:「同一個 plugin 你用,薄殼也用,保證兩邊同步」
              「我要你幫雲端做薄殼,永遠都有問題,你要做的就是這組設定
                你自己可以 dogfooding」

搬進來:41 支 hook(51 條註冊)/7 支 command/2 支 skill/23 支腳本。
不搬 .env、wiki、docs——那些是知識不是環境。

51 條 hook 路徑全部從 $CLAUDE_PROJECT_DIR/.claude/hooks/ 改成 ${CLAUDE_PLUGIN_ROOT}/hooks/,
零漏網。那正是薄殼一直壞掉的根:雲端 cwd 不是真身,寫死路徑就斷。

尚未驗證:Claude Code 能不能從私有 Gitea repo 裝 marketplace(要憑證)。
下一步就是在本機實際裝一次,通了才動雲端 bootstrap.sh。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 11:41:46 +08:00
commit c2638668e3
85 changed files with 11879 additions and 0 deletions
+93
View File
@@ -0,0 +1,93 @@
#!/usr/bin/env bash
# guard-cross-project.sh — 頂層總管 guardrail
#
# 職責邊界(InkStoneCo CLAUDE.md D9):頂層只做「跨專案的整理與安排」(總管),
# 不進單一子 repo 做實作。子 repo 的程式碼/設定實作 = 在那個子 repo 的專案裡執行,
# 頂層只負責「交棒」(寫 docs/HANDOFF-*.md)並記錄安排。
#
# 本 hook 攔 PreToolUse 的 Write/Edit/MultiEdit
# - 目標路徑落在子 repo 目錄(matrix/ polaris/ products/ _archive/)內
# - 且不是 .md 文件
# → 擋下(exit 2),提示改用交棒(寫 HANDOFF)。
# 放行:頂層自己的檔(CLAUDE.md / .claude/ / docs/ / MEMORY.md…)、
# 以及子 repo 內的 .md(交棒 HANDOFF / 筆記 / 文件——leo 2026-06-15 拍板放行所有 .md)。
#
# 誠實限制(arcrun mindset §7):本 hook 擋的是「路徑語法層」——能擋「寫程式碼進子 repo」,
# 擋不了「把實作偽裝成 .md」或「該交棒卻判斷成可直改」這種語意層越界。它是底線,不是萬能。
input="$(cat)"
# 取 file_pathWrite/Edit/MultiEdit 都用 tool_input.file_path
file_path="$(printf '%s' "$input" | python3 -c '
import sys, json
try:
d = json.load(sys.stdin)
print(d.get("tool_input", {}).get("file_path", ""))
except Exception:
print("")
' 2>/dev/null || true)"
# 拿不到路徑就放行(不誤擋;hook 不該因解析失敗卡死正常操作)
[ -z "$file_path" ] && exit 0
# 頂層 repo 根(hook 檔位於 <root>/.claude/hooks/
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# 轉成相對 repo_root 的路徑(file_path 可能是絕對或相對)
case "$file_path" in
/*) rel="${file_path#"$repo_root"/}" ;; # 絕對路徑 → 去掉 repo_root 前綴
*) rel="$file_path" ;; # 相對路徑 → 假定相對 repo_root
esac
# 不在子 repo 目錄內 → 放行(頂層自己的檔)
case "$rel" in
matrix/*|polaris/*|products/*|_archive/*) : ;; # 落在子 repo,繼續判斷
*) exit 0 ;;
esac
# 自動派工放行(2026-06-28 leo 拍板上線,實測通過):
# 子 repo 的 subagent 可直接寫該 repo code(繞 D9)——因 subagent 心智已是該 repo
# A/B 實驗證 ≈ claude -p),讓「心智是該 repo 的小弟寫該 repo」符合 context 隔離。
# 雙重夾:① CHILD_SESSION=1harness 內建 subagent 標籤,總管主 session 無此標籤仍被擋)
# ② 路徑在下面白名單 array 內。
# 隔離保證=prompt reset(軟,靠監測)非結構級;要絕對純走 claude -p。心法見 wiki。
#
# 🔧 leo 維護:要放開一個 repo 給 subagent 自動寫 code,就在這 array 加一行路徑前綴。
# ⚠️ 加 = 放權,想清楚私人/共用(改它影響誰)再加。array 空 = 誰都不放(安全預設)。
AUTODISPATCH_ALLOW=(
"polaris/mira" # 私人環境(只影響 leo
"matrix/arcrun" # 共用框架(影響全部人,走 PR 把關)
"products/arcrun-rag" # 產品組裝 repo2026-07-13 leo 放行 G8:回覆「放行」)
)
if [ "$CLAUDE_CODE_CHILD_SESSION" = "1" ]; then
for allowed in "${AUTODISPATCH_ALLOW[@]}"; do
case "$rel" in
"$allowed"/*) echo "🤝 [guard] subagent 放行:$allowed(自動派工)" >&2; exit 0 ;;
esac
done
fi
# 在子 repo 內:.md 放行(交棒 / 文件),其餘擋
case "$rel" in
*.md|*.MD|*.markdown) exit 0 ;;
esac
# 走到這 = 寫非 .md 檔進子 repo 目錄 = 越界實作 → 擋
sub="${rel%%/*}"
cat >&2 <<EOF
❌ BLOCKED by InkStoneCo 總管 guardrail(職責邊界 D9
違反:頂層總管直接寫實作檔進子 repo($sub/)。
路徑:$rel
頂層只做「跨專案的整理與安排」,不進單一 repo 做實作。
子 repo 的程式碼 / 設定 = 在該子 repo($sub)的專案裡改,不在頂層。
正確做法:
• 要子 repo 改什麼 → 寫一份交棒文件:$sub/docs/HANDOFF-*.md.md 放行),
給判準與論證,成品由該 repo 的 CC 按它自己的 rules 產出。
• 真要由你(總管)動這個子 repo → 切換到那個子 repo 的工作脈絡再做,不在頂層越界。
參考:CLAUDE.md「職責邊界(核心原則)」+ decisions-summary D9。
EOF
exit 2