c7af690c2b
leo 2026-08-16 在 inkstone/InkStoneCo#40 → comment 2942 裁定「取消 Active SDD」, 11 天沒被執行。原因不是有人偷懶,是**執行它的第一步會鎖死自己**: sdd-guard.sh 是 fail-closed 的 · 動 code 檔時 status: active 不是恰好 1 份 → 擋(0 份也擋) · 路徑所在的 repo 沒有 3-specs → 也擋 ⇒ 照裁決把最後那份 active 拿掉 → 變 0 份 → 任何人動任何 .ts/.py/.go 全被擋。 而 ISEP 這個 repo 自己就沒有 3-specs——本票開工第一件事實測到: $ echo '{"tool_name":"Edit","tool_input":{"file_path":".../hooks/lib/dispatch_parse.py"}}' \ | bash hooks/sdd-guard.sh 🚫 SDD 協議攔截:… 找不到任何 SDD exit 2 **它一直在誤攔 ISEP 自己,只是沒人回報。** ── 這一版做了什麼 ──────────────────────────────────── · hooks/sdd-guard.sh 刪除,hooks.json 取消註冊(85 → 84 條,只少這一條) · commands/sdd-check.md 改寫:SDD 只記「起初的樣子」,任務本體在 Gitea 票; 找不到 SDD 不再是停下來的理由,找不到票才是 · agents/inkstoneco-hand.md 拿掉「任何時刻只允許一份 status: active」那條紅線 · hooks/lib/path-resolve.sh 只加註解:它的唯一 caller 走了,但別順手刪 (#22 學到的東西住在裡面,十幾支閘還在用它要修的那個寫法) ── 迴歸測試:測的不是「檔案刪了沒」,是「那個擋還會不會發生」── hooks/tests/sdd-guard-retired.test.sh(通過 8/失敗 0,離線): 把「裁決執行完之後的世界」(沒有 3-specs 的 repo、兩份 status: active 的 repo) 丟給 hooks.json 上**整組** Write|Edit|MultiEdit 的閘——清單當場從 hooks.json 讀、 不寫死——不准有任何一支用 SDD/3-specs 當理由擋下來。 ⇒ 日後有人換個檔名把同一個形狀種回來,這支照樣紅。 🔴 判準刻意不是「一支閘都不准擋」:同組還住著跟 SDD 無關、且看 session 狀態 決定擋不擋的閘(history-first/subagent-first)。把它們算失敗,這支測試會在別人 改別的東西時無故變紅,紅久了就沒人看——誤攔比漏擋更該修,對測試一樣成立。 **紅的證明**:把 sdd-guard 暫時復原(檔案+註冊)重跑 → 通過 1/失敗 7, 四條行為格全部指名 sdd-guard.sh。已還原。 ── 自己跑過的 ────────────────────────────────────── · hooks/tests/sdd-guard-retired.test.sh 通過 8/失敗 0 · 逐支點名 hooks.json(README「裝什麼」那道指令) 84 條,對 main 做集合差: 少了 sdd-guard.sh × 1,多出 0 支,其餘一支不差 · 盤點數字全部在這棵樹上實數,不是加減推: ls hooks/*.sh|wc -l = 61(原 62) grep -c '"command":' hooks/hooks.json = 84(原 85) agents 7/commands 7/skills 2/scripts 48(皆未變動) · 盤點表對帳三格(hooks-inventory 自己寫死的那三道):三格皆無輸出 · scripts/check-version-consistency.sh ✅ 0.16.2 一致 · claude plugin validate . ✅ Validation passed · hooks/tests/ 全部離線測試 24 支重跑:本次改動 0 退步 (dispatch-format-guard 40/52、prod-write-guard 18/19-fail、 stage-before-prod-guard 9/7-fail、另 3 支需帶參數/建不起沙盒—— **六支在 gitea/main 上逐支重跑結果一模一樣,是既有狀態不是本次造成**) ── 沒做、也不該由這張票做的 ───────────────────────── · inkstone/InkStoneCo 那半(拿掉 active SDD + 刪 CLAUDE.md「單一活性鐵律」段) ——那是 inkstoneco-hand 的 repo;而且順序上本來就要等這一版出去、 兩邊 /plugin update 之後才動得,先拿掉就鎖死 · checkbox 分診(掛 inkstone/InkStoneCo#49,票上明寫不要另開票) · 版本號:待總管定版 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ZBu4Sa1cGntKFRBYNZ6xs
469 lines
13 KiB
JSON
469 lines
13 KiB
JSON
{
|
|
"description": "InkStone Environment Plugin (ISEP) —— leo 的 Claude Code 環境唯一真相源:所有機械閘、slash command、skill、腳本。本機與雲端裝同一份,總管自己也吃它(dogfood)。",
|
|
"hooks": {
|
|
"PreToolUse": [
|
|
{
|
|
"matcher": "Bash",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/github-contact-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/kbdb-api-wall-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/stage-before-prod-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/main-and-prod-push-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/prod-write-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/not-my-branch-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/leo21c-write-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/release-tag-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/ticket-api-bypass-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/comment-carries-task-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/milestone-due-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/milestone-account-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/reply-identity-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/search-is-not-proof-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/diagnosis-evidence-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/dispatch-format-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/line-needs-own-worktree.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": ".*(arcrun_push_workflow|arcrun_delete_workflow|arcrun_recipe_push|arcrun_recipe_delete|arcrun_create_tag|arcrun_delete_tag|arcrun_tag_resource|arcrun_untag_resource|kbdb_create_record|kbdb_create_template).*",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/prod-write-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Write|Edit|MultiEdit",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/guard-cross-project.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/wiki-secret-scan.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/component-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/credential-only-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/arcrun-intent-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/kbdb-api-wall-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/subagent-first-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/mistake-needs-ticket-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/pending-changes-retired.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/wiki-size-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Grep|Glob|Read|Bash",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/wiki-first-search.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Task",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/subagent-wiki-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/kbdb-api-wall-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/micromanage-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/irreversible-dispatch-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/no-ticket-no-dispatch.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/dispatch-format-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/roster-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/mainline-focus-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/search-is-not-proof-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/parallel-lines-cap-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": ".*arcrun_(push_workflow|validate_yaml).*",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/arcrun-intent-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Edit|MultiEdit",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/history-first-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Agent",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/micromanage-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/irreversible-dispatch-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/no-ticket-no-dispatch.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/dispatch-format-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/roster-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/mainline-focus-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/search-is-not-proof-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/parallel-lines-cap-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "SendMessage|.*Claude_Code_Remote__(send_message|create_session|create_trigger|update_trigger|fire_trigger|send_later).*",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/dispatch-format-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "AskUserQuestion",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/ask-user-question-guard.sh"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"SessionStart": [
|
|
{
|
|
"matcher": "startup|resume|clear",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/session-start-recall.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/skill-deploy-drift-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/isep-presence-beacon.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/countdown-milestone-refresh.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "\"${CLAUDE_PLUGIN_ROOT}\"/scripts/mainline refresh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/overdue-nag-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/wiki-size-guard.sh"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"Stop": [
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/empty-handed-stop-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/worklist-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/factory-idle-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/mainline-idle-guard.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/pr-verdict-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/browser-verify-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/self-drive-police.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/self-drive-judge.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/delivery-police.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/wiki-first-police.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/unpushed-police.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/countdown-guard.sh"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"SubagentStop": [
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/worklist-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/self-drive-police.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/self-drive-judge.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/delivery-police.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/wiki-first-police.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/unpushed-police.sh"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"PostToolUse": [
|
|
{
|
|
"matcher": ".*kbdb_(search|get_map|query|graph_neighbors).*",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/kbdb-asked-stamp.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": ".*kbdb_(search|get_record|query|graph_neighbors|get_map).*",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/kbdb-evidence-stamp.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "Agent|Task",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/subagent-first-stamp.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/investigate-first-stamp.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/issue-status-autoflip.sh"
|
|
},
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/baton-handback-guard.sh"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": "SendMessage",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/investigate-first-stamp.sh"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"UserPromptSubmit": [
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/countdown-guard.sh"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|