工人有名字+回覆也是派工+未經調查不寫診斷(inkstone/ISEP#86/#87/#88)
三張票同一族(誰在派、派給誰、派的內容住哪裡),做在同一條分支: #86 工人名單:agents/ 七位有名字的工人+scripts/roster+hooks/roster-guard.sh 派工用 Task 的 subagent_type 指名,派工單格式一個字都沒改; 指對名字就把那位的檔案原文注入(你是誰/先讀什麼/你的紅線)。 【身份】欄同時吃得下工人名字(原本三個角色照舊)。 #87 未經調查不寫診斷:hooks/diagnosis-evidence-guard.sh + investigate-first-stamp.sh 三個結構訊號(派過人查沒/有沒有走得過去的出處/有沒有份量), 一個關鍵字比對都沒有;轉述有出處不會被誤擋。 #88 回覆也是派工:不另造閘,把攔截點加掛上去。 hooks/lib/dispatch_parse.py 的 tool_channel() 一次列全所有通往 subagent 的路 (SendMessage/雲端 session・trigger/claude -p);擋下來時把那段內容原文印出來。 subagent 往上回報(to: "main")=交件不是派工,刻意不管。 順手修掉一個真的會咬人的 flake:dispatch-format-guard 原本開四支 python 各讀一個欄位, 機器忙的時候某個欄位會靜靜變空字串(實測連跑 10 次有 1 次「豁免了卻還是被擋」)。 四個欄位改成一次讀完。 版本號待總管定(plugin.json 只更新了描述裡的數字,版本沒動)。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ZBu4Sa1cGntKFRBYNZ6xs
This commit is contained in:
+59
-4
@@ -199,11 +199,12 @@ bash hooks/tests/ask-user-question-guard.live.test.sh
|
||||
- 📌 這支會隨模型版本漂移,**是量尺不是一次性驗收**。改完判準要連跑三次都全綠才算數
|
||||
(2026-08-26 實測:第一版判準連兩次都在同一題漏擋,收緊 ③④ 定義後三次全綠)
|
||||
|
||||
### A11 — 派工單只剩票號:擋得住,也放得過,而且會注入共通規定
|
||||
### A11 — 派工單只剩票號(含**回覆那條路**):擋得住,也放得過,而且會注入共通規定
|
||||
```
|
||||
bash hooks/tests/dispatch-format-guard.test.sh
|
||||
```
|
||||
**該看到**:`19/19 通過`。**離線、不打網路、不花錢**——這支閘是純結構判斷,沒有語意判官,
|
||||
**該看到**:`52/52 通過`(`inkstone/ISEP#88` 之前是 33 條;本頁一度寫 19,那是更早的數字,
|
||||
**沒有人回頭改** —— 同一個病,只是換一欄)。**離線、不打網路、不花錢**——這支閘是純結構判斷,沒有語意判官,
|
||||
所以它不需要像 A10 那樣另開一支 live 測試量準度,**每次結果都一樣**。
|
||||
**失敗**:
|
||||
- A 群任何一條紅 ⇒ **誤攔**。合規的派工只有一行票號,擋掉它等於整台機器派不了工
|
||||
@@ -212,6 +213,58 @@ bash hooks/tests/dispatch-format-guard.test.sh
|
||||
它壞了不會有人立刻發現——派工照樣送出去,只是收工方**不知道要貼回原票**
|
||||
- ⑨ 紅 ⇒ 真跡放行了。那份測資是**真的發生過的那一次派工**(見 `hooks/tests/fixtures/README.md`)
|
||||
- ⑰ 紅 ⇒ 訊息被 shell 展開了(同 A9 ⑩b 那個病:閘照擋,但它教人怎麼解的那兩行變成空白)
|
||||
- **D 群⑲⑳㉑㉒ 紅 ⇒ `inkstone/ISEP#88` 的驗收條件沒過**:回覆一個正在跑的 subagent
|
||||
時夾帶指令沒被擋(⑲)、或擋了卻沒把那段內容原文印出來(㉑,出路是「貼上票」,
|
||||
找不到原文就得回頭自己翻)
|
||||
- **E 群㉔–㉙ 任一紅 ⇒ 有一條通往 subagent 的路又漏了**。那六條是雲端 session/trigger/
|
||||
`claude -p`——`ticket-api-bypass-guard.sh` 檔頭記過這一族的通病:「認動作的方式漏了一條路」
|
||||
- **F 群㉚–㉟ 任一紅 ⇒ 誤攔**。㉚特別重要:subagent 往上回報(`to: "main"`)是**交件**,
|
||||
擋它等於擋掉交件本身;㉟反過來,子 session 自己往下派工時規矩要照樣管它,不然是逃逸艙口
|
||||
|
||||
### A16 — 工人有名字:指名派工、沒有這個人、注入它的檔案:24 條
|
||||
```
|
||||
bash hooks/tests/roster-guard.test.sh
|
||||
```
|
||||
**該看到**:`24 通過 / 0 失敗`。**離線、不打網路、不花錢**——純結構判斷(名字在不在名單裡),
|
||||
沒有語意判官,每次結果一樣。
|
||||
|
||||
**它在守什麼**(`inkstone/ISEP#86`):「身為派工的人,我要工人有名字,
|
||||
我才知道票上這件事到底是誰做的。」開票當日實查:`/root/.claude/agents/` 不存在,
|
||||
派工派給的是**沒有名字的臨時工**——票上只看得到「有個 agent 做了」。
|
||||
|
||||
**失敗**:
|
||||
- ①②③ 紅 ⇒ 驗收 1 沒過:`scripts/roster` 列不出名單、或列了卻看不出各自管什麼
|
||||
- ④⑤ 任一紅 ⇒ **誤攔**,名單上的人被擋掉 = 整台機器派不了工。這比漏擋嚴重
|
||||
- ⑥⑦⑧ 紅 ⇒ 驗收 4 沒過:派一個不存在的名字時講不出「沒有這個人」
|
||||
- ⑨ 紅 ⇒ 擋了卻沒印名單,人不知道有誰可以派(閘的訊息要講得出出路)
|
||||
- ⑬ 紅 ⇒ 名單讀不到時**沒有 fail-open**。一份讀不到的名單不該讓整台機器停擺
|
||||
- ⑯⑰ 紅 ⇒ 注入壞了。那是「你是誰/先讀什麼/你的紅線」唯一的送達方式——
|
||||
它壞了不會有人立刻發現,派工照樣送出去,只是工人不知道自己是誰
|
||||
- ⑱ 紅 ⇒ 驗收 3 沒過:票上的【身份】欄吃不下工人名字(或把原本三個角色弄壞了)
|
||||
|
||||
### A17 — 未經調查不寫診斷:26 條
|
||||
```
|
||||
bash hooks/tests/diagnosis-evidence-guard.test.sh
|
||||
```
|
||||
**該看到**:`26 通過 / 0 失敗`。**全程離線**:不打 Gitea、不開任何測試票,
|
||||
戳記走 `ISEP_STAMP_DIR`(不碰 `/tmp` 的正式戳記)。
|
||||
|
||||
**它在守什麼**(`inkstone/ISEP#87`):「先派人查 → 拿到查的結果 → 才可以寫診斷。」
|
||||
未經調查的診斷寫在票上會長得像事實,**工人會照著它去驗證,而不是去查**。
|
||||
|
||||
**失敗**:
|
||||
- ①–⑦ 任一紅 ⇒ 驗收 1 沒過。⑥⑦特別看:那是**側門**(直接打 Gitea API),
|
||||
只封正門等於沒封
|
||||
- ② 紅 ⇒ 驗收 3 沒過:訊息說不出「你還沒派人查這件事」,變成籠統的「格式不對」
|
||||
- ⑧⑨ 紅 ⇒ 驗收 2 沒過(派過人查卻還在擋),或戳記從「按票分」滑成「按 session 分」
|
||||
——後者等於派過一次就永久解鎖
|
||||
- **⑩–⑫ 任一紅 ⇒ 驗收 4 沒過,這是誤攔**:轉述別人查到的東西(有出處)被擋,
|
||||
那會逼人把真的有出處的話也吞回去
|
||||
- ⑬ 紅 ⇒ 判準從結構滑回措辭。那一條**故意用一段連「根因/因為/應該是」都沒有的內容**,
|
||||
它一旦放行,代表閘開始靠關鍵字判斷了(leo 2026-08-17 已證偽那條路)
|
||||
- ⑭–⑲ 任一紅 ⇒ 誤攔(短回覆、唯讀、搜尋、關票被擋)
|
||||
- ㉑ 紅 ⇒ 鬼打牆:同一張票擋不只一次,人會學會忽略它
|
||||
- ㉓㉔ 紅 ⇒ payload 壞掉時擋住了。這支是 PreToolUse,fail-closed 會讓人做不了事
|
||||
|
||||
### A12 — 票上的每一則留言都認得出是誰寫的(兩道門)
|
||||
```
|
||||
@@ -366,8 +419,10 @@ B2(信標那行)/B3(setup 輸出)/B4(閘的訊息)三個畫面
|
||||
| A6 標籤對齊+冪等 | 總管 | ✅ 14 repo,第二次 0/0 |
|
||||
| **A9 人閘警察管路** | 總管 | ✅ 14/14(2026-08-26) |
|
||||
| **A10 人閘警察準度** | 總管 | ✅ 9/9,連跑三次(2026-08-26),A 群誤攔 0 |
|
||||
| **A11 派工單只剩票號** | 總管 | ✅ 19/19(2026-08-27) |
|
||||
| **A12 留言身份欄(兩道門)** | 總管 | ✅ 11/11(2026-08-27) |
|
||||
| **A11 派工單只剩票號+回覆那條路(ISEP#88)** | 總管 | ✅ 52/52(2026-08-28) |
|
||||
| **A12 留言身份欄(兩道門)** | 總管 | ✅ 11/11(2026-08-28 複跑) |
|
||||
| **A16 工人有名字(ISEP#86)** | 總管 | ✅ 24/24(2026-08-28) |
|
||||
| **A17 未經調查不寫診斷(ISEP#87)** | 總管 | ✅ 26/26(2026-08-28) |
|
||||
| A7 plugin 裝得起來 | 總管 | ✅ |
|
||||
| **A8 新 session 閘會觸發** | 總管 | 見本版 release note |
|
||||
| **B1–B5 雲端** | **leo** | 還沒跑(機器碰不到 Cloud environment) |
|
||||
|
||||
@@ -44,6 +44,58 @@
|
||||
|
||||
---
|
||||
|
||||
## 1.5 派給誰:從名單裡挑一個**有名字的工人**(inkstone/ISEP#86)
|
||||
|
||||
派工單只有票號,那「這是誰的活」寫在哪?——**不寫在派工單裡,寫在 `subagent_type`。**
|
||||
|
||||
```
|
||||
Task(subagent_type="isep-hand", prompt="【工單】inkstone/ISEP#86")
|
||||
▲ 名單上的名字 ▲ 派工單仍然只有這一行
|
||||
```
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 名單在哪 | `agents/`,一個檔案一位工人(規約:`docs/governance/worker-roster.md`) |
|
||||
| 怎麼看 | `python3 scripts/roster list`/`show <名字>`/`which <owner/repo>` |
|
||||
| 機械閘 | `hooks/roster-guard.sh`——沒指名或名單上沒有這個名字就擋,並印出整份名單 |
|
||||
|
||||
**為什麼「你是誰」不能收進 §2 的共通規定**:共通規定是「每次都一樣」的東西,
|
||||
而「你是誰、你該讀哪些、你的紅線」**每個工人都不一樣**。所以它有自己的家(名單),
|
||||
由 `roster-guard.sh` 在派工當下注入——同樣不必有人記得寫。
|
||||
|
||||
---
|
||||
|
||||
## 1.6 回覆也是派工:**同一套規矩,同一支閘**(inkstone/ISEP#88)
|
||||
|
||||
派工單被壓成只剩票號之後,**回覆一個正在跑的 subagent 這條路沒有被管到**——
|
||||
那支閘掛在 `PreToolUse(Task|Agent)`,而回覆走的是別的工具,根本不經過那個攔截點。
|
||||
|
||||
實況(2026-08-27):第一次派工乾乾淨淨只有票號,中途回覆時又把一長串修改要求丟過去。
|
||||
**那些話票上一個字都沒有**,那條線被停掉或換人接手就消失。
|
||||
|
||||
⇒ **不另造一支平行的閘**:同一支 `dispatch-format-guard.sh`、同一個判斷函式,
|
||||
只是把所有通往 subagent 的路一次列全(表在 `hooks/lib/dispatch_parse.py` 的 `tool_channel()`):
|
||||
|
||||
| 路 | 裝話的欄位 |
|
||||
|---|---|
|
||||
| `Task`/`Agent` | `prompt` |
|
||||
| `SendMessage` | `message` |
|
||||
| 雲端 `create_session` | `prompt` |
|
||||
| 雲端 `send_message` | `text`/`message` |
|
||||
| 雲端 `create_trigger`/`update_trigger` | `prompt` |
|
||||
| 雲端 `fire_trigger` | `text` |
|
||||
| 雲端 `send_later` | `message` |
|
||||
| Bash `claude -p <prompt>` | 指令裡那段 prompt |
|
||||
|
||||
🔴 **新增一條路要加在那張表裡,不要再開一支閘。**
|
||||
「認動作的方式漏了一條路」是這一族的通病——`ticket-api-bypass-guard.sh` 的檔頭
|
||||
記過同一課(第一版只認大寫裸字 `POST`,`requests.post()` 與隱式 POST 全部漏掉)。
|
||||
|
||||
**刻意不管的方向**:subagent 往上回報(`SendMessage to: "main"`)=**交件不是派工**。
|
||||
擋它等於擋掉交件本身。
|
||||
|
||||
---
|
||||
|
||||
## 2. 共通規定(每一次派工由機器自動注入給收工方)
|
||||
|
||||
<!-- INJECT:BEGIN 這段之間的內容會被 dispatch-format-guard.sh 原文注入,改這裡=改所有派工 -->
|
||||
@@ -55,8 +107,10 @@
|
||||
3. **交件=貼回那張票**(`scripts/ticket say <owner/repo#N> -F <檔>`),
|
||||
不是只在對話裡回報。回覆第一行必須是身份欄,見下。
|
||||
4. **回覆第一行一律是**:
|
||||
`【身份】subagent/<owner/repo>/<你的分支>`
|
||||
角色三選一:`總管`/`subagent`/`leo`。
|
||||
`【身份】<你的名字>/<owner/repo>/<你的分支>`
|
||||
名字用機器注入給你的那個(`isep-hand`、`scout`…);沒有名字時才退回
|
||||
`總管`/`subagent`/`leo` 三選一。**票上要看得出是哪個工人做的**,
|
||||
而三條線並行時「subagent」這個字回答不了「是誰」。
|
||||
5. **不准 push 到 `main`/`master`**,也不准部署 prod。做在自己的分支上,交回分支名。
|
||||
6. **Gitea 的 org 是 `inkstone`**(不是 `Leo`);`gh` 打不到 Gitea;
|
||||
標籤是 `s/*` 不是 `status/*`。
|
||||
@@ -80,9 +134,13 @@
|
||||
【身份】subagent/inkstone/ISEP/feat/ticket-carries-the-task
|
||||
```
|
||||
|
||||
- 角色是**三選一的允許清單**:`總管`/`subagent`/`leo`
|
||||
- 角色是**允許清單**:`總管`/`subagent`/`leo`,**再加上 `agents/` 名單上的每一個工人名字**
|
||||
(`isep-hand`/`arcrun-hand`/`scout`…,inkstone/ISEP#86)。清單以外的名字一律擋。
|
||||
- 第二格是你動的 repo,第三格是分支(沒有就寫 `-`)
|
||||
|
||||
🔴 **有名字就用名字。** 三條線並行時三則「【身份】subagent/…」長得一模一樣,
|
||||
等於沒有身份——這正是 ISEP#86 要解的那件事。
|
||||
|
||||
### 為什麼
|
||||
|
||||
2026-08-27 實害:多條線並行時票上的留言看不出身份,
|
||||
@@ -106,8 +164,30 @@
|
||||
## 4. 這份規範自己怎麼被驗
|
||||
|
||||
```
|
||||
bash hooks/tests/dispatch-format-guard.test.sh 派工單閘:該擋的與不該擋的
|
||||
bash hooks/tests/reply-identity.test.sh 身份欄:正門與側門兩道
|
||||
bash hooks/tests/dispatch-format-guard.test.sh 派工單閘+**回覆那條路**:該擋的與不該擋的
|
||||
bash hooks/tests/reply-identity.test.sh 身份欄:正門與側門兩道
|
||||
bash hooks/tests/roster-guard.test.sh 工人名單:指名、沒有這個人、注入
|
||||
bash hooks/tests/diagnosis-evidence-guard.test.sh 未經調查不寫診斷
|
||||
```
|
||||
|
||||
測資裡放的是**真的發生過的那幾份違規派工單**,不是想像出來的例子。
|
||||
|
||||
---
|
||||
|
||||
## 5. 寫上票之前:**未經調查不寫診斷**(inkstone/ISEP#87)
|
||||
|
||||
順序只有一個方向:**先派人查 → 拿到查的結果 → 才可以寫診斷。**
|
||||
|
||||
> 「診斷寫完了,工人就不知道自己要做什麼——它會照著我的結論去驗證,而不是去查。
|
||||
> 而我不是那個 repo 的專家,它才是。」
|
||||
|
||||
機械閘 `hooks/diagnosis-evidence-guard.sh` 看三個**結構**訊號(一個關鍵字都沒有):
|
||||
|
||||
1. 這個 session 有沒有**派人查過那張票**(`investigate-first-stamp.sh` 的戳記)
|
||||
2. 這段話裡有沒有**走得過去的出處**(檔案:行號/commit/comment 號/票號/網址/實測輸出)
|
||||
3. 這段話**有沒有份量**(一句「收到」不可能是診斷)
|
||||
|
||||
①有 ⇒ 放行。①無+②有 ⇒ 放行(**轉述有出處不能被誤擋**)。三者皆缺 ⇒ 擋一次。
|
||||
|
||||
🔴 **「根因」「因為」「應該是」這類詞一律不准當判準**——leo 2026-08-17 已證偽文字層封路:
|
||||
當日 8 次誤攔、0 次正確攔截,而且**紅線寫得越細,命中關鍵字的機率越高 ⇒ 那些閘在懲罰謹慎**。
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# `agents/` — 工人名單(inkstone/ISEP#86)
|
||||
|
||||
> leo 派工時派給的不能是「一個 agent」,要派給**有名字的人**。
|
||||
> 「票上看不出來這件事是誰做的」是這張票的來由。
|
||||
|
||||
**一個檔案 = 一個工人。** 每個檔案只回答四件事:
|
||||
|
||||
| 段 | 問題 | 為什麼一定要有 |
|
||||
|---|---|---|
|
||||
| `**負責 repo**` | 它管哪一個 repo | 派工時挑人的唯一判準;也是【身份】欄第二格 |
|
||||
| `## 開工前先讀` | 它要先讀什麼 | 這是**每個工人各自不同**的部分——共通規定補不了 |
|
||||
| `## 紅線` | 它不准做什麼 | 全機共通的紅線在共通規定裡;這裡只寫這個 repo 特有的 |
|
||||
| frontmatter `description` | 一句話它是誰 | `scripts/roster list` 印的就是這一行 |
|
||||
|
||||
## 為什麼是這個形狀,不是自己造一套
|
||||
|
||||
`agents/` 是 Claude Code plugin **原生**的 subagent 目錄,檔名(frontmatter 的 `name`)
|
||||
就是 `Task` 工具的 `subagent_type`。⇒ 「指名派給誰」不必發明新欄位、不必改派工單格式
|
||||
(派工單仍然只有 `【工單】` 一行,`dispatch-format-guard.sh` 的行為一個字都沒變)。
|
||||
|
||||
## 怎麼用
|
||||
|
||||
```
|
||||
python3 scripts/roster list # 名單:有哪幾個工人、各自管什麼
|
||||
python3 scripts/roster show isep-hand # 一個工人的全文(它開工前會讀到的東西)
|
||||
python3 scripts/roster names # 只印名字,給腳本用
|
||||
```
|
||||
|
||||
派工時把名字放進 `Task` 的 `subagent_type`;名字不在名單上,
|
||||
`hooks/roster-guard.sh` 會擋下來並說「**沒有這個人**」,同時把名單印出來。
|
||||
|
||||
## 加一個工人
|
||||
|
||||
在這個目錄新增一個 `.md`(照既有檔案的四段),然後:
|
||||
|
||||
```
|
||||
python3 scripts/roster list # 新的名字要出現
|
||||
bash hooks/tests/roster-guard.test.sh # 全綠
|
||||
```
|
||||
|
||||
**不必改任何 hook**——名單是資料,閘讀的是這個目錄。
|
||||
+19
-9
@@ -1,4 +1,4 @@
|
||||
# 52 支閘,白話盤點表
|
||||
# 56 支閘,白話盤點表
|
||||
|
||||
> 回應 `inkstone/InkStoneCo#40`:「如果加入了,我應該可以白話文看到 hooks 的內容?」
|
||||
> 這份表就是那個「白話文」——不用點開任何 `.sh` 檔,一行看懂一支閘在管什麼。
|
||||
@@ -7,16 +7,14 @@
|
||||
|
||||
## 一句話結論
|
||||
|
||||
`hooks/` 底下有 **53 個 `.sh` 檔**,`hooks.json` 實際掛上 **68 條註冊**(同一支閘常被多種情境同時掛上);
|
||||
`hooks/` 底下有 **53 個 `.sh` 檔**,`hooks.json` 實際掛上 **68 條註冊**(同一支閘常被多種情境同時掛上);
|
||||
`hooks/` 底下有 **56 個 `.sh` 檔**,`hooks.json` 實際掛上 **75 條註冊**(同一支閘常被多種情境同時掛上);
|
||||
其中 **3 支檔案存在但沒被掛上**(2 支是待人填的空範本、1 支是刻意留著沒開的止血帶,見下面「未生效」表)。
|
||||
下面按「你會在什麼時候撞到它」分組,一支一行。
|
||||
|
||||
> 🔴 **這兩個數字上一版是錯的(2026-08-26 實際數過才發現)**:本頁原本寫「43 個檔、53 條註冊」,
|
||||
> 而當時真實是 **45 個檔、55 條註冊**——中間有兩支閘進來時沒有回頭改這裡。
|
||||
> 現在的寫法是實際數出來的:
|
||||
> `ls hooks/*.sh | wc -l` = 53;`grep -c '"command":' hooks/hooks.json` = 68。
|
||||
> `ls hooks/*.sh | wc -l` = 53;`grep -c '"command":' hooks/hooks.json` = 68。
|
||||
> `ls hooks/*.sh | wc -l` = 56;`grep -c '"command":' hooks/hooks.json` = 75。
|
||||
> ⚠️ **冒號不能省**:`grep -c '"command"'`(沒冒號)會連 `"type": "command"` 一起數到,回 **120**。
|
||||
> 本頁 2026-08-27 之前寫的是沒冒號那版——**照著它跑會拿到一個跟本頁不符的數字**。
|
||||
> **一份會偷偷過期的盤點表,跟沒有盤點表差不多**——見本頁最後「怎麼跟實況對帳」那段。
|
||||
@@ -41,6 +39,18 @@
|
||||
> 📌 **`0.7.0`(`inkstone/ISEP#30`,2026-08-27)進來一支**:`mainline-idle-guard.sh`(F 組,Stop)。
|
||||
> 48→**49** 支、59→**60** 條,兩個數字都是加完之後當場數出來的(指令同上)。
|
||||
>
|
||||
> 📌 **`inkstone/ISEP#86`/`#87`/`#88`(2026-08-28)進來三支、+7 條**:
|
||||
> `roster-guard.sh`(D 組,`Task`+`Agent` 各一條)、
|
||||
> `diagnosis-evidence-guard.sh`(A 組,Bash)、
|
||||
> `investigate-first-stamp.sh`(H 組,`Agent|Task` 與 `SendMessage` 各一條),
|
||||
> 外加 `dispatch-format-guard.sh` 多掛兩處——Bash(接 `claude -p` 這條路)與
|
||||
> **新的「回覆 subagent」matcher**(`SendMessage` 與雲端 session/trigger 那幾支)。
|
||||
> 53→**56** 支、68→**75** 條,兩個數字都是**在這棵樹上當場數出來的**
|
||||
> (`ls hooks/*.sh | wc -l`/`grep -c '"command":' hooks/hooks.json`),
|
||||
> 不是拿上一版加減推的。順手改掉兩個過期的數字:`README.md` 的「48 支/59 條註冊/23 支腳本」
|
||||
> ——實數是 53/68/35(那是**併之前** main 上的實況),本版之後是 56/75/36。
|
||||
> **同一個病,只是換一個檔案。**
|
||||
|
||||
> 📌 **`0.10.0`(`inkstone/ISEP#81`,2026-08-28)進來一支**:`pr-verdict-guard.sh`(F 組,Stop)。
|
||||
> 51→**52** 支、64→**65** 條,兩個數字都是加完之後當場數出來的(指令同上)。
|
||||
> 順手改掉一個過期的數字:描述欄長期寫「27 支腳本」,實數是 **34**
|
||||
@@ -77,7 +87,7 @@
|
||||
| `reply-identity-guard.sh` | 直接打 Gitea API 貼留言到票上時,內文第一行沒有 `【身份】`(`總管`/`subagent`/`leo`)就擋下——票上多條線並行時,看不出哪一則是誰寫的。純讀取、走 `scripts/ticket` 正門、指令裡加 `reply-identity-ok` 都放行。 | 🛑 擋 |
|
||||
| `comment-carries-task-guard.sh` | AI 要在票裡留一則「等某某上線才驗得了」這種**還沒做完的事**,卻沒有把它開成一張子票時,擋一次。留言沒人會回頭讀,票的 open/closed 撈一次就看得到。 | 🛑 擋(同一輪只擋一次) |
|
||||
| `search-is-not-proof-guard.sh` | AI 用知識庫的**搜尋**找到一筆東西,然後把那筆東西的原始編號直接貼進票裡或派工單裡,當成「某個功能壞了」的證據——而它從沒用正規的檢索路徑去查過那筆——擋一次。你關心的是:不會再有人拿錯的方法量出一個錯的結論,然後退回一張其實已經做完的票。 | 🛑 擋(同一輪只擋一次) |
|
||||
|
||||
| `diagnosis-evidence-guard.sh` | 你想把一段有份量的東西寫上票,而這個 session **沒派人去查過那張票**、那段話裡也**沒有任何走得過去的出處**(檔案:行號/commit/comment 號/票號/網址/貼出來的實測輸出)就擋一次——未經調查的診斷寫在票上會長得像事實,工人會照著它去驗證而不是去查。派過人查、或把出處帶上,都放行;一句短回覆不管。 | 🛑 擋 |
|
||||
## B. AI 想寫檔案/改程式碼的當下(PreToolUse / Write·Edit·MultiEdit)
|
||||
|
||||
| 閘名 | 對你意味著什麼 | 動作 |
|
||||
@@ -109,8 +119,8 @@
|
||||
| `micromanage-guard.sh` | 派工單寫得太細(指名檔案函式、編號步驟、要求每做一項回報一次…)就擋下——subagent 該被當成有能力的同事,不是照抄劇本的工具。 | 🛑 擋 |
|
||||
| `irreversible-dispatch-guard.sh` | 派工單裡出現「刪分支」「drop table」「rm -rf」這類不可逆動作,卻沒寫「先停下來等回覆才執行」就擋下。 | 🛑 擋 |
|
||||
| `no-ticket-no-dispatch.sh` | 派工單裡沒有寫工單號(`【工單】owner/repo#N`),或那張票已經關閉/根本不存在,就擋下——沒有票號的工作沒有人追得到進度。 | 🛑 擋 |
|
||||
| `dispatch-format-guard.sh` | **派工單 = 票號,就這樣。** 票號以外還寫了別的東西(背景、驗收條件、紅線、交件方式、「這個 session 才知道的事」)就擋下,並告訴你那些內容該搬去哪:每次都一樣的 → 共通規定;這次才知道的 → **寫進那張票**。反過來,合規的派工它會**自動把共通規定注入**給收工方(交件方式、不准 push main、org 是 `inkstone`…),所以你不寫也不會漏。判準是「這一行是不是【工單】欄位」——**在不在**,不是寫了什麼,所以講得再謹慎也不會被多罰。純禮貌收尾(「謝謝」)不算違規;`(→ comment M)` 不論全形或半形括號都認得(ISEP#65 修過一次:CLAUDE.md 自己規定的合格寫法曾經被這支閘自己擋下)。 | 🛑 擋(+注入) |
|
||||
|
||||
| `dispatch-format-guard.sh` | **派工單 = 票號,就這樣。** 票號以外還寫了別的東西(背景、驗收條件、紅線、交件方式、「這個 session 才知道的事」)就擋下,並告訴你那些內容該搬去哪:每次都一樣的 → 共通規定;這次才知道的 → **寫進那張票**。反過來,合規的派工它會**自動把共通規定注入**給收工方(交件方式、不准 push main、org 是 `inkstone`…),所以你不寫也不會漏。判準是「這一行是不是【工單】欄位」——**在不在**,不是寫了什麼,所以講得再謹慎也不會被多罰。純禮貌收尾(「謝謝」)不算違規;`(→ comment M)` 不論全形或半形括號都認得(ISEP#65 修過一次:CLAUDE.md 自己規定的合格寫法曾經被這支閘自己擋下)。**`ISEP#88` 起同一支閘也掛在「回覆 subagent」那條路上**(`SendMessage`、雲端 session/trigger、以及 Bash 的 `claude -p`)——回覆也是派工,同一套規矩;擋下來時會把那段內容**原文印出來**方便直接貼上票。subagent 往上回報(`to: "main"`)不管,那是交件不是派工。 | 🛑 擋(+注入) |
|
||||
| `roster-guard.sh` | 派工要**指名派給誰**:`Task` 的 `subagent_type` 得是 `agents/` 名單上的名字(`isep-hand`/`arcrun-hand`/`scout`…),沒指名或指了不存在的名字就擋下,並把整份名單印出來。指對了它會**自動把那位工人的檔案原文注入**給它——你是誰、負責哪個 repo、開工前先讀什麼、你的紅線是什麼(這些每個工人都不一樣,共通規定補不了)。名單是資料:加一個工人=在 `agents/` 加一個 `.md`,不必改任何 hook。 | 🛑 擋(+注入) |
|
||||
## D2. AI 想開口問你問題的當下(PreToolUse / AskUserQuestion)
|
||||
|
||||
| 閘名 | 對你意味著什麼 | 動作 |
|
||||
@@ -168,7 +178,7 @@
|
||||
| `issue-status-autoflip.sh` | AI 一派工出去,就自動把對應的 Gitea 票改成「進行中(s/doing)」,不必等人手動改標籤。 | 📝 記錄(自動改票) |
|
||||
| `baton-handback-guard.sh` | 一條派工線做完了,就去看它那張票有沒有**指派給人/標籤有沒有說它卡在哪/有沒有寫下一步**,缺哪一格就當場說出來。你關心的是:不會再有票做完了卻沒人接手,躺在那裡沒人發現。 | 📝 記錄(提醒,不擋) |
|
||||
| `kbdb-evidence-stamp.sh` | AI 每次去知識庫拿資料,就記一筆「這是**搜尋**搜到的,還是**走正規檢索路徑**拿到的」。你關心的是:它等一下要拿這筆資料下結論時,有東西可以對照它走的是哪條路。 | 📝 記錄 |
|
||||
|
||||
| `investigate-first-stamp.sh` | 你真的**派人去查某張票**之後,按「session + 票號」留一個時間戳——給 `diagnosis-evidence-guard.sh` 判斷「這件事有沒有人查過」用。按票分而不是按 session 分:早上派人查了 A 票,不該等於解鎖了 B 票的診斷。 | 📝 記錄 |
|
||||
## I. 你會撞到但跟「派工/收工」無關的一支(Edit·MultiEdit)
|
||||
|
||||
| 閘名 | 對你意味著什麼 | 動作 |
|
||||
|
||||
Reference in New Issue
Block a user