sdd-guard 退役:讓「取消 Active SDD」這個裁決真的執行得下去(inkstone/ISEP#91)

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
This commit is contained in:
Claude
2026-08-31 00:56:37 +00:00
parent 4b91cd5d48
commit c7af690c2b
12 changed files with 317 additions and 376 deletions
+32
View File
@@ -515,6 +515,38 @@ D 群同時釘住反面:認不出來(`cd $VAR`、`cd -`、cd 到不是 repo
- ① 紅 ⇒ 連總管在自己的目錄裡切分支都被擋。那不是嚴格,那是把共用目錄的主人趕出去
- ㉞㉟ 紅 ⇒ `prune` 做錯了。㉞是沒清掉說謊的登記;**㉟是把還在的 worktree 也弄掉了,那是災難**
### A25 — `sdd-guard` 退役了,而且退乾淨了:8 條
```
bash hooks/tests/sdd-guard-retired.test.sh
```
**該看到**`通過 8 失敗 0`。離線,自己開兩顆假 git repo,跑完自己清。
**它在守什麼**`inkstone/ISEP#91`):leo 2026-08-16 在 `inkstone/InkStoneCo#40` 裁定
**取消 Active SDD**——任務狀態搬到 Gitea 管,SDD 只記「起初的樣子」。
`sdd-guard.sh`**fail-closed** 的:`status: active` 不是恰好 1 份就擋(**0 份也擋**),
路徑所在的 repo 沒有 `3-specs` 也擋。⇒ **照裁決把 active SDD 拿掉,會當場鎖死所有 code 寫入**
這就是那個裁決躺了 11 天沒人敢執行的真正原因。
🔴 **這支測的不是「檔案刪掉了沒有」,是「那個擋還會不會發生」**
它把「裁決執行完之後的世界」(沒有 `3-specs` 的 repo、有兩份 `status: active` 的 repo
丟給 `hooks.json` 上**整組** `Write|Edit|MultiEdit` 的閘——清單是當場從 `hooks.json` 讀的,
不寫死——**不准有任何一支用 SDD/3-specs 當理由擋下來**。
⇒ 日後有人換個檔名把同一個形狀種回來,這支照樣紅。
**失敗**
- ②那四條任一紅 ⇒ 裁決又被種回去了。**最要看的是最後一條**(ISEP 自己的 `hooks/lib/*.py`):
ISEP 這個 repo 本身就沒有 `3-specs`,退役前那一格是紅的——它是這件事的活體證據
- ③紅 ⇒ 條文回來了。有人在 `commands/``agents/``skills/``hooks/`
又寫了一次「只准一份 active SDD」,而**條文會被載入,載入就會被照做**
- ①的第三條(`hooks.json` 仍是合法 JSON)紅 ⇒ 合併把檔案弄壞了;
但**它只證明語法沒壞、不證明閘還在**——閘在不在要另外跑 README 那道逐支點名
📌 **這支只管 ISEP 這一半。** 裁決的另外兩件在 `inkstone/InkStoneCo`
拿掉那份 active SDD `CLAUDE.md` 的「單一活性鐵律」段,以及
`system-dev/docs/` 底下的任務 checkbox 分診(掛 `inkstone/InkStoneCo#49`)。
🔴 **順序不可顛倒**:要等這一版 ISEP 出去、兩邊 `/plugin update` 之後,
那半才動得——先拿掉 active SDD 就會鎖死。
### A5 — 開票前的搜尋是跨 repo 的
```
python3 scripts/ticket where 標籤 模組化