文章目錄

Whetstone 是我從 Matt Pocock Skills fork 出來、只為 Claude Code 與 GitHub Issues 改寫的 Skill 組。主流程一樣是 grill、to-spec、to-tickets、implement、pr,差別最大的有兩處。第一,implement 不再每張工單做完都 code review,只有 checkpoint 工單(做錯會影響後續工單的那幾張)先審,其餘的在開 PR 前一起審,審查次數與額度消耗都比較少。第二,implement 與 implement-spec 合併成一個 implement,並重新設計開分支、審查與實作方式,可以選擇由主 Session 自己實作,或把工單全部派給 Subagent。
用 Claude Code 開發、用 GitHub Issues 管理工單的人可以直接換成 Whetstone。使用 Codex、GitLab 或 Linear,或是依賴 triage 與 wayfinder 的話,繼續用 Matt Pocock Skills 比較合適。Matt Pocock Skills 本身的流程請見用 Matt Pocock Skills 拆工單並逐張實作。
兩套流程對照
Whetstone 以 Matt Pocock Skills v1.3.1(commit 5beb35b)為基準改寫。兩者最大的差別是 implement 什麼時候審查,下圖以三張工單、其中一張是 checkpoint 為例,橘色是審查發生的位置:
逐階段的差異如下:
| 階段 | Matt Pocock Skills | Whetstone |
|---|---|---|
| grill | grill-me、grilling、grill-with-docs 三個 | 合併成 grill |
| to-spec | 只能手動呼叫,user story 要求列得越完整越好 | Claude 可接續呼叫,一個使用者目標寫一則 user story |
| to-tickets | 只能手動呼叫,加上 ready-for-agent label,工單不寫檔案路徑 |
建立 sub-issue 與 blocked by,標出 checkpoint,列出預計修改的檔案 |
| implement | implement 做一張,implement-spec 做整份,每張工單派一個 Subagent 在 Worktree 實作 | 合併成一個 implement,可選模式 A 或模式 B |
| code review | implement 每張工單做完都審,審完才 commit,implement-spec 全部做完審一次 | 只有 checkpoint 工單 commit 後先審,其餘 commit 在 pr 時一起審 |
| commit | 沒有對應 | commit Skill,一張工單一個 commit,結尾加 Refs: #n |
| pr | 只寫 PR 本文,draft PR 由 implement-spec 開 | 審查、push 並開 PR,本文替每張工單列一行 Closes #n |
差異一:code review 的時機
Matt Pocock Skills 的 implement 規定每張工單做完都呼叫 code-review,審完才 commit。code-review 每次都會平行開兩個 Subagent,一個檢查是否符合專案規範,一個檢查是否符合 spec。工單有十張就審十次,其中多數工單只是照著已定好的介面加功能,逐張審查花掉的時間與額度,換到的效果有限。
Whetstone 只讓真正需要的工單先審,其餘集中在開 PR 前審一次。哪些工單要先審,在 to-tickets 拆工單時決定。Claude 會建議把錯誤容易擴散的工單標成 checkpoint,例如共用介面、資料結構或風險較高的核心修改,由使用者確認,大多數工單不需要標。標成 checkpoint 的工單,本文最後一行會加上 <!-- whetstone:checkpoint -->。兩個審查時間點如下:
- implement 做完 checkpoint 工單並 commit 後,立即對這個 commit 執行 review。必須修的問題用同一個
Refs的新 commit 修正,依賴它的工單開工時,介面已經審過。 - pr 在 push 前收集分支上的 commit,跳過
Refs指向 checkpoint 工單的那些,只審其餘的 commit。
下面是測試 repo 的 tickets 腳本輸出,原本是以 Tab 分隔的純文字,這裡整理成表格:
| Issue | 狀態 | 標題 |
|---|---|---|
| spec #5 | open | greet:預設名字、--shout 與 --lang zh |
| 工單 #6(checkpoint) | in-review | greet(name, options) 介面、預設名字與 CLI 參數解析 |
| 工單 #7 | in-review | --shout 大寫問候 |
| 工單 #8 | in-review | --lang zh 與未知語言錯誤 |
#7 與 #8 都被 #6 擋住,#6 定義的介面兩張都會用到,所以標成 checkpoint,做完就先審查。#7 與 #8 拆工單時刻意分開修改的檔案,#6 完成後可以同時進行。三張工單都已連結到 open 的 PR,所以狀態是 in-review。
這樣做也有代價。非 checkpoint 工單的問題要到開 PR 前才會發現,如果漏標了該先審的工單,後面的工單可能已經照著錯的設計寫完。checkpoint 的修正 commit 與 pr 階段的修正 commit 也不會再審。每標一張 checkpoint 就多跑一輪 review,標得越多,越接近每張工單都審。
review 本身也有三個改變:
- 問題分成
must-fix與judgement兩級。must-fix 由流程直接修正。judgement 是需要人判斷的建議,例如程式碼壞味道,不自動修。checkpoint 階段的 judgement 列在 implement 的最終報告,pr 階段的寫進 PR 本文的「AI review」段落。Matt Pocock Skills 則是把 code review 提出的問題全部修掉。 - 審查員指定模型。規範審查用 Haiku,依規範文件涵蓋的目錄分組,每組一個,最多三個。需求審查用 Sonnet。變更少於約 100 行、規範也只有一組時,不開 Subagent,由主 Session 直接審。
- 沒有指定範圍時,預設審查
origin/<預設分支>...HEAD,不會像 code-review 先問使用者要從哪裡開始比。
重構的位置也跟著調整。Matt Pocock Skills 的 tdd 只做紅燈與綠燈,重構交給 code-review。Whetstone 的 tdd 在綠燈後就重構這一輪寫到的程式碼,沒碰到的程式碼才交給 review。
差異二:implement 與 implement-spec 合併成一個
Matt Pocock Skills 的實作分成兩個 Skill。implement 做一張工單,由主 Session 用 tdd 實作,做完先 code review 再 commit 到目前的分支。implement-spec 做整份 spec,先建立整合分支,每張工單派一個 Subagent 在各自的 Worktree 實作,再由 merger Subagent 合併,全部做完後審查整個分支一次。
Whetstone 把兩者合併成一個 implement,傳工單編號就做一張,傳 spec 編號就做整份,並重新設計了分支、審查與實作方式:
| 項目 | implement | implement-spec | Whetstone 的 implement |
|---|---|---|---|
| 範圍 | 一張工單 | 整份 spec | 依傳入的編號,一張或整份 |
| 分支 | 直接 commit 到目前分支 | 建立整合分支 | 開工時問一次:從預設分支開 <spec#>-<slug>,或留在目前分支 |
| 實作者 | 主 Session | 每張工單一個 Subagent,各開 Worktree | 模式 A 或模式 B,見下一節 |
| code review | 每張工單做完都審 | 全部做完審一次 | 只先審 checkpoint 工單,其餘在 pr 審 |
| commit | 審完才 commit | 各工單分支由 merger Subagent 合併 | 一張工單一個 commit,結尾加 Refs: #n |
| 開 PR | 不處理 | 第一次合併後開 draft PR | 做完後問要不要接著執行 pr |
除了表中的項目,Whetstone 的 implement 開工前會用 --add-assignee @me 把工單指派給自己,避免兩個 Session 做同一張。進度都記在 GitHub 的工單狀態與 commit 的 Refs: #n,中途停下來,下次在新的 Session 執行同一個指令就會從沒做完的工單接著做。
誰來實作:模式 A 與模式 B
Whetstone 的 implement 開工時,把分支和模式放在同一則訊息一起問。只剩一張工單,或所有工單都被 blocked by 串成一條線、不可能平行時,就不問模式,直接用模式 A。下表把兩種模式和 implement-spec 並排比較:
| 項目 | implement-spec | 模式 A(預設) | 模式 B |
|---|---|---|---|
| 實作者 | 每張工單一個 Subagent | 主 Session,可平行時才派 Subagent | 每張工單一個 Subagent |
| 工作目錄 | 每張工單各開 Worktree | 共用同一個 | 範圍重疊又要平行時才開 Worktree |
| 合併 | merger Subagent | 主 Session 逐張 commit | 主 Session commit,Worktree 用 land 腳本 |
| 適合 | 所有 spec | 一般大小的 spec | Context 撐不完的長 spec |
模式 A 和 Matt Pocock Skills 的 implement 一樣由主 Session 實作,差別在它能處理整份 spec,也能平行。平行靠的是 to-tickets 在每張工單列出預計修改的檔案。兩張可以同時開工的工單檔案不重疊時,主 Session 把其中一張交給 Sonnet Subagent。Subagent 不 commit,只跑自己工單的測試,完成後由主 Session 檢查 diff、跑完整測試,再把它的檔案 commit 成那張工單。會改到相同檔案的工單,拆工單時就設成互相 blocked by 或直接合併,不會同時進行。Matt Pocock Skills 的 to-tickets 則要求不寫檔案路徑,理由是路徑很快會過時,implement-spec 改用 Worktree 隔離每張工單。
模式 B 接近 implement-spec,主 Session 只負責協調,但不會替每張工單都開 Worktree。檔案不重疊的工單一樣共用工作目錄,只有修改範圍重疊、又想平行進行的工單才各開一個 Worktree,Subagent 在自己的分支 commit,主 Session 再用 land 腳本 rebase 回 spec 分支,不會產生 merge commit。
兩種模式的 Subagent 都只有三種回報:DONE、TICKET SCOPE CHANGE REQUIRED、BLOCKED。工作需要超出工單範圍時,Subagent 會停下來回報,由主 Session 問使用者,不會自己擴大範圍。
模式 A 的取捨在主 Session。它要用同一個 Context 做完所有工單,spec 一長就可能撐不完,這時改用模式 B。兩種模式與 implement-spec 的 Token 用量,我還沒有實測比較。
其他差異
流程以外的差異如下:
| 項目 | Matt Pocock Skills | Whetstone |
|---|---|---|
| 支援的 Agent | Claude Code、Codex 等 | 只支援 Claude Code |
| 工單管理 | GitHub、GitLab、本機 Markdown 或自行描述 | 只支援 GitHub |
| Skill 數量 | Plugin 內含 27 個 | 16 個 |
| 專案設定 | /setup-matt-pocock-skills 在每個專案寫入 docs/agents/* 與 CLAUDE.md 段落 |
不在專案寫入設定檔 |
| 工單狀態 | 用 triage label 標記 | 從 GitHub 原生欄位推導 |
| GitHub 操作 | 由模型自己組 gh 指令 |
由固定的腳本執行 |
| 主流程接續 | to-spec、to-tickets、implement 只能手動呼叫 | 五個主流程 Skill 都能由 Claude 接續呼叫 |
| 安裝與更新 | Plugin 或 skills.sh | clone 後用 link 腳本連到 ~/.claude/skills,以 git pull 更新 |
專案裡不留設定檔
Matt Pocock Skills 的 /setup-matt-pocock-skills 會在每個專案寫入 issue tracker 種類、label 對照與 domain 文件位置,Skill 改版後每個專案都要重跑一次。Whetstone 只支援 GitHub,issue tracker 種類不必再設定。其他需要的事實,主要是建置、測試與 Lint 指令,改成每次執行時依下圖的順序尋找,找到就停。auto memory 是 Claude Code 依 repo 存在本機的記憶,問過的答案存進去,下次就不必再問:
工單狀態也不再需要 label。spec 是 parent issue,工單是掛在它底下的 sub-issue,先後順序用 blocked by 表示,implement 開工時會把工單指派給自己。PR 本文替每張工單寫一行 Closes #n,merge 進預設分支時 GitHub 一次關閉全部工單,PR 被退回時工單也不會提早關閉。
GitHub 操作交給腳本
透過 GitHub API 設定 blocked by 時要傳 blocker 的 database id,不能傳 #number 或 node_id,Matt Pocock Skills 的 GitHub 說明也特別標出這一點。讓模型每次自己組指令,就得先把這份說明讀進 Context,組錯時還要讀錯誤訊息再重試。Whetstone 把這些操作放進三支腳本:context 偵測 repo 與分支,tickets 列出工單狀態,land 把模式 B 的 Worktree 分支合回 spec 分支並刪除 Worktree。每支腳本都有 .sh 與 .ps1,只有 PowerShell 可用的 Windows 電腦也能執行。
常駐 Context 更少
Claude Code 每回合都會把可自動呼叫的 Skill 名稱與描述放進 Context。Matt Pocock Skills 的 27 個 Skill 中有 11 個可由 Claude 呼叫,描述合計 2,152 字元。Whetstone 有 12 個,描述合計 1,608 字元,多了主流程的 Skill,總長度反而少了四分之一。Skill 被呼叫時才讀入的 Markdown 本文,全部加總從 203,214 字元降到 74,006 字元,這個數字包含刪除 11 個 Skill 的部分。以上都是字元數,不是 Token 數。
不適用的情況
Whetstone 只為我自己的環境設計,下列情況不適合:
- 使用 Codex 或其他 Agent。Whetstone 刪除了 Matt Pocock Skills 給 Codex 的
agents/openai.yaml,Skill 也依賴 Subagent 模型指定、auto memory 這些 Claude Code 專屬的功能。 - 工單放在 GitLab、Linear、Jira 或本機 Markdown。Whetstone 只呼叫
gh。 - 依賴 triage Skill 與 label 分流 issue。Whetstone 不讀也不建立 label。
- 需要 wayfinder 規劃一次 Session 做不完的大型工作。wayfinder 會把大型工作拆成一張張待決策的工單,Whetstone 沒有對應的 Skill,只能自己拆成多份 spec。teach、prototype 等其他刪除的 Skill 同樣沒有替代。
- 希望每張工單做完都先審查。Whetstone 只先審 checkpoint 工單,理由見前面的差異一。
- 希望 Skill 內容是中文。Whetstone 的
SKILL.md一律用英文寫,回覆語言交給使用者的 CLAUDE.md 決定。
安裝與從 Matt Pocock Skills 遷移
安裝前先登入 gh,再 clone repo 並執行 link 腳本:
1gh auth login
2git clone git@github.com:tedliou/whetstone.git
3bash whetstone/scripts/link.sh
Windows 改用 powershell -NoProfile -ExecutionPolicy Bypass -File whetstone/scripts/link.ps1,它會建立指向 repo 資料夾的 Junction,不需要系統管理員權限。接著在 Claude Code 執行一次 /setup-whetstone,它只會修改 ~/.claude,寫入輸出風格與危險指令的 deny 規則。
已經裝了 Matt Pocock Skills Plugin 的話,/setup-whetstone 會提議停用它,避免兩套 tdd、grill 同時出現。原本習慣的 Skill 在 Whetstone 的對應如下:
| Matt Pocock Skills | Whetstone |
|---|---|
| grill-me、grilling、grill-with-docs | grill |
| implement、implement-spec | implement,傳工單編號做一張,傳 spec 編號做整份 |
| code-review | review,改名是為了避開 Claude Code 內建的 /code-review |
| setup-matt-pocock-skills | setup-whetstone |
| 沒有對應 | commit |
| triage、wayfinder、teach、prototype、research、wizard、ask-matt 等 | 沒有對應 |
tdd、diagnosing-bugs、domain-modeling 等其餘 Skill 保留名稱並整份重寫。Matt Pocock Skills 寫進專案的 docs/agents/* 與 CLAUDE.md 段落不會被 Whetstone 讀取,可以自行決定是否刪除,已建立的 triage label 也不影響工單狀態的判斷。
改寫的過程
保留原專案歷史的 fork
Matt Pocock Skills 的 SCOPE.md 寫明個人化的修改應該放在 fork 裡,所以我沒有回頭發 PR,而是建了新 repo 並推入完整歷史,保留每個 commit 的作者與 blame。分岔點標成 upstream-base tag,Matt Pocock Skills 發新版時可以拿來比對。
依 Claude 官方建議改寫
改寫的依據是 Claude Code 的 Skills 文件與 Anthropic 的 Skill authoring best practices。文件中影響設計的行為,以及 Whetstone 的對應做法如下:
| 官方文件的行為或建議 | Whetstone 的做法 |
|---|---|
| Skill 清單的預算是 Context 的 1%,超過時先拿掉最少用的 Skill 描述 | 只需要手動用的 Skill 設 disable-model-invocation: true,可自動呼叫的描述合計限制在 1,700 字元內 |
| Context 壓縮後,每個已呼叫的 Skill 只保留前 5,000 Token | SKILL.md 本文控制在 5,000 Token 內,必須成立的規則放最前面 |
參考檔只從 SKILL.md 連一層 |
分支、commit、關票規則只寫在 _shared/workflow.md,各 Skill 直接連過去 |
在 SKILL.md 用 !`指令` 動態填入內容時,指令失敗會讓整個 Skill 無法載入 |
不用動態填入,第一步用現有的 Shell 工具執行 context 腳本 |
| 用要搭配的模型分別測試 | Subagent 的指示做成填空模板,規範審查用 Haiku、需求審查與實作用 Sonnet |
另外我自己加了一條規則:Skill 不用 MUST、CRITICAL 這類全大寫強調,改成寫出要做什麼和原因,讓模型能判斷例外。
讓主流程能接續又不誤觸發
主流程 Skill 開放 Claude 呼叫後,最怕「幫我 implement 一個 debounce 函式」這種一般請求也觸發 implement,跑去查 GitHub 並開分支。主流程 Skill 的描述因此都寫明觸發條件,例如 implement 要求有 issue 編號,或是接在 to-tickets 之後:
1description: Implements a GitHub ticket or a whole spec, one commit per ticket. Use only with an issue number or after to-tickets, not for ad hoc coding.
我用 Claude Code 2.1.309 的 claude plugin eval,替五個主流程 Skill 各寫 3 則該觸發和 3 則不該觸發的 Prompt,兩套 Skill 各跑 3 次,每次只載入受測的 Plugin。Matt Pocock Skills 有三個 Skill 只能手動呼叫,不列入比較。該觸發的結果如下:
| 主流程步驟 | Prompt 範例 | Matt Pocock Skills | Whetstone |
|---|---|---|---|
| grill | 「Grill me on this plan: …」 | 9/9 | 9/9 |
| to-spec | 「討論完了,把剛剛的結論開成 spec。」 | 只能手動呼叫 | 9/9 |
| to-tickets | 「Break spec #12 into tickets.」 | 只能手動呼叫 | 9/9 |
| implement | 「Implement #42.」 | 只能手動呼叫 | 9/9 |
| pr | 「幫我開 PR。」 | 6/9 | 9/9 |
不該觸發的 Prompt 兩套都沒有誤觸發。Matt Pocock Skills 的 pr 描述只有「Use when writing a PR body.」,兩則英文 Prompt 都觸發了,中文的「幫我開 PR。」三次都沒觸發。Prompt 是我自己寫的,數字只能說明這組情境下的結果。
在測試 repo 跑完整流程
觸發測試只能確認 Skill 有被叫起來,結果對不對要在真的 repo 上跑。這部分的測試我交給 Claude Opus 5.5 自動執行,讓它在一個私有的測試 repo,用一個小 CLI 需求把 Whetstone 從 grill 一路跑到開 PR。給 AI 用的 Skill 也由 AI 來測,Skill 每改一版就能重跑一次完整流程,不必每次自己操作。前面的 tickets 輸出就來自這次測試。這次找到三個只讀 SKILL.md 看不出來的問題:
| 問題 | 修正 |
|---|---|
${CLAUDE_SKILL_DIR} 只在 Skill 內容裡被替換,參考檔與 Shell 指令裡都不會 |
每個 SKILL.md 自己寫出腳本資料夾,並要求在 Shell 中寫出完整路徑 |
| Windows 上用暫存檔傳 commit 訊息時,路徑太長導致失敗 | commit 訊息與 issue 本文改走 stdin(git commit -F -、--body-file -) |
Refs #n 少了冒號,git 不會把它當成 commit 訊息結尾的 trailer 欄位 |
改成訊息最後一行的 Refs: #n |
Refs: #n 不只是格式問題。pr 要靠它找出哪些 commit 屬於 checkpoint 工單、可以跳過審查,新的 Session 也靠它判斷哪些工單已經完成。
總結
Whetstone 適合用 Claude Code 與 GitHub Issues、想讓主流程一路接下去的人。它最大的取捨在審查:只有容易擴散錯誤的 checkpoint 工單先審,其餘集中在開 PR 前審一次,省下逐張審查的時間與額度。實作預設由主 Session 用同一個 Context 完成,只有長 spec 才把工單全部派給 Subagent。
- 優點:審查次數從每張工單一次,減少為 checkpoint 數量加一次,共用介面這類錯誤仍能在後續工單開工前審查。一般大小的 spec 不必替每張工單建立 Worktree 與 Subagent,Skill 改版也只要
git pull。 - 缺點:非 checkpoint 工單的問題要到開 PR 前才會發現,漏標該先審的工單時,後續工單可能已經照著錯的設計寫完。模式 A 的主 Session Context 會隨工單變長。
- 尚未驗證:實際省下多少 Token,以及延後審查是否漏掉逐張審查能抓到的問題。