3f622ba646
+ 每次結案都留下估多久/花多久/差多少(inkstone/ISEP#85) #84:scripts/release-manifest freeze 前每一格都真的去 Gitea 抓過(抓不到不給凍結);凍結後不准再加東西; rollback 一定吐出整份清單的每一格,--only 指名單一 repo 會被擋下 ——那正是票上那個病:剩下的還停在新版 ⇒ 一組從來沒測過的組合。 清單與 INDEX.md 寫在專案根的 releases/(不是 plugin 目錄,plugin update 會清掉)。 #85:scripts/milestone-account + hooks/milestone-account-guard.sh 三個數字自己算(取自 Gitea 的 created_at/due_on/closed_at,不用手填); 差超過 ±25%(超時或提早都算)就要從七個固定代號裡挑一個,挑不出來不准結案; 代號要有 Gitea 時間軸撐得住——訊號不成立的代號直接拒收(不採信自述)。 閘擋的是「直接 curl PATCH state=closed 但還沒記帳」,正門走 milestone-account close。 盤點數字在本樹實數(ls hooks/*.sh|grep -c '"command":'): hooks 53→54 支、註冊 68→69 條、scripts 39 支(描述欄舊的 38 把三個目錄也數進去了)。 順手修掉 docs/hooks-inventory.md「一句話結論」被貼兩次、且標頭 52/內文 53 互相矛盾。 測試(全部離線,不打 Gitea、不留測試票/不關真的 milestone): scripts/test-release-manifest.sh 21/21 scripts/test-milestone-account.sh 23/23 hooks/tests/milestone-account-guard.test.sh 22/22 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ZBu4Sa1cGntKFRBYNZ6xs
66 lines
3.5 KiB
Markdown
66 lines
3.5 KiB
Markdown
# ISEP — InkStone Environment Plugin
|
||
|
||
> leo 2026-08-20:「你把全部環境設定放在一個 claude code plugin,**同一個 plugin 你用,薄殼也用,保證兩邊同步**⋯⋯
|
||
> 以後有任何變化,增加 command, hook⋯⋯都增加在這裡,再去跟它同步。」
|
||
> 「我要你幫雲端做薄殼,永遠都有問題,**你要做的就是這組設定你自己可以 dogfooding**。」
|
||
|
||
## 這個 repo 解什麼
|
||
|
||
在此之前,同一套環境有**兩份**:
|
||
|
||
```
|
||
真身 InkStoneCo/.claude/ ← 本機在跑的
|
||
薄殼 由 generate-shell-payload.py 產生一份,塞進 GitHub 私 repo ← 雲端在跑的
|
||
```
|
||
|
||
兩份必然漂移。`inkstone/InkStoneCo#57` 記著實測結果:**薄殼比真身少 7 支閘**,
|
||
其中兩支是前一天才立的。`#14` 更早:雲端 33 支 guard **一支都沒生效**。
|
||
|
||
⇒ 現在只有一份:**本 repo 就是唯一真相源**,本機與雲端裝同一個 plugin。
|
||
⇒ 而且**總管自己也用它**——壞掉的時候是我先踩到,不是雲端替我踩。
|
||
|
||
## 裝什麼
|
||
|
||
| | 數量 | 是什麼 |
|
||
|---|---|---|
|
||
| `hooks/` | 54 支 + `hooks.json` | 全部機械閘(PreToolUse/Stop/SubagentStop/SessionStart/PostToolUse 共 69 條註冊,2026-08-28 在樹上實數;`ISEP#60` 移除 `claim-verify-police.sh`/`subagent-claim-worksheet.sh` 這對自造機制,改由 Gitea 原生三格承接見 `ISEP#59`) |
|
||
| `commands/` | 7 支 | `/wiki-recall` `/ship-check` `/cp-write` … |
|
||
| `skills/` | 2 支 | |
|
||
| `scripts/` | 23 支 | `ticket`/`github-arm.sh`/`gitea-bootstrap.sh` … |
|
||
|
||
**不放**:`.env`(金鑰,違 D36「金鑰只有一個家」)、`wiki/`、`docs/`、`_archive/`
|
||
——那些是**知識**不是**環境**。
|
||
|
||
## 路徑規約(薄殼一直壞掉的根)
|
||
|
||
hook 一律用官方的 `${CLAUDE_PLUGIN_ROOT}`,**不准寫死絕對路徑、也不用 `$CLAUDE_PROJECT_DIR`
|
||
去指 hook 自己**:雲端的 cwd 不是真身,寫死就斷。
|
||
腳本**內部**要指專案檔案(wiki、docs)時才用 `$CLAUDE_PROJECT_DIR`——那是對的,
|
||
因為那些東西本來就住在被操作的那個 repo 裡。
|
||
|
||
## 改東西的規矩
|
||
|
||
🔴 **只改這裡,然後兩邊 `/plugin update`。**
|
||
不要再改 `InkStoneCo/.claude/hooks/`——那個目錄退場中。
|
||
|
||
## 這些閘各自在管什麼
|
||
|
||
**不用點開任何 `.sh`**——`docs/hooks-inventory.md` 一支一行白話,按「你會在什麼時候撞到它」分組。
|
||
測試手冊在 `docs/TESTING.md`,治理規範在 `docs/governance/`。
|
||
|
||
🔴 **派工前先讀 `docs/governance/dispatch-and-reply-format.md`**——
|
||
派工單只給票號(其餘全部寫進票或共通規定),票上的每一則留言第一行要表明身份。
|
||
兩件事都有機械閘(`dispatch-format-guard.sh`/`reply-identity-guard.sh`)。
|
||
|
||
## 版本
|
||
|
||
**「ISEP 現在是哪一版」只有一個地方答得出來:[Gitea Releases](https://git.uncle6.me/inkstone/ISEP/releases)。**
|
||
每一版的內容、改了什麼、驗過什麼都寫在那裡的 release note,不寫在這份 README。
|
||
|
||
這份 README 本來寫死過「狀態:0.1.0」,但 repo 一個 tag 都沒打(`release_counter=0`)——
|
||
leo 當場指出這是違規:宣稱交付卻沒有 tag 撐它(`inkstone/ISEP#6`)。
|
||
現在改成結構性防漂移:`.claude-plugin/plugin.json` 的 `version` 欄位永遠跟最新 tag 一致,
|
||
`scripts/check-version-consistency.sh` 會擋下兩者對不上的狀態,
|
||
`hooks/release-tag-guard.sh` 則在打 tag 的當下直接擋住不一致的 tag——
|
||
細節與判準都寫在那兩支腳本開頭的註解。
|