工人有名字+回覆也是派工+未經調查不寫診斷(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:
@@ -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 次正確攔截,而且**紅線寫得越細,命中關鍵字的機率越高 ⇒ 那些閘在懲罰謹慎**。
|
||||
|
||||
Reference in New Issue
Block a user