50876ffa4f
leo 交辦:把 claude.ai 寫的治理規範整理進 ISEP,並且「查看是否合理,提出意見⋯⋯ 改一版你的版本」。原稿作者看不到 codebase,標籤名/hook 名/既有鐵律有實錯。 三份文件: - _draft-claude-ai-v0.5.0.md 原稿,一字未改,加存檔標頭 - sdd-gitea-governance.md v0.6.0 現行版 - DIVERGENCE-v0.5.0-to-v0.6.0.md 我改了哪 14 處、為什麼 修訂重點(實查 2026-08-20 的現場,不是推測): - 標籤名幾乎全是憑空的:gate/human・s/review・close/*・hub・type/* 現場一個都不存在。 Human 不改名(leo 08-17 才改過,改名會廢掉他的看板習慣),另加 human/exec 當第二維度。 - 狀態機三態擴成七態:原稿會擠掉 s/triage・s/backlog・s/pending・s/stage, 而那四個態上掛著 179 張 open 票。s/review 與 s/stage 是兩件事,不可互相取代。 - E1–E16 的 hook 全是憑空命名,改成標註「已有 <實際檔名> / 待建」—— E14 其實已經有了(subagent-claim-worksheet.sh),重造就是第 42 支互相打架的閘。 - 刪掉「薄殼只裝 shell-safe 子集」:那是舊薄殼模型的殘留,正是 InkStoneCo#57 的成因, 而且與原稿自己的 P11.2.1/P11.2.4 自相矛盾。 - 排程 job 第一版一律不依賴 Gitea Actions runner(有沒有 runner 未經查證, 依賴不確定存在的東西,壞掉的形式是「以為有人在跑」)。 - 補上原稿整份沒有的「載入契約」一節——那正是 leo 需求 3 的核心,也是 InkStoneCo#14 的根因。 - 補上 M4.6:release note 寫在 release 裡不寫 README(leo 2026-08-20 當場指正)。 - 補上 §3.4 總管收工義務:審核通過的當下就關票(leo 2026-08-20 指出上次 milestone 0% 的病)。 兩個裁決題已按判斷先做、理由寫在 DIVERGENCE §E,leo 可打回: PR-only 只套 ISEP 不套全部 repo;舊的 duplicate 標籤封存不刪。
219 lines
13 KiB
Markdown
219 lines
13 KiB
Markdown
# 我改了 claude.ai 那版的哪些地方,為什麼
|
||
|
||
> leo 2026-08-20 交辦:「你查看是否合理,提出意見,因為這個是計劃,
|
||
> 有些已經有、有些還沒有、有些有了不符合⋯⋯則你要改一版你的版本。」
|
||
>
|
||
> 本檔是**我的意見書**。原稿存檔在 `_draft-claude-ai-v0.5.0.md`,
|
||
> 修訂後的現行規範是 `sdd-gitea-governance.md`(v0.6.0)。
|
||
|
||
---
|
||
|
||
## 先講結論
|
||
|
||
- **骨架是對的,照單全收**
|
||
- 物件模型(SDD → tracking → leaf → PR → release,milestone 橫切當 time 軸)
|
||
- 「封路優於守規」這條公理——它跟你 08-17 那句「封的是動作,不是文字」是同一件事
|
||
- 「人是特殊 executor」把 `gate/human`(審核者)與 `exec/human`(執行者)拆開
|
||
- 🔴 **這是原稿最有價值的一條**。現行的 `Human` 標籤把兩件事混在一起:
|
||
「你來按放行」跟「這件事只有你的手能做」——前者你可以晚點按,
|
||
後者你不按整條線就停在那。混在一起你看不出哪張真的在擋路。
|
||
- 時態分工(SDD 未來式/Gitea 現在式/Wiki 過去式)
|
||
- **有 14 處對不上現場,我改了**。下面逐條。
|
||
- **有 2 處是你的裁決題,我先按我的判斷做了,理由寫在票上,你覺得不對就打回。**
|
||
|
||
---
|
||
|
||
## A. 事實錯誤(原稿寫的東西,現場不存在或不長那樣)
|
||
|
||
### A1. 標籤名幾乎全是憑空的
|
||
|
||
- 我實查(2026-08-20):`inkstone/ISEP` 當時 **0 個標籤**;`inkstone/InkStoneCo` 有 10 個
|
||
- 現有:`Human` `duplicate` `p/high` `p/low` `s/backlog` `s/doing` `s/pending` `s/stage` `s/todo` `s/triage`
|
||
- 原稿要的 `gate/human` `s/review` `close/*` `hub` `type/*`——**一個都不存在**
|
||
- 為什麼會這樣:claude.ai 看不到 codebase 也連不上 Gitea,標籤名只能用猜的。這不是它的錯,是那個 surface 的限制。
|
||
- **我怎麼改**:把標籤集寫成 `labels.yaml` 當唯一真相源,並且**先建出來再說**——ISEP 已經實建 23 個並驗證存在。名字取捨見 A2–A4。
|
||
|
||
### A2. `gate/human` → 不改名,維持 `Human`
|
||
|
||
- 你 08-17 才把 `s/leo` 改名成 `Human`,而且明講**它是正交維度不是流程狀態**,
|
||
你自己是靠 Gitea 原生「指派給您的」+這個標籤在看跨 repo 的待辦。
|
||
- 改名成 `gate/human` 會做兩件壞事:既有票全部要重貼標籤;你現在的看板習慣當場失效。
|
||
- **我怎麼改**:`Human` 原封不動(語意=你是審核者)。另外**新增** `human/exec`
|
||
表示「這張票的執行者是人」。兩者可以疊,也可以只有其一。
|
||
|
||
### A3. 狀態機只有三態,會把現場四個態擠掉
|
||
|
||
- 原稿:`s/todo → s/doing → s/review → closed`。
|
||
- 現場正在用的還有 `s/triage`(還沒驗傷)、`s/backlog`(要做但沒排 sprint)、
|
||
`s/pending`(卡在外部)、`s/stage`(已上 stage 等你驗)。
|
||
三個 repo 加起來 179 張 open 票掛在這些態上。
|
||
- **我怎麼改**:狀態機擴成七態,原稿的三態是其中的主幹道。
|
||
|
||
### A4. `s/review` 和 `s/stage` 是兩件事,原稿把它們當成一件
|
||
|
||
- `s/review` = **PR 開了,等總管 merge**(程式碼還沒進 main)
|
||
- `s/stage` = **已經部署到 stage,等 leo 實際打開來驗**(程式碼早進 main 了)
|
||
- 原稿只有前者,等於把「等你驗收」這個態砍掉——那正是你唯一會看的那個態。
|
||
- **我怎麼改**:兩個都留,並在狀態機裡標明先後。
|
||
|
||
### A5. E1–E16 的 hook 全是憑空命名,現場有 41 支真的
|
||
|
||
- 原稿的封路清單只寫「用什麼封」,沒有一個對得上真檔名。
|
||
- 實際對照(我逐支比對過檔名,不是猜的):
|
||
|
||
| 原稿 | 現場有沒有 | 對應到哪支 |
|
||
|---|---|---|
|
||
| E1 直接 push 預設分支 | ◐ 有但語意相反 | `main-and-prod-push-guard.sh`(擋 subagent,放行總管) |
|
||
| E6 代理越過人閘 | ◐ 部分 | `irreversible-dispatch-guard.sh`/`prod-write-guard.sh` |
|
||
| E11 地端雲端漂移 | ◐ 管的是別的 | `skill-deploy-drift-guard.sh`(管 skill,不管 manifest) |
|
||
| E12 宣稱交付但票未關 | ◐ 部分 | `delivery-police.sh`/`claim-verify-police.sh` |
|
||
| E14 subagent 空口宣稱 | ✅ **已經有了** | `subagent-claim-worksheet.sh`+`empty-handed-stop-guard.sh` |
|
||
| E2 E3 E4 E5 E7 E8 E9 E10 E13 E15 E16 | ❌ 沒有 | — |
|
||
|
||
- **我怎麼改**:修訂版的封路清單一律標「現況:已有 `<檔名>` / 待建」,
|
||
已有的不重造(重造就是第 42 支互相打架的閘)。
|
||
|
||
### A6. §11.1 的目錄結構與實際 repo 不符
|
||
|
||
- 原稿畫的是 `governance-plugin/`,實際 repo 叫 `ISEP`。
|
||
- 原稿沒提到的、實際存在的:`commands/`(7 支)、`skills/`(2 支)、`scripts/`(23 支)。
|
||
- 原稿列的、實際不存在的:`labels.yaml`、`templates/`、`jobs/`、`manifest.json`。
|
||
- 🔴 **順手抓到的髒東西**:`scripts/install.sh` 其實是 **system-dev-template 的安裝器**
|
||
(內容在裝 wiki/SDD,跟 plugin 無關),搬家時混進來的。修訂版標明它是待清理項。
|
||
|
||
### A7. §11.4.4 叫 install.sh 去 `systemctl restart gitea`
|
||
|
||
- 我沒有查證 Gitea 跑在哪台、是不是 docker、我有沒有那台的 shell。**所以我不知道這行能不能跑。**
|
||
- 但更根本的問題:原稿自己在 §11.4.3 說「模板通道壞掉不影響治理正確性」——
|
||
既然如此,就不該為它在安裝腳本裡放一個會失敗、會嚇人、還可能重啟到別人東西的動作。
|
||
- **我怎麼改**:模板通道降級成 optional 的獨立腳本,不掛在 install 流程上。
|
||
|
||
### A8. Telegram「小六 bot 通道」
|
||
|
||
- 原稿直接寫了通道名。**我沒有核實過那是不是現役通道名**,所以修訂版不寫死通道名,
|
||
改成指向 `wiki/agent-memory.md` 的通知通道段(真相源在那裡,這裡只放指針)。
|
||
|
||
---
|
||
|
||
## B. 與你既有鐵律直接打架的(照原稿走,第一天就會違規)
|
||
|
||
### B1. §11.2.5「薄殼只裝 manifest 標記 shell-safe 的子集」— 🔴 這條我整條刪掉
|
||
|
||
- **這是舊薄殼模型的殘留,而且它會把你剛拆掉的病裝回去。**
|
||
- 你 08-20 的原話是「同一個 plugin 你用,薄殼也用,**保證兩邊同步**」。
|
||
「只裝子集」= 兩邊不一樣 = 就是 `InkStoneCo#57`(薄殼少 7 支閘)那張票的成因本身。
|
||
- 原稿其他地方(P11.2.1「安裝同一個 release」、P11.2.4「整包替換禁止 cherry-pick」)
|
||
跟這條**自相矛盾**——它自己也知道不該有子集。
|
||
- **我怎麼改**:刪除,並在修訂版明文寫「沒有子集,只有同一份」。
|
||
|
||
### B2. §12.1 說 SDD 的寫入者是「人」、代理僅提案
|
||
|
||
- 現況相反:SDD 幾乎都是 AI 寫的,你是審的那個。照字面走,第一天就全面違規。
|
||
- **我怎麼改**:改成「代理可寫,但範圍/驗收/非目標的變更必經人閘」——
|
||
管的是**哪些欄位需要你點頭**,不是誰握筆。
|
||
|
||
### B3. E9 留言 ≤600 字元、同票同 session >3 則就 reject
|
||
|
||
- 這條的方向是對的(推理進 wiki,留言只帶指標),但**數字太緊,而且它懲罰誠實**。
|
||
- 你 08-17 自己的診斷:文字層的閘那天 **8 次誤攔、0 次正確攔截**,
|
||
而且「紅線寫得越細,命中關鍵字的機率越高 ⇒ 那些閘在懲罰謹慎」。
|
||
- **我怎麼改**:超長不 reject,改成**擋下來並要求把長內容移去 wiki 再留指標**;
|
||
則數上限拿掉(改用「同一張票同一 session 第 4 則起要先讀前 3 則」的提示,不是硬擋)。
|
||
|
||
### B4. E13「`s/review` 佇列非空即 block 總管 stop」
|
||
|
||
- 這條會讓總管**永遠停不下來**:你在上課、沒人 merge,佇列就一直非空。
|
||
- 而且它跟現有的 `empty-handed-stop-guard.sh`(判準是「這回合有沒有 tool call」)疊在一起,兩支會互相踩。
|
||
- **我怎麼改**:判準改成「有**我自己開的** `s/review`,而**這一回合我完全沒碰它**」才擋——
|
||
擋的是遺忘,不是擋等待。
|
||
|
||
### B5. M4.3「Timebox 不可延長,到期強制關 milestone、搬票、打 tag」
|
||
|
||
- 對你的作息(上課日只有中午晚上各看一眼)**這條會製造假交付**:
|
||
scope 縮到剩一張票也照樣打 tag,那個 tag 打開來沒東西。
|
||
- 而且它依賴排程 job,而我不確定有沒有 runner(見 C1)。
|
||
- **我怎麼改**:到期**不自動關、不自動打 tag**,改成強制做一次「降 scope 對帳」並通知你;
|
||
打 tag 永遠是「驗過了」才發生的動作。
|
||
|
||
---
|
||
|
||
## C. 技術可行性我實查過的
|
||
|
||
### C1. 排程 job(E5/E8/E16/stale/digest)需要 Gitea Actions runner — **我還沒查有沒有**
|
||
|
||
- 誠實標記:**這格我沒驗。** 我不知道這台 Gitea 有沒有掛 runner。
|
||
- 另外你的 D20 紅線「禁排程輪詢」管的是 **GitHub**(自架 Gitea 不受 flag 影響),
|
||
所以規則上不衝突,但**能不能跑是另一回事**。
|
||
- **我怎麼改**:第一版所有 job 都做成 `scripts/` 底下可手動跑、也可由 SessionStart hook 順手跑的東西,
|
||
**不依賴 runner**。等確認有 runner 再升級成排程。這樣壞掉的成本是「沒人跑」,不是「以為有人跑」。
|
||
|
||
### C2. Gitea 1.26.4 支援 label `exclusive` — ✅ 查證過,可用
|
||
|
||
- 所以原稿 P11.4.5「`s/*` 與 `close/*` 一律 exclusive,非法狀態不可表示」**成立**,我照做了。
|
||
- 現有 10 個標籤全部 `exclusive: false`,這次會被改成 true。
|
||
|
||
### C3. Gitea 有 issue dependency API — ✅ 查證過(`/issues/{index}/dependencies`)
|
||
|
||
- 所以 R2.5「順序關係用原生 dependency」可行。
|
||
|
||
### C4. Gitea **沒有**跨 repo 搬 issue 的 API — ❌ 查證過
|
||
|
||
- 只有 repo transfer,沒有 issue transfer。
|
||
- 影響:`InkStoneCo#40`(forge-discipline 母規格)、`#57`、`#14` **搬不到 ISEP**。
|
||
- **我怎麼改**:不搬,用互鏈。ISEP 的 hub 票 `#1` 指回那三張。
|
||
|
||
---
|
||
|
||
## D. 原稿沒寫、但非有不可的(你的需求 1–3 的核心)
|
||
|
||
### D1. plugin 到底怎麼被載入 — 原稿整份沒提
|
||
|
||
- 你的需求是「雲端每次執行拉 `github.com/youlinhsieh/inkstoneco`,
|
||
CC plugin 要把 loading 需要的放進去」。
|
||
- 原稿 §11 講的是「分發」(release、manifest、checksum),
|
||
**完全沒講 Claude Code 這個 host 怎麼發現並掛載這個 plugin**。
|
||
- 而這正是 `InkStoneCo#14` 那張票的病根:Claude Code 只在 session 啟動當下讀一次 cwd 的 `.claude/`。
|
||
- **我怎麼改**:修訂版加一節「載入契約」,並且這件事另立 `ISEP#5` 專票去做實測。
|
||
|
||
### D2. 版本號的一致性沒有任何機制
|
||
|
||
- 原稿 §9 說「plugin 版本 = 規範版本」,但沒說怎麼保證。
|
||
- 而**今天就出事了**:README 宣稱 0.1.0、`plugin.json` 寫 0.1.0、Gitea 上 **release 數 = 0**。
|
||
- **我怎麼改**:修訂版把 E12 改寫成「版本三處一致」的閘(`plugin.json` / tag / release 存在),
|
||
並把「release note 寫在 release 裡、不寫 README」寫進規範(你 08-20 的原話)。另立 `ISEP#6`。
|
||
|
||
### D3. ISEP 是 private repo,雲端拿不到就什麼都不用談
|
||
|
||
- 原稿沒提憑證。**這是整條線最可能默默失敗的一格。**
|
||
- 修訂版寫進「載入契約」,實作走既有 credential 機制(D36:只拿名字不碰值)。
|
||
|
||
---
|
||
|
||
## E. 兩個裁決題(我先按自己的判斷做了,你打回我就改)
|
||
|
||
### E1. E1「PR-only,禁止直接 push 預設分支」要不要套到所有 repo?
|
||
|
||
- **衝突點**:你的 CLAUDE.md 明寫「總管推 main **自己裁**(但要逐筆看過那些 commit)」,
|
||
原稿要求全部走 PR。兩者不能同時成立。
|
||
- **我的判斷**:**只有 ISEP 這個 repo 走 PR-only,其他 repo 維持現行。**
|
||
- 理由:ISEP 是所有環境的唯一真相源,它壞掉是**所有 session 一起壞**——
|
||
這個 repo 值得多一道摩擦。其他 repo 壞掉只影響自己。
|
||
- 一刀切到 14 個 repo 會在你最忙的時候把整條線卡在「等總管開 PR」。
|
||
- **這題命中四題公式的「跨專案結構」**,所以我標成裁決題寫在這裡;
|
||
但照你 08-17 的規矩(不確定 → 假設 → 記錄 → 繼續走),我不停下來等。
|
||
|
||
### E2. 現有 `duplicate` 標籤要不要被 `close/duplicate` 取代?
|
||
|
||
- **我的判斷**:新的照建,舊的**不刪只封存**(`is_archived`)。
|
||
- 理由:刪標籤會把它從所有歷史票上摘掉——那是不可逆的,而且會讓舊票的關閉理由憑空消失。
|
||
|
||
---
|
||
|
||
## 附:我沒動的東西(原稿寫得比我好的)
|
||
|
||
- §1 物件模型的那張圖與職責表——直接沿用
|
||
- §5 關閉分類 taxonomy(七種 `close/*`)——名稱與語意全部沿用
|
||
- §7 討論路由的那棵決策樹——沿用
|
||
- §10.1「OP 是票的唯一狀態容器,留言是 append-only 的 delta」——沿用,這條解掉了「一張票要讀 40 則留言才知道現況」
|
||
- §12.4 單向依賴(Wiki 壞不影響 Gitea,Gitea 壞不影響 SDD,通知丟不影響一切)——沿用
|