verification-gate · diff
git:20260515.4186f14 to git:20260723.ee57bf2
34 added, 160 removed. Audit A to A.
---
name: verification-gate
- description: 完成前驗證閘門,強制要求提供新鮮的驗證證據才能宣稱完成。當 agent 或使用者聲稱「完成了」「修好了」「做好了」但未提供驗證證據時自動啟用。不適用於設計討論(用 design-brainstorm)或分支決策(用 branch-finisher)。
+ description: 完成前驗證閘門,強制要求提供新鮮的驗證證據才能宣稱完成。當 agent 或使用者聲稱「完成了」「修好了」「測試通過」「done」「fixed」但未附驗證證據時自動啟用。
allowed-tools: Read, Bash, Grep, Glob
---
# Verification Gate — 完成前驗證閘門
- 借鑑 obra/superpowers 的 `verification-before-completion` 概念,適配 DD Pipeline 風格。
-
- ## 核心原則
-
- **證據優先於宣稱,永遠如此。**
-
- > 沒有新鮮的驗證證據,就不能宣稱完成。
- > 執行命令 → 讀取輸出 → 然後才能宣稱結果。
+ 借鑑 obra/superpowers 的 `verification-before-completion` 概念。
## 鐵律
- **禁止在沒有新鮮驗證證據的情況下宣稱完成。**
-
- - 「新鮮」= 在本次工作中實際執行並觀察到的結果
- - 「之前跑過」不算 — 程式碼改了,之前的結果已失效
- - 「應該可以」不算 — 推測不是證據
- - 「改動很小」不算 — 小改動也能破壞系統
-
- ## 觸發條件
-
- **自動觸發時機:**
- 當出現以下宣稱但缺乏對應證據時啟用:
-
- **關鍵詞:**
- - 「完成了」「做好了」「修好了」「已修復」
- - 「測試通過」「建置成功」「部署完成」
- - 「所有功能正常」「問題已解決」
- - 「done」「fixed」「all tests pass」
-
- ## 5 步驗證流程(閘門函數)
-
- ### Step 1: 識別驗證項目
-
- 列出所有需要驗證的項目:
-
- | 宣稱類型 | 必要驗證 |
- |---------|---------|
- | 「測試通過」 | 執行 `npm test` / `pytest` 並讀取輸出 |
- | 「建置成功」 | 執行 `npm run build` / `cargo build` 並確認零錯誤 |
- | 「bug 已修復」 | 重現原始問題的步驟,確認不再發生 |
- | 「功能已實作」 | 執行功能的端對端測試或手動驗證 |
- | 「沒有迴歸」 | 執行完整測試套件,確認無新增失敗 |
- | 「linting 通過」 | 執行 `eslint` / `ruff` 並確認零警告 |
- | 「型別正確」 | 執行 `tsc --noEmit` / `mypy` 並確認零錯誤 |
-
- ### Step 2: 執行驗證命令
-
- 對每個驗證項目:
- 1. 執行對應的命令
- 2. **等待命令完成**(不要假設結果)
- 3. 記錄完整輸出
-
- ### Step 3: 讀取並分析輸出
-
- - 逐行讀取命令輸出
- - 識別成功/失敗指標
- - 記錄任何警告或異常
-
- ### Step 4: 驗證結果
-
- - 所有驗證項目都通過?→ 進入 Step 5
- - 有任何失敗?→ **停止,修復問題,重新從 Step 1 開始**
- - 有警告但不影響功能?→ 記錄警告,進入 Step 5
-
- ### Step 5: 宣稱完成(附帶證據)
-
- 產出驗證報告:
-
- ```markdown
- ## 驗證結果
+ **執行命令 → 讀取輸出 → 然後才能宣稱結果。** 沒有新鮮證據就不能宣稱完成。
- | 項目 | 命令 | 結果 | 證據 |
- |-----|------|------|------|
- | 測試 | `npm test` | 通過 (25/25) | [輸出摘要] |
- | 建置 | `npm run build` | 成功 | 零錯誤,bundle size: 245KB |
- | Lint | `eslint .` | 通過 | 零警告 |
+ 「新鮮」= 本次工作中、最後一次修改**之後**實際執行並觀察到的結果。
+ 「之前跑過」「應該可以」「改動很小」都不算。
- **結論**:所有驗證通過,工作已完成。
- ```
+ ## 驗證流程
- ---
+ 1. **識別驗證項目** — 依宣稱類型對照:
- ## 常見失敗模式
+ | 宣稱 | 必要驗證 |
+ |---------|---------|
+ | 測試通過 | 執行測試指令,讀完整輸出(通過/失敗/跳過數,不只看 exit code) |
+ | 建置成功 | 執行 build,確認零錯誤、輸出檔案存在 |
+ | bug 已修復 | 重現原始問題步驟,確認不再發生 |
+ | 功能已實作 | 端對端執行該功能(真實 API / 瀏覽器,同 6 步迴圈步驟 5) |
+ | 沒有迴歸 | 執行完整相關測試套件,確認無新增失敗 |
+ | lint / 型別正確 | 執行 linter / type checker,確認零錯誤 |
+ | subagent 回報完成 | 讀 subagent 改的檔案 + 親自重跑它聲稱通過的驗證 |
- | 宣稱 | 問題 | 正確做法 |
- |------|------|---------|
- | 「測試應該會通過」 | 沒有實際執行 | 執行測試,讀取輸出 |
- | 「我剛才跑過了」 | 在修改後沒有重新執行 | 每次修改後重新驗證 |
- | 「改動太小不會有問題」 | 假設小改動無風險 | 小改動也要驗證 |
- | 「其他測試不受影響」 | 沒有執行完整測試套件 | 執行所有相關測試 |
- | 「本地跑得好好的」 | 環境差異 | 確認 CI 也通過 |
+ 2. **執行並讀取** — 等命令完成,逐行讀輸出,記錄警告與異常
+ 3. **裁決** — 全過 → 附證據宣稱完成;任何失敗 → 停止、修復、從頭重驗
+ 4. **宣稱完成(附證據)** — 報告格式:項目 / 命令 / 結果 / 證據摘要,逐列列出
- ## 紅旗清單 — 看到這些就停下
+ 修 bug 時的迴歸驗證模式:`git stash && <測試>`(看到失敗)→ `git stash pop && <測試>`(看到通過)。
- 以下任何情況出現時,**立即停止並補充驗證**:
+ ## 紅旗 — 看到即停下補驗證
- - 使用「應該」「大概」「我覺得」等不確定語氣
- - 跳過測試因為「改動很小」
+ - 「應該」「大概」「我覺得」等不確定語氣出現在完成宣稱裡
- 宣稱完成但沒有貼出任何命令輸出
- - 引用舊的測試結果(修改前的)
- - 說「手動驗證過了」但沒有說明步驟
- - 假設 subagent 的工作是正確的而未確認
+ - 引用修改**前**的測試結果
+ - 「手動驗證過了」但沒說步驟
+ - 未經確認就採信 subagent 的回報
## 合理化防範
- | 常見藉口 | 現實 |
+ | 藉口 | 現實 |
|---------|------|
| 「這只是重構,不影響行為」 | 重構是最常引入 bug 的操作之一 |
| 「型別系統已經保證了」 | 型別不能保證運行時行為 |
+ | 「改動太小」 | 小改動也能破壞系統 |
| 「我很確定」 | 確定程度不能替代證據 |
- | 「時間不夠跑測試」 | 不跑測試花的時間更多(debug) |
- | 「測試太慢了」 | 至少跑相關的測試子集 |
-
- ## 關鍵驗證模式
-
- ### 測試驗證
- ```bash
- # 不要只看 exit code,讀取完整輸出
- npm test 2>&1
- # 確認:通過數、失敗數、跳過數
- ```
-
- ### 迴歸測試
- ```bash
- # 先確認修改前的失敗
- git stash && npm test # 看到失敗
- git stash pop && npm test # 看到通過
- ```
-
- ### 建置驗證
- ```bash
- npm run build 2>&1
- # 確認:零錯誤、零警告、輸出檔案存在
- ```
-
- ### 需求驗證
- ```markdown
- 逐條對照需求清單:
- - [ ] 需求 1: [具體驗證方式和結果]
- - [ ] 需求 2: [具體驗證方式和結果]
- ```
-
- ### Agent 委託驗證
- ```markdown
- subagent 回報完成後:
- 1. 讀取 subagent 修改的檔案
- 2. 執行 subagent 聲稱通過的測試
- 3. 確認結果一致
- ```
+ | 「時間不夠 / 測試太慢」 | debug 花的時間更多;至少跑相關子集 |
+ | 「本地跑得好好的」 | 環境差異存在,CI 也要過 |
## 與原生 `/goal` 的關係
- Claude Code 原生 `/goal` 指令(≥ 2.1.139)與本閘門互補,職責分工:
-
- | 機制 | 負責 |
- |------|------|
- | `/goal` | **推進跨輪迴圈** — 設定完成條件,未達成就自動再跑一輪 |
- | `verification-gate` | **把守每輪證據門檻** — 每次「完成」宣稱都必須附新鮮驗證證據 |
-
- 組合使用:用 `/goal` 自主收斂時,本閘門的鐵律仍適用於迴圈中的**每一輪** —— `/goal` 的
- 評估器讀到的「完成」宣稱,必須是執行命令、讀取輸出後得出的結果,否則就是無證據宣稱,
- 閘門應擋下。`/goal` 解決「要不要再跑一輪」,`verification-gate` 解決「這一輪能不能說完成」。
-
- ## 適用範圍
-
- **何時啟用此閘門:**
- - 宣稱 bug 已修復
- - 宣稱功能已實作
- - 宣稱測試已通過
- - 宣稱建置已成功
- - 宣稱重構未影響行為
- - subagent 回報工作完成
-
- **何時不需要:**
- - 純粹的討論或設計(沒有「完成」的宣稱)
- - 文件撰寫(無需執行驗證)
- - 探索性調查(還在了解問題)
-
- ## 底線
+ 互補:`/goal`(Claude Code ≥ 2.1.139)負責「要不要再跑一輪」;本閘門負責「這一輪能不能
+ 說完成」。用 `/goal` 自主收斂時,鐵律仍適用於每一輪 — 評估器讀到的「完成」必須是
+ 執行命令、讀取輸出後的結果。
- **執行命令。讀取輸出。然後才能宣稱結果。**
+ ## 不適用
- 沒有捷徑。沒有例外。沒有「這次不需要」。
+ 純討論/設計(沒有完成宣稱)、文件撰寫、探索性調查。