完成的證明
你無法決定工作是否完成。腳本會根據收據來決定。你的工作是撰寫合約、產生證明,並逐字報告腳本計算出的裁決。
請求: $ARGUMENTS
規則
無收據,即無聲明。
收據僅對其提取時所在的程式碼有效。
裁決是計算出來的,絕非手寫。
「完成」、「已修復」、「正常運作」、「通過」、「準備就緒」、「已部署」、「一切順利」、勾號,或任何讓讀者相信其中之一的句子,都屬於聲明。「應該可以運作」也是如此,這是一個附帶藉口的聲明。每個聲明都需要在當前樹的帳本中有一行「PROVEN」,否則就不能提出。
引擎
此技能資料夾中的 scripts/proof.py(通常位於 ~/.claude/skills/proof-of-done/scripts/proof.py,或專案中的 .claude/skills/proof-of-done/...)。標準庫,Python 3.8+。每次會話設定一次:
P="python3 $(ls -d ~/.claude/skills/proof-of-done .claude/skills/proof-of-done 2>/dev/null | head -1)/scripts/proof.py"
所有內容都位於專案根目錄的 .proof/ 中:acceptance.md(合約,請提交它)、contract.lock 和 contract-log.md(請提交它們)、receipts.jsonl 和 artifacts/(本地證據,已加入 git 忽略)。
五個步驟
1. 合約,在程式碼之前
$P init,然後撰寫 .proof/acceptance.md。每個標準一行,四個欄位:
- AC1 :: 已登入使用者可以連接 Gmail 並看到「已連接」 :: e2e :: run: npx playwright test tests/gmail-connect.spec.ts
- AC2 :: 一封電子郵件變成一項任務,其主旨作為標題 :: integration :: run: pytest tests/test_email_to_task.py -q
- AC3 :: 收件匣頁面無需重新整理即顯示新任務 :: visual :: see: screenshot after converting one email
- 一個標準陳述的是某人(使用者、呼叫者、檔案、資料列)可以觀察到什麼,而不是存在什麼程式碼。「新增了一個處理器」不是一個標準。
- 等級是該聲明所需證明的強度。閱讀 references/proof-ladder.md 來選擇它:UI 聲明至少需要
e2e或visual,錯誤修復需要一個修復前會失敗的測試,部署需要在部署目標上進行runtime。 run:是僅在標準成立時才返回退出碼 0 的確切命令。按照你將要執行的方式撰寫它。範圍狹窄是好的(一個測試檔案),空洞則不行(true、echo ok、沒有斷言的測試)。- 如果使用者提供了標準,請使用他們的用詞。如果沒有,則從請求中推導出它們,在一個簡短的區塊中顯示它們,然後繼續進行(除非某個標準確實含糊不清,否則不要等待)。新增一個
## 超出範圍列表,這樣就不會有人根據未要求的內容對你評分。 $P freeze。從現在開始,刪除一個標準、降低等級或將命令換成更簡單的命令,都會顯示在contract-log.md中,並且需要使用使用者同意的--reason。新增標準則始終可以。
對於一行變更,合約可以只是一個標準。它仍然存在。
2. 建置,邊做邊證明
正常實作。在每個連貫的步驟之後,執行 $P run AC2(或 $P run --all)並閱讀其輸出。FAILED 行是資訊,不是繞道而行的障礙:閱讀輸出,修復原因,再次執行。對於錯誤修復,在修復前執行新測試,並記住那個失敗的收據:一個從未失敗過的迴歸測試無法證明任何東西(先紅,後綠)。
對於 see: 標準:產生證據(Playwright 截圖、儲存到檔案的 curl -i 輸出、匯出的 CSV、日誌摘錄),打開它並查看它(讀取圖片,讀取檔案),然後執行 $P attach AC3 path/to/shot.png --note "inbox after convert, task visible"。該檔案會被複製到 .proof/artifacts/ 中,因此不會干擾其他收據。附加你沒有查看過的截圖,與引用你沒有執行過的測試是同樣的謊言。
3. 裁決
$P run --all # 為每個標準取得最新收據,在最終樹上執行
$P verdict # 帳本和裁決;僅當完成時返回退出碼 0
狀態:PROVEN(收據在當前樹上通過)、FAILED、PENDING(無收據)、STALE(證明後程式碼已變更)、MISMATCH(收據執行了與合約不同的命令)、SUSPECT(退出碼 0 但執行了零個測試,僅有跳過、缺少工具,或證明了編輯了樹)、BLOCKED、WAIVED。裁決:DONE、DONE WITH WAIVERS、BLOCKED、NOT DONE。
最後一次執行後的任何編輯,即使是註解,都會使收據變為 STALE。這就是重點:最後執行,然後立即報告。
4. 獨立檢查
製造者永遠不會為自己的工作評分。當任務不僅僅是小的變更、觸及 UI、部署或資料,或是由子代理完成時,請啟動一個檢查者子代理,並使用 references/checker.md 中的提示。它會重新讀取合約、自己重新執行證明、查看附加的檔案、讀取差異以檢查範圍蔓延和閘門篡改,並返回 ACCEPT 或 REJECT 並附上原因。REJECT 則回到步驟 2。當子代理告訴你它成功了時,以同樣的方式對待它:git diff --stat,自己執行它的證明。
5. 報告
從完全按照計算出的裁決行開始,然後是收據:
VERDICT: DONE (或 NOT DONE / BLOCKED / DONE WITH WAIVERS)
| 標準 | 證明 | 結果 |
|---|---|---|
| AC1 使用者連接 Gmail,看到「已連接」 | npx playwright test tests/gmail-connect.spec.ts | exit 0, 3 passed |
| AC2 電子郵件變為任務 | pytest tests/test_email_to_task.py -q | exit 0, 5 passed |
| AC3 收件匣無需重新整理即顯示任務 | .proof/artifacts/AC3-...png (已查看) | 任務在頂部可見 |
檢查者:ACCEPT (或 REJECT:...)
未證明:無 (或每個未解決的標準、原因以及下一步行動)
超出範圍:...
如果是 NOT DONE,首先清楚地說出來,然後說明哪些已證明、哪些未證明,以及最小可行的下一步。明確的 NOT DONE 是一份好的報告。結果是錯誤的 DONE 會讓使用者花費除錯時間並失去他們的信任。
語言守衛
在發送任何訊息之前,掃描它。以下這些在當前樹上需要一個 PROVEN 收據,否則就不能出現:
- done, finished, complete, fixed, resolved, works, working, passes, green, ready, shipped, deployed, live, all good, should work, should be fixed, probably, looks good, ✅, "Perfect!", "Great, that worked"
- 當你只運行了子集時說「tests pass」;當你只運行了 linter 時說「build passes」;當你推送時說「deployed」;當你變更了程式碼但未重現症狀時說「fixed」。
說出你運行了什麼以及它返回了什麼:「pytest tests/test_email_to_task.py: 5 passed, exit 0」不言自明。當你還沒有運行過時:「尚未驗證」。
完整的藉口表格以及證明被規避的方式在 references/anti-gaming.md 中。每個專案閱讀一次;簡短版本:永遠不要削弱、跳過、模擬掉或刪除證明聲明的東西,也永遠不要編輯測試以匹配錯誤的輸出。
停止掛鉤(可選,按專案)
$P hook --install 將一個 Stop 掛鉤新增到 ./.claude/settings.local.json(--shared 新增到已提交的 settings.json)。在一個擁有 .proof/acceptance.md 的專案中,當會話嘗試在裁決不是 DONE 時結束時,掛鉤會將其退回一次並附上未解決的標準,除非最後一條訊息已經包含 VERDICT: NOT DONE 或 VERDICT: BLOCKED。它永遠不會循環(它會讓第二次停止通過),並且在沒有合約的專案中不執行任何操作。為長時間或無人值守的工作安裝它;告知使用者它已存在。
當無法執行證明時
沒有瀏覽器、沒有暫存環境存取權限、遺失金鑰、付費 API:不要默默地用較弱的證明代替。$P block AC4 --reason "no staging credentials" 並報告 BLOCKED,附上確切遺漏的內容以及一旦它存在時將證明它的命令。$P waive 僅適用於使用者明確放棄的標準,使用他們的用詞,引用在原因中。
小型任務
一個錯字或一行配置:一個標準、一個命令、一個收據、報告中的一行(VERDICT: DONE + 命令及其結果)。儀式可以縮小;規則不能。