# 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`。 ### B0 — 先讓機器把要貼的東西產生好(不要自己拼湊) ``` bash scripts/make-cloud-env.sh ``` 它會去既有的 `.env` 把值讀出來,產生一個**含真實值、可直接複製**的檔到 `~/.claude/cloud-env/<時間>.txt`(權限 600,**刻意不在任何 repo 裡**),只把路徑印出來。 變數的**名字**寫在腳本裡(要加變數就加在那個清單),**值不進版控、不進對話**。 🔴 **貼完就刪那個檔**(指令印在它自己最後一行)。 ### 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 一開,找這一行: ``` 🟢 ISEP v0.3.0 已載入(44 支閘在 …) ``` **該看到**:有這行,而且版本號跟 Releases 頁最新那個一樣。 **失敗**: - **沒有這行** ⇒ plugin 沒載入,這個 session 是**零閘狀態**。先修 plugin,不要開始做事。 - 版本比 Releases 舊 ⇒ 環境快取住了(setup 跑完會被拍成快照,約 7 天、或改了 setup script 才重拍)→ 動一下 setup script 的內容強制重拍。 🔴 **為什麼是這一行,而不是叫它跑指令**:這行由 `isep-presence-beacon.sh` 發出, 而那支腳本**住在 plugin 裡**。plugin 沒載入 ⇒ 它不可能發聲。 **沒有「剛好也會過」的情況**——這就是鑑別力。 ### B3 — 要它把 setup 的驗證結果貼回來 ``` 把這個環境 setup script 的輸出貼給我看 ``` **該看到**兩行綠: ``` ✅ git 認證通:拉得到 inkstone/ISEP ✅ marketplace inkstone 已就位 ``` **失敗**:任一行是紅的 ⇒ 訊息本身會講該查什麼(token 值對不對、有沒有被撤銷)。 看不到任何輸出 ⇒ setup script 根本沒跑,回 B1 確認欄位真的存好了。 ### B4 — 閘真的會擋(用有鑑別力的動作) ``` 請把這段寫進 /tmp/x.md:__GITEA_TOKEN__=abc ``` **該看到**:被 `credential-only-guard` 擋下,訊息提到金鑰佔位符。 **失敗**: - 真的寫進去了 ⇒ 雲端仍然沒有閘。 - 它只是嘴上說「我不應該這麼做」而沒有閘的訊息 ⇒ 同上,那是模型自律不是機械閘。 🔴 **不要再用 `git tag` 當測試**(舊版 B4 就是這樣寫的,而它是假的): `git tag` 出現在**三支閘的白名單**裡,閘全滅時它照樣「被擋」的相反——照樣通過, 於是 2026-08-20 那次雲端零閘,三個驗證步驟**全部回綠**。 一個在閘死掉時也會給出正確答案的測試,不是測試。 ### B5 — 回報 B2(信標那行)/B3(setup 輸出)/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 的里程碑不准關。**