Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aac6498850 | |||
| 5342917f2b |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "isep",
|
"name": "isep",
|
||||||
"description": "InkStone Environment Plugin —— leo 的 Claude Code 環境唯一真相源:60 支機械閘(82 條註冊,白話盤點見 docs/hooks-inventory.md)、7 支 slash command、2 支 skill、7 位有名字的工人(agents/,見 docs/governance/worker-roster.md)、48 支腳本,外加治理規範與標籤真相源。本機與雲端裝同一份,沒有子集。",
|
"description": "InkStone Environment Plugin —— leo 的 Claude Code 環境唯一真相源:60 支機械閘(82 條註冊,白話盤點見 docs/hooks-inventory.md)、7 支 slash command、2 支 skill、7 位有名字的工人(agents/,見 docs/governance/worker-roster.md)、48 支腳本,外加治理規範與標籤真相源。本機與雲端裝同一份,沒有子集。",
|
||||||
"version": "0.16.0",
|
"version": "0.16.1",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"inkstone",
|
"inkstone",
|
||||||
"guardrails",
|
"guardrails",
|
||||||
|
|||||||
+8
-1
@@ -97,11 +97,18 @@ def names(directory=None):
|
|||||||
|
|
||||||
|
|
||||||
def find(name, directory=None):
|
def find(name, directory=None):
|
||||||
|
# 🔴 subagent_type 在 plugin 裡帶前綴:Claude Code 給的是 "isep:isep-hand",
|
||||||
|
# 而 agents/*.md 的 frontmatter name 是 "isep-hand"。原本用完全相等比對
|
||||||
|
# ⇒ 真實的派工一律認不出來,而名單裡的名字工具又不收 ⇒ 兩種寫法都派不出去。
|
||||||
|
# 2026-08-28 v0.16.0 上線後實撞:整個環境派不出任何工,只能蓋 solo 戳記自己修。
|
||||||
|
# 測試沒抓到是因為 24 條全部餵手寫 payload,沒有一條用真實的 subagent_type 形狀。
|
||||||
n = (name or "").strip()
|
n = (name or "").strip()
|
||||||
if not n:
|
if not n:
|
||||||
return None
|
return None
|
||||||
|
# 允許 "<plugin>:<name>";冒號後面那半才是名單上的名字
|
||||||
|
bare = n.rsplit(":", 1)[-1].strip() if ":" in n else n
|
||||||
for w in load(directory):
|
for w in load(directory):
|
||||||
if w["name"] == n:
|
if w["name"] == n or w["name"] == bare:
|
||||||
return w
|
return w
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -176,6 +176,30 @@ else
|
|||||||
printf ' ❌ ⑱ 身份欄沒有吃下工人名字(或把原本的三個角色弄壞了)\n'; FAIL=$((FAIL+1))
|
printf ' ❌ ⑱ 身份欄沒有吃下工人名字(或把原本的三個角色弄壞了)\n'; FAIL=$((FAIL+1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "── 驗收 4:真實的 subagent_type 形狀(2026-08-28 實撞的死鎖)──────"
|
||||||
|
|
||||||
|
N=$((N+1))
|
||||||
|
if python3 - "$ROOT" <<'PY' 2>/dev/null
|
||||||
|
import sys, os
|
||||||
|
sys.path.insert(0, os.path.join(sys.argv[1], "hooks", "lib"))
|
||||||
|
import roster
|
||||||
|
d = os.path.join(sys.argv[1], "agents")
|
||||||
|
# Claude Code 給 plugin agent 的真實值帶前綴,agents/*.md 的 name 沒有
|
||||||
|
assert roster.find("isep:isep-hand", d), "帶 plugin 前綴的真實 subagent_type 認不出來"
|
||||||
|
assert roster.find("isep:scout", d), "帶前綴的 scout 認不出來"
|
||||||
|
# 名單上的裸名字仍然要收(人會照 roster list 直接貼)
|
||||||
|
assert roster.find("isep-hand", d), "裸名字被弄壞了"
|
||||||
|
# 剝前綴不能變成放行任何東西
|
||||||
|
assert roster.find("isep:nobody", d) is None, "不存在的名字被放行了"
|
||||||
|
assert roster.find("nobody", d) is None, "不存在的裸名字被放行了"
|
||||||
|
assert roster.find("", d) is None, "空字串被放行了"
|
||||||
|
PY
|
||||||
|
then
|
||||||
|
printf ' ✅ ⑲ 帶 plugin 前綴的真實 subagent_type 認得出來,不存在的仍然擋\n'; PASS=$((PASS+1))
|
||||||
|
else
|
||||||
|
printf ' ❌ ⑲ 真實的 subagent_type(isep:isep-hand)認不出來——就是這個造成 8/28 的死鎖\n'; FAIL=$((FAIL+1))
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
printf '結果:%s 通過 / %s 失敗(共 %s 條)\n' "$PASS" "$FAIL" "$N"
|
printf '結果:%s 通過 / %s 失敗(共 %s 條)\n' "$PASS" "$FAIL" "$N"
|
||||||
[ "$FAIL" -eq 0 ] || exit 1
|
[ "$FAIL" -eq 0 ] || exit 1
|
||||||
|
|||||||
+3
-1
@@ -41,6 +41,7 @@ usage() {
|
|||||||
solo <session_id> 這件事真的該自己做(subagent-first-guard)——回覆裡要寫理由
|
solo <session_id> 這件事真的該自己做(subagent-first-guard)——回覆裡要寫理由
|
||||||
dispatch <session_id> 派工單真的有例外(dispatch-format-guard)
|
dispatch <session_id> 派工單真的有例外(dispatch-format-guard)
|
||||||
ask <session_id> 這題真的是人閘(ask-user-question-guard)
|
ask <session_id> 這題真的是人閘(ask-user-question-guard)
|
||||||
|
roster <session_id> 派工真的是名單的例外(roster-guard)
|
||||||
kbdb-down KBDB 真的連不上(history-first-guard)——回覆裡要說明
|
kbdb-down KBDB 真的連不上(history-first-guard)——回覆裡要說明
|
||||||
|
|
||||||
--list 列出目前存在的戳記
|
--list 列出目前存在的戳記
|
||||||
@@ -93,7 +94,7 @@ case "$GATE" in
|
|||||||
kbdb-down)
|
kbdb-down)
|
||||||
stamp /tmp/.kbdb-down "KBDB 連不上而放行——**回覆裡要說明**,這是留痕不是豁免" ;;
|
stamp /tmp/.kbdb-down "KBDB 連不上而放行——**回覆裡要說明**,這是留痕不是豁免" ;;
|
||||||
|
|
||||||
solo|dispatch|ask)
|
solo|dispatch|ask|roster)
|
||||||
SID="${1:-${CLAUDE_SESSION_ID:-}}"
|
SID="${1:-${CLAUDE_SESSION_ID:-}}"
|
||||||
if [ -z "$SID" ]; then
|
if [ -z "$SID" ]; then
|
||||||
printf '❌ %s 要綁 session id(閘用它認「是不是同一個 session」)。\n' "$GATE" >&2
|
printf '❌ %s 要綁 session id(閘用它認「是不是同一個 session」)。\n' "$GATE" >&2
|
||||||
@@ -104,6 +105,7 @@ case "$GATE" in
|
|||||||
solo) stamp "/tmp/.solo-ok-$SID" "這件事自己做——**回覆裡要寫理由**" ;;
|
solo) stamp "/tmp/.solo-ok-$SID" "這件事自己做——**回覆裡要寫理由**" ;;
|
||||||
dispatch) stamp "/tmp/.dispatch-ok-$SID" "這張派工單的例外,放行一次" ;;
|
dispatch) stamp "/tmp/.dispatch-ok-$SID" "這張派工單的例外,放行一次" ;;
|
||||||
ask) stamp "/tmp/.ask-ok-$SID" "這題確認是人閘,放行一次" ;;
|
ask) stamp "/tmp/.ask-ok-$SID" "這題確認是人閘,放行一次" ;;
|
||||||
|
roster) stamp "/tmp/.roster-ok-$SID" "這次派工確認是名單的例外,放行一次" ;;
|
||||||
esac ;;
|
esac ;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
|
|||||||
Reference in New Issue
Block a user