1dfc4e373a
leo 2026-08-20 問「InkStoneCo#40 加入了嗎?如果是這樣我應該可以白話文看到 hooks 的內容?」
答案是不行——43 支閘沒有任何白話清單。這一版補上。
docs/hooks-inventory.md 43 支逐支一行,按「你會在什麼時候撞到它」分 9 組
抽驗 5 支逐行核對源碼;順帶抓到 3 支有檔案沒註冊
docs/TESTING.md A1-A8 + B1-B5,每格都有「怎麼跑/該看到什麼/什麼算失敗」
scripts/test-*.sh 兩支閘的測試,共 21 條,全過
兩個實撞的洞:
- release-tag-guard 的排除清單是前綴比對,x 整條放行
(A8 那個新 session 抓到的,總管複驗屬實)。改用 #23 驗證過的判準:
關鍵字要在指令位置才算執行。補 3 條複合指令測試,8/8。
⇒ 這是 InkStoneCo#36「包一層就繞過去」的同一個病,發生在同一天新寫的閘上。
- scripts/ticket 寫死只認名叫 gitea 的 remote,在 ISEP(remote 叫 origin)整個跑不起來
⇒「開票前先搜」那道閘在新 repo 等於不存在。改成掃所有指向本站的 remote + 環境變數 fallback。
A8 已通過:新 session 裡 plugin 的閘真的觸發(exit 2、tag 未建立、訊息來自 plugin 路徑)。
文件漂移訂正:plugin.json 與 README 寫 42 支/52 條,實際 43 支/53 條。
兩支新閘補上 #40 §1 要求的三行中文檔頭。
🔴 但仍違反 #40 §3「新規則一律先 warn」——兩支都是 block。理由記在 #40 留言,等 leo 裁。
166 lines
6.5 KiB
Markdown
166 lines
6.5 KiB
Markdown
# ISEP 測試手冊
|
||
|
||
> leo 2026-08-20:「**你交出版本測試了嗎?你要測試無誤才叫我測試,
|
||
> 如果雲端不能測試也要提供 test cases 讓我開啓雲端測試**」。
|
||
>
|
||
> 規約:每一格都要有「**怎麼跑/該看到什麼/什麼算失敗**」三件。
|
||
> **沒跑過的格子一律標空白,不准標綠。**
|
||
|
||
---
|
||
|
||
## 先讀:改了 ISEP 卻沒發版,改動到不了任何人手上
|
||
|
||
2026-08-20 實撞:新增一支 hook 併進 `main`,然後跑 `claude plugin update isep@inkstone`
|
||
→ 回「**已是最新版 (0.2.0)**」,新 hook **沒有進到安裝的那一份**。
|
||
|
||
原因:`plugin update` 比的是 **`plugin.json` 的版本號,不是內容**。
|
||
⇒ **版本沒動 = 更新是 no-op = 本機與雲端又各自停在不同內容上**(就是 `InkStoneCo#57` 的病)。
|
||
|
||
**所以:任何要生效的改動,都必須跟著一個新版本號。這不是儀式,是傳輸機制本身。**
|
||
|
||
---
|
||
|
||
## A. 總管自己要跑完的(交給 leo 之前)
|
||
|
||
### A1 — plugin manifest 合法
|
||
```
|
||
claude plugin validate .
|
||
```
|
||
**該看到**:`✔ Validation passed`,不帶 warning。
|
||
**失敗**:任何 error;或有 warning 卻沒處理。
|
||
|
||
### A2 — 版本三處一致
|
||
```
|
||
bash scripts/check-version-consistency.sh
|
||
```
|
||
**該看到**:`✅ 版本一致:plugin.json=X.Y.Z,最新 tag=vX.Y.Z,README 沒有自行宣告版本。`
|
||
**失敗**:exit 1;或 README 又出現寫死的版本號。
|
||
|
||
### A3 — 打 tag 的閘:擋得住,也放得過
|
||
```
|
||
bash scripts/test-release-tag-guard.sh
|
||
```
|
||
**該看到**:`3/3 通過`(1 個該擋、2 個不該擋)。
|
||
**失敗**:該擋的放行(假綠);或不該擋的被擋——**誤攔比漏擋更該修**,誤攔會懲罰謹慎。
|
||
|
||
### A4 — 開票側門閘:13 條
|
||
```
|
||
bash scripts/test-ticket-api-bypass-guard.sh
|
||
```
|
||
**該看到**:`13/13 通過`。
|
||
**失敗**:任何一條不符,特別看「不該擋」那 8 條。
|
||
|
||
### A5 — 開票前的搜尋是跨 repo 的
|
||
```
|
||
python3 scripts/ticket where 標籤 模組化
|
||
```
|
||
**該看到**:命中數 > 0,而且結果**橫跨多個 repo**(`InkStoneCo` / `Arcrun` / `arcrun-rag` …)。
|
||
**失敗**:
|
||
- `🔴 拿不到 token` ⇒ 這個 repo 的 remote 沒帶憑證(2026-08-20 修過一次:原本寫死只認名叫 `gitea` 的 remote,
|
||
ISEP 的叫 `origin`,於是這道閘在新 repo 等於不存在)
|
||
- 結果只有單一 repo ⇒ 搜尋沒有跨 repo,等於沒搜
|
||
|
||
### A6 — 標籤對齊且冪等
|
||
```
|
||
bash scripts/gitea-labels-sync.sh
|
||
bash scripts/gitea-labels-sync.sh
|
||
```
|
||
**該看到**:第二次全部 `0 created / 0 updated`。
|
||
**失敗**:第二次還在改(不冪等);或任何既有標籤被刪除。
|
||
|
||
### A7 — plugin 裝得起來、內容對得上
|
||
```
|
||
claude plugin marketplace add https://git.uncle6.me/inkstone/ISEP.git
|
||
claude plugin install isep@inkstone
|
||
claude plugin list
|
||
claude plugin details isep
|
||
```
|
||
**該看到**:`isep@inkstone` `enabled`,版本=最新 release;`details` 列出 9 skills、5 個 hook 事件。
|
||
**失敗**:版本落後(先發版,見開頭那段);或 `marketplace list` 的 `Source` 顯示**本機目錄**而非 Git URL
|
||
——本機目錄有未提交改動就會跟 main 分岔,那是一條漂移路徑。
|
||
|
||
### A8 — 閘在**新 session** 真的會觸發
|
||
|
||
前七格證明「腳本會擋」與「檔案就位」,**不是「harness 真的會去叫它」**。
|
||
plugin 的 hook 是 session 啟動時載入,所以這格一定要開**新**的 session。
|
||
```
|
||
claude -p '請執行 git tag -a v9.9.9 -m test'
|
||
```
|
||
**該看到**:回報被擋,訊息是 `release-tag-guard` 那段(提到 plugin.json 與版本對不上)。
|
||
**失敗**:
|
||
- tag 真的被打出去 ⇒ **閘沒被載入**,這是最危險的假綠
|
||
- 訊息來自 `InkStoneCo/.claude/hooks/…` 而不是 plugin ⇒ 你驗到的是舊那份
|
||
|
||
> 為什麼挑 `release-tag-guard` 當考題:它**只存在於 ISEP**,舊的 `.claude/` 那份沒有。
|
||
> 用它才分得出「載到的是 plugin」還是「載到的是舊的」。
|
||
|
||
---
|
||
|
||
## B. 只有 leo 能跑的(雲端)
|
||
|
||
機器碰不到 claude.ai 的 Cloud environment 設定,這段一定要你動手。
|
||
看到跟「該看到」不一樣就停下來,把畫面貼回 `inkstone/InkStoneCo#14`。
|
||
|
||
### B1 — 設定(一次性)
|
||
|
||
claude.ai → **Cloud environments** → 你的環境:
|
||
|
||
1. **Environment variables** 加一個
|
||
- 名稱:`GITEA_TOKEN_CLAUDE_CODE`
|
||
- 值:**既有的** claude-code 機器帳號 Gitea token(不要新造一把)
|
||
2. **Setup script** 欄位:貼進 `docs/cloud-setup-script.sh` 的全文,一字不改。
|
||
|
||
**該看到**:儲存後沒有紅字。
|
||
|
||
### B2 — 開一個新的雲端 session,確認裝上了
|
||
|
||
在雲端 session 裡打:
|
||
```
|
||
跑 claude plugin list 給我看
|
||
```
|
||
**該看到**:`isep@inkstone` / `Version: 0.2.1`(要跟 Releases 頁最新那個一樣)/ `✔ enabled`。
|
||
**失敗**:
|
||
- 沒有 `isep` ⇒ Setup script 沒跑成功 → 叫它把 setup 的輸出貼回來
|
||
- 版本比 Releases 舊 ⇒ 環境快取住了(設定跑完會被拍成快照,約 7 天或改了 setup script 才重拍)
|
||
→ 動一下 setup script 的內容,強制重拍
|
||
|
||
### B3 — 雲端載到的元件數量要跟本機一樣
|
||
```
|
||
跑 claude plugin details isep 給我看
|
||
```
|
||
**該看到**:`Skills (9)`、`Hooks (5) PreToolUse, SessionStart, Stop, SubagentStop, PostToolUse`
|
||
——**跟本機看到的一模一樣**。
|
||
**失敗**:比本機少 ⇒ 又回到「兩邊不一樣」,正是 `InkStoneCo#57` 那張票的病。
|
||
|
||
### B4 — 最關鍵:雲端的閘真的會擋,而且擋的是 plugin 那份
|
||
```
|
||
請執行 git tag -a v9.9.9 -m test
|
||
```
|
||
**該看到**:被擋下,訊息提到「版本不一致」與 `plugin.json`。
|
||
**失敗**:
|
||
- 它真的把 tag 打出去 ⇒ **雲端仍然沒有閘**(跟 `InkStoneCo#14` 記的一樣)
|
||
- 它只是嘴上說「我不應該這麼做」而沒有閘的訊息 ⇒ 同上,那是模型自律不是機械閘
|
||
|
||
### B5 — 回報
|
||
|
||
B2/B3/B4 三個畫面貼回 `inkstone/InkStoneCo#14`。
|
||
全綠 ⇒ 那張票可以關,`#57` 也解掉一半。
|
||
|
||
---
|
||
|
||
## 目前狀態
|
||
|
||
| | 誰跑 | 狀態 |
|
||
|---|---|---|
|
||
| A1 manifest 合法 | 總管 | ✅ |
|
||
| A2 版本三處一致 | 總管 | ✅ |
|
||
| A3 打 tag 閘 | 總管 | ✅ 3/3 |
|
||
| A4 開票側門閘 | 總管 | ✅ 13/13 |
|
||
| A5 搜尋跨 repo | 總管 | ✅ |
|
||
| A6 標籤對齊+冪等 | 總管 | ✅ 14 repo,第二次 0/0 |
|
||
| A7 plugin 裝得起來 | 總管 | ✅ |
|
||
| **A8 新 session 閘會觸發** | 總管 | 見本版 release note |
|
||
| **B1–B5 雲端** | **leo** | 還沒跑(機器碰不到 Cloud environment) |
|
||
|
||
**A8 與 B 全綠之前,這個 sprint 的里程碑不准關。**
|