把一件工作從「有人說了一句話」帶到「judged 過的交付」:先判斷要不要立案,再決定現在 該在 refinement / engineering / verify-ac 哪一站、什麼時候換站,載入說明「這類工作怎麼算 done」的知識,然後一路推進到收斂或撞上四種已宣告的停點之一。任何會改變程式碼或行為的 請求都從這裡進,使用者不需要知道這個名字。唯讀的查詢與說明不走這裡。 有人帶著一件要做的事出現時的第一站,不論他有沒有說出任何指令名稱。例如 「幫我做 X」「這個壞了要修」「想重構 Y」「繼續」「接著推」。 也用於:不知道現在在哪、不知道下一步是什麼、手上有多張單不知道先做哪一張。 不用於:唯讀的查詢與說明(「這支腳本在幹嘛」「查一下 X」)——那些沒有「怎麼算成功」 要簽,直接回答。
Scanned 9/5/2026
Install to Claude Code
npx -y skills add HsuanYuLee/polaris --skill driving-work-to-done --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Driving Work To Done?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/hsuanyulee-driving-work-to-done)More formats (shields.io, HTML) on the badges page.
---
name: driving-work-to-done
description: |
把一件工作從「有人說了一句話」帶到「judged 過的交付」:先判斷要不要立案,再決定現在
該在 refinement / engineering / verify-ac 哪一站、什麼時候換站,載入說明「這類工作怎麼算
done」的知識,然後一路推進到收斂或撞上四種已宣告的停點之一。任何會改變程式碼或行為的
請求都從這裡進,使用者不需要知道這個名字。唯讀的查詢與說明不走這裡。
有人帶著一件要做的事出現時的第一站,不論他有沒有說出任何指令名稱。例如
「幫我做 X」「這個壞了要修」「想重構 Y」「繼續」「接著推」。
也用於:不知道現在在哪、不知道下一步是什麼、手上有多張單不知道先做哪一張。
不用於:唯讀的查詢與說明(「這支腳本在幹嘛」「查一下 X」)——那些沒有「怎麼算成功」
要簽,直接回答。
metadata:
version: 1.0.0
requires:
- skill: refinement
why: 立案之後簽 assertion 那一站;也是開種子單的地方(本支散文指名 open-seed-issue.sh)
- skill: engineering
why: 兩個關卡之間那一站;本支只說「去那裡」,不說怎麼做
- skill: verify-ac
why: 判定達成那一站;本支明文不做判定
scope: universal
---
# driving-work-to-done — 一件工作、一個入口、一個下一步
三支 skill 各做一站的事:`refinement` 簽下成功的定義,`engineering` 施工,`verify-ac`
判定。**它們都不決定下一步是什麼**——那寫在這裡,只寫在這裡。
一份工作有兩種成功條件,它們住在不同地方:
- **這張單獨有的**(acceptance criteria)→ 進 `refinement` 凍結的 fence。
- **這一類工作共用的**(definition of done)→ 由領域知識帶進來,見〈載入領域知識〉。
把共用的那份寫進每一張單的 fence,等於每次都重簽同樣幾行不承載新資訊的東西。
## 一、有工作進來:要不要立案
判準只有一條:**有沒有「怎麼算成功」需要人簽字。**
| 這件事 | 立案? |
|---|---|
| 查一下、說明一段程式、跑個既有測試 | 否。什麼都沒改,沒有要簽的東西 |
| 會改到程式碼或行為——不論多小 | **是** |
| 不確定 | **是**。立案的成本遠低於做完才發現目標不對 |
**只讀的問題不走這條**,其餘都走。以前這裡有一格是「改 typo、調一個顯然的常數 → 否,
成功的定義不會有爭議」,拆掉了:那一格的判準是「這件事夠小」,而那是每次都由當事人自己
判、每次都會判得更寬的東西。
**把判斷與依據說出來**,一句話就夠,讓人能當場推翻。不立案的到此為止,直接把事做完。
### 手上正在做別的事,但長出了一個不能消失的東西
開發途中會問出、查出、撞出只有當下知道的東西。停下來簽一張正式的單太貴——assertion 此刻也
簽不出來,因為怎麼算成功還沒想清楚。丟著又會消失:一個修正留在一個到不了別人手上的
地方,跟沒有那個修正是一樣的(2026-08-07 真的發生過,同一個 bug 因此咬了兩版)。
所以有第三條路:**開一張種子單,然後回去做你原本在做的事。**
開單那一刻要回答兩件事:**這是哪一種單**,以及**這件事有沒有人已經記過了**。
- **種類自己宣告**,開單那條路不從名字或內容推。舉發實作途中撞到的問題,跟開發一個新
功能,問得出答案的東西不一樣——撞到的人當下就知道自己是誰、剛剛在讀哪個檔,而想加
新功能的人沒有「撞到」這件事,那兩格硬填會填出一個編的。
- **舉發那一種開之前會看到撞到了哪幾張**,並且要對每一張寫下一句判斷。**判斷的內容不
決定開不開得成單**——說「都不是同一件」照樣開得出來。擋人的只有「沒有回答問題」。
```bash
bash .claude/skills/refinement/scripts/open-seed-issue.sh \
--issues issues --namespace <命名空間> --slug <名字> --kind report \
--who <誰、在做什麼工作時撞到的> --where <撞到的檔案> \
--what <做什麼> --when <什麼時候要> --why <想解決什麼> --how <拿什麼測> \
--note '<前因後果>' [--vs <單號>=<判斷>]...
```
新功能那一種是 `--kind feature`,不問 `--who` 與 `--where`,也不查重。跑 `--help` 看
兩種各要哪幾格。
**這幾條規矩住在哪一份,看這件工作落在誰身上。** 落在這套流程自己身上(skill、它們的
腳本、常駐規則)的話,那一份是 `framework-self-dev`——它說出為什麼是這兩種、查重的鍵
為什麼是檔案而不是標題。落在別的東西上的話,那個東西自己的知識說了算。
它不簽 assertion、不決定領域、不開 worktree、不碰你現在這張單。產出的單會出現在下面〈四〉
那個「接下來做哪一張」的答案裡,標成 `seed:`——所以它拿得給另一個 session 開工,而那個
session 從 `refinement` 開始。
**已經在進行中的單不要重問。** 同一件事往下做就是了——對已經簽過的東西再問一次是儀式,
不是把關。換成另一件會改變行為的事,才重新判斷。
## 二、現在在哪、下一步是什麼
不要問人,讀狀態:
```bash
bash .claude/skills/driving-work-to-done/scripts/spine-loop-state.sh where --state {issue}/.spine/loop-state.json
```
它會說出站別、有沒有停、還剩幾輪。**任何時候不確定現在在哪就跑它**——問人才是不知道
自己在哪的那個症狀。
它同時回答另一個「在哪」:**這個工作區還是不是這張單當初落腳的那些。** 開輪次那一刻
記下的身分由領域決定(核心只當它是一組不透明字串),之後每次問路都比一次。**那是一組,
不是一個**——一張單牽涉幾個地方由領域宣告的命令印幾行決定,核心不預設是一個。回 `DRIFTED`
表示現在動手的地方跟這張單預期的不同(少一個、多一個、值不同都算,而且它會說出少了哪些、
多了哪些)——可能是有人切走了,也可能是另一個 session 正在共用同一份工作區。回
`unmeasurable` 表示這一次什麼都沒比到,那不是「還在原地」。
| 現在的狀況 | 下一步 |
|---|---|
| 還沒有單 | `refinement`:判立案、寫 assertion、凍結、開輪次 |
| assertion 凍結好了 | `engineering` |
| 這一輪做完了、想知道算不算達成 | `verify-ac` |
| `verify-ac` 判非 PASS,原因是實作沒到 | 回 `engineering` |
| `verify-ac` 判非 PASS,原因是**assertion 本身錯了** | 停 `assertion_wrong`,回 `refinement` 重簽 |
| 交付紀錄寫成了 | 這條流程走完了。之後怎麼出貨是專案自己的事 |
| 交付紀錄寫成了,而後來有人指出還要改的東西 | 回 `engineering`。改完**重走 `verify-ac`**——那一站要量的是改完之後的東西,不是上一次留下的判定 |
| 這件事**不做了**(放棄、被別的取代、需求消失) | `close`,見下方 |
**交付之後還要改,不是一個新的開始,也不是一個停點。** 那張單的成功定義沒有變——變的是
「實作有沒有走到那份定義」這個問題的答案。所以它回 `engineering`,而不是回 `refinement`
重簽、也不是另開一張單:另開一張的話,同一份 assertion 會有兩張單各自宣稱自己達成了它。
**回去之後一定要重走判定。** 上一次的判定是對上一棵樹下的,而它會留在原地看起來仍然有效
——一份綁在舊狀態上的 PASS,跟一份剛量出來的 PASS 長得一模一樣。真的是成功的定義本身錯了
(不是實作沒到),那才是 `assertion_wrong`,走上面那一列。
**「不做了」是一個終點,不是一個停點。** 四種停點都在等人回話,而這一種已經有答案了——
它只是不會有實作。以前這種單沒有地方去:要嘛永遠躺在待辦裡被每一次「下一張做哪個」重新
看過一遍,要嘛被手動刪掉,而刪掉的那一張在下一次有人提出同一件事時說不出「這討論過」。
```bash
bash .claude/skills/driving-work-to-done/scripts/spine-loop-state.sh close \
--state {issue}/.spine/loop-state.json --note '<為什麼不做了>' [--by <人>]
```
理由是必填的:一個沒有理由的關閉,跟把單刪掉的差別只有磁碟空間。已經收斂的單它會拒絕——
那張是做完的,不是不做的,而把兩者混成同一格之後就沒有人分得出來了。
**換站不需要說服任何腳本。** `advance` 是記下來,不是請求核准。還會擋人的只有兩類:
不可逆的動作,以及證據不足。
## 三、只在四個地方停
流程停下來的時候要說出是哪一種,而且要留下紀錄——**停在紀錄外等於沒停**,回來的人只
看得到一張不動的單,看不到它為什麼不動。
| 停點 | `--kind` |
|---|---|
| assertion 不對,要人重簽 | `assertion_wrong` |
| 新增依賴/重造既有組件/擴大 security surface | `surfaced_concern` |
| 連續未收斂打到上限 | `unconverged_cap`(`record` 自己會寫) |
| 需要人授權的不可逆動作 | `unauthorized_action` |
```bash
bash .claude/skills/driving-work-to-done/scripts/spine-loop-state.sh stop \
--state {issue}/.spine/loop-state.json --kind surfaced_concern --note '<一句話>'
```
這四種以外的字串會被拒絕。**這四種以外的理由不是停下來的理由**——特別不包括「要不要
繼續?」「要我往下做嗎?」,那不是停點,那是把判斷推回給人。
## 四、沒撞停點就繼續
**沒有停點就往下走,不要回頭問。** 這包含跨單:手上有多張單而當下這張走不動了,
下一張由同一個地方回答,不是由人指定。
```bash
# 這一張單還能不能往下走
bash .claude/skills/driving-work-to-done/scripts/spine-loop-state.sh next --state {issue}/.spine/loop-state.json
# 手上這一整棵樹,接下來做哪一張
bash .claude/skills/driving-work-to-done/scripts/spine-loop-state.sh next --across-issues issues
```
單張回 `continue` 就繼續,回 `stop:<kind>` 才停。跨單回 `next:{那張單相對於樹根的位置}`——
它是拿去開檔案用的,**不是身分**:一張單的身分是它的名字,位置會隨狀態改變。並且把停住
的逐張列出來、把已收斂與已交付的算成數字——**不列成清單但要有數字**,一個安靜的第三態下一次
就會被當成看過了。
**種子單也逐張列出來**(`seed:` 開頭),不只算進數字。它們還沒簽 assertion,所以接手的第一站
是 `refinement` 而不是 `engineering`;而它們存在的整個理由就是「拿給另一個 session 開工」,
掉出這個答案的東西等於沒開。
**幾個數字加起來要等於整棵樹。** 一張單的狀態不一定住在這裡——命名空間宣告了解析器的,
權威在那個外部系統。那些單走不進站別,但它們仍然是單,所以它們有自己的數字,而不是消失:
最後一行把等式寫出來,分母是位置重算認得的那組單,不由這裡再數一次。**逐張的清單只有一
份**,在重算產出的那份「還沒出去的單」上——這裡指過去,不抄第二遍。
那個等式不是裝飾。2026-08-21 量到,這個答案只涵蓋 700 張單裡的 555 張,差的 145 張裡有
121 張還在中間態,包含正在進行的工作;而它們不在任何一格、也不在任何一個數字裡,輸出看
起來完全正常。少算的方向剛好是「看起來事情比較少」,所以沒有人會抱怨。
排序只看狀態:最靠近交付的先做(在製品不該堆高),同一站取最近動過的那張(那是「你剛剛在做
哪一張」寫在磁碟上的唯一痕跡)。命名空間叫什麼、單號多大都不參與。
**流程自己的工具擋住你的時候,那不是停點。** 一道關卡對一份已經被實證是對的交付判紅,是那
道關卡的缺陷,處理是修它然後繼續——把摩擦寫進可以改的那部分、把修法做掉。停在「被框架擋住了,你要
不要開一張單」等於把工具的問題變成人的決定,而工具是來幫忙的,不是來收費的。
同一件事的另一面:**關卡判紅而你想繞過它的時候,先把產出改成它接受的樣子**,不要把「用哪個
繞法」做成問題丟回去。關卡是權威,繞過去才需要人點頭。
### 寫摩擦的時候指名是哪一支
「這一套東西有沒有讓工作更常做對」只能從真的跑過的那幾次讀出來,而**寫的時候不指名,事後
就讀不出來**。2026-08-13 量到的:1,721 份單的正文裡有 345 份寫了摩擦,其中 323 份文件裡同時
出現某支 skill 的名字——但那是同現,不是歸因。一張走主流程的單本來就會提到 `refinement` 與
`engineering`,所以那 323 份回答不了「是哪一支害的」。**素材有量,形狀不對。**
所以摩擦與幫助各記一行,就寫在可以改的那部分裡,格式是:
```
<!-- SKILL-UTILITY: {skill 名} | helped|hurt | {一句話:發生了什麼} -->
```
**兩個方向都要記。** 只記摩擦的話,讀出來的結論永遠是「這套東西都在擋人」——而
2026-08-13 那一趟裡,兩次擋下真正不可逆的後果(公司代號要進公開 repo、副本漂開)跟六次
擋下正確的工作,是同一批紀錄該說出來的兩半。
讀它不需要工具:`grep -rn 'SKILL-UTILITY' <單的根目錄>`。**不要為它寫一支腳本**——它不擋任何
人,它是拿來讀的;一個會擋人的 utility 判準會在第三次被繞過。
**它記得到的只有走過單的工作。** 沒有立案就用掉的那些(查一下、跑個報告、看一次收件匣)
不留這種紀錄,所以這一份紀錄天生偏向「會改程式碼的工作」。這是已知的覆蓋缺口,讀結論的時候
要把它說出來,不要把「沒有紀錄」讀成「沒有問題」。
反覆出現的失敗長這樣,看到就是退化了:
- 把連續的意圖收斂成單步,做完一步就停下來報告;
- 停在階段邊界等人說「好」;
- 用一句「要不要繼續?」把判斷推回給人。
## 四之二、每一張本地開的單都帶著號
沒有號的單排不進待辦、也沒有一個穩定的東西給別的單引用,而它會一直長出來,到某次盤點才
被一次找到一批。**號不需要人記,也不需要任何新的宣告**——開單那條路自己算:
```bash
bash .claude/skills/driving-work-to-done/scripts/next-ticket-number.sh \
--issues <單的根目錄> --namespace <命名空間>
```
判準是樹裡已經有的東西:**宣告了狀態解析器的命名空間,它的單來自外部系統**,號也一樣來自
那裡——本地鑄造一個出來,下一個人會拿它去那個系統搜,然後搜到別的東西或什麼都沒有。沒宣告
的命名空間,本地就是權威,取現有最大號加一。
**照著它算一個號再自己建目錄,是開單的第二條路。** 走這一條的話,上面〈手上正在做別的
事〉那幾件事沒有東西替你做——種類、6W、查重、判斷,四樣都要自己做完再建目錄。那一份說
清楚要做什麼的知識跟著這件工作落在誰身上走:落在這套流程自己身上的是
`framework-self-dev`。
所以「這件事該開在哪個命名空間」有一個乾脆的答案:**改框架本身的工作(skill、腳本、規則)
就是框架的工作**,即使它講的內容是某一家公司的;產品工作的單來自那家公司的系統,我們從來
不鑄造那種號。2026-08-08 有兩張改 `.claude/skills/` 的單因為「內容跟某家公司有關」被放進
那家公司的命名空間,於是它們永遠拿不到號。
## 四之三、一張單住在哪
**位置是狀態的投影,而 `--execute` 會把投影落地——但只落在它證明得了身分的那幾張上。**
重算算出每一張單該在哪一格,把那個答案寫進那張單自己的 `{單}/.spine/placement.json` 與人看
的那份清單,然後把**搬得動**的資料夾搬過去。
**搬得動要先證明,四項缺一就不搬**:這張單是鏈頂、身上有 `.spine/`、它的單號在整棵樹裡只有
一條路徑、目的地還不存在。任何一項不成立就留在原地,而報告會逐張說出卡的是哪一項。
四項各自擋掉一種真的發生過的事。DP-661 曾經把搬動整個拿掉,因為那一半自己製造了它要解決的
問題:一次沒搬完的搬動留下一個空殼,而那個空殼從此是同一個單號的第二條路徑,於是同一張單
有兩份 `placement.json` 說不同的話。**這一版不靠「搬得比較小心」把它擋回去**——擋回去的是
那四項先決條件,它們在搬之前就答得出來。
**搬動用檔案系統的更名,不是 `git mv`。** 單的那棵樹是好幾個工作階段共用的,而 `git mv` 會把
改動放進共用的索引,別人下一次送出就會把它一起帶走。更名之後 git 自己認得出改名,而索引一個
字都沒有被動過。
**路徑投影的是歸屬,格子投影的是鏈頂那張單的狀態。** 一張單有母單的話,它住在母單底下:
`{命名空間}/{格}/[{日期}/]{鏈頂}/…/{它自己}`,中間每一層都是一個單號。母單鏈有幾層就有
幾層,不並排成一層。
**子單不因為自己的狀態算到別的地方去。** 同一個母單底下的子單狀態各不相同是常態——各自
算一格的話,那個母單就被切成好幾塊,而它正是人拿來理解工作的單位。子單自己的狀態沒有消失,
它算得出來,寫在那張單的 `placement.json` 與人看的那份清單上。
**鏈上出現、樹裡還沒有的母單,重算逐張說出來,不補。** 以前它會把那些目錄造出來——而一個
只當路徑用、沒有內容的母單層,翻樹的人在它身上讀不到任何東西,機器又會把它算成一張單。
要不要開那張單是人的決定。
**單底下不是每一個目錄都是單。** 帶著 `.spine/` 的才是。少了這道判準,舊層留在單裡的那些
工作目錄會被一個一個算成單,然後被指名成一個不存在的重複。
**但「不是單」與「不要穿過去」是兩件事。** 不是單的目錄照樣要走進去看——樹上有一些只當路徑
用的中間層(沒有 `.spine/`、沒有正文,只有一個子單目錄,多半是過去那些搬動留下的),而在
那裡停下來的話,底下的單就永遠不進清單。那是一個會自己維持住的洞:孫單看不見 → 它的歸屬鏈
沒有人讀 → 孫單繼續看不見。2026-08-21 真樹上因此漏掉 19 張。
**位置是狀態的投影,不是第二個權威。** 一張單在哪一格由它自己的狀態算出來——所以要問「這張
單走到哪了」,讀那份紀錄,不要讀它躺在哪個資料夾。**手動把一張單搬到別處,下一次重算會把它
搬回狀態說的那一格**,而它搬不動的那幾張會留在原地並被指名。
**流程搬。** `record` 寫完輪次就重算一次,把每一張單該在的那一格算出來、寫回去、搬過去:
```bash
bash .claude/skills/driving-work-to-done/scripts/place-issues-by-state.sh --issues <單的根目錄> --check
bash .claude/skills/driving-work-to-done/scripts/place-issues-by-state.sh --issues <單的根目錄> --execute
```
**兩種模式的差別是寫不寫、搬不搬**:`--check` 什麼都不寫、也不搬,有落差就 exit 1;
`--execute` 把推導結果寫回每一張單、重寫清單,並把四項先決條件都成立的那幾張搬到算出來的
那一格。**推導結果跟上一次一樣的那些單,`--execute` 一個字都不寫**——每跑一次就把整棵樹的
時間戳全部改寫一次,弄髒的是共用的工作區,而那些檔案的內容一個字都沒有變。
**格子叫什麼不寫在散文裡。** 那份清單是那支腳本自己的,`--check` 會把每一格與各裝幾張印
出來。抄一份到文件裡就有兩個答案,而漂掉的那一刻沒有人在看。
推導出來的結果會寫回**單現在所在的那個目錄**(`{單}/.spine/placement.json`)——不是它「該
去」的那條路徑。所以一張單只有一份紀錄,而讀那份紀錄的程式走到單所在的地方就讀得到它。
位置給人看,那份紀錄給程式讀,
兩者同一次推導產出,所以不會有第二個答案。**任何要問「這張單收斂了沒」的程式讀那一份,
不准從資料夾名推狀態**——那條路徑一多一層資料夾就會靜靜地失效。
### 兩層推導,問不到就說出來
1. **走過主流程的單**:`{單}/.spine/loop-state.json` 就是權威,不需要問任何人。
2. **沒走過的**:問那個命名空間自己宣告出來的解析器。宣告長這樣,掃的是所有 skill 的
`SKILL.md`:
```
<!-- {任意前綴}-ISSUE-STATE-{命名空間}: {命令} -->
```
**核心不認得任何一個外部系統,也不認得任何一個外部狀態名。** 換一個地方只要換那一行。
順序不能反:主流程的答案是本地的、確定的,讓一趟網路往返有機會覆蓋它,等於把權威交給一個會
逾時的東西。**問不到不得讓重算說謊**——那些單落進「等人歸位」那一格並被指名「這次沒問到」,
不沿用上一次的答案,也不讓整支停掉。
兩層都問不到的目錄(主流程之前的舊層、還沒開輪次的種子)**不參與位置判定,留在原地**,但
數量每次都會被印出來——**那個數字由那一次重算自己印,不寫在散文裡**。把它們全掃進「等人
歸位」那一格會讓那一格裝進幾百張,而那一格存在的意義是「機器問過了、答不出來、等人歸位」,
一個沒人看得完的抽屜等於沒有這一格。一個不被判定的第三態如果安靜,下一次就會有人以為那些
目錄都被檢查過了。
### 終局那幾格
**做完了、出去了、不做了是三件事,不是同一件。**「不做了」以前沒有地方放,於是它要嘛永遠
躺在待辦裡被每一次〈四〉重新看過一遍,要嘛被人手動刪掉——而刪掉的那一張,下一次有人提出
同一件事時說不出「這討論過,結論是不做」。走進那一格的方式是上面〈二〉的 `close`。
終局那幾格底下多一層日期:任何終局都該知道時間,一格裝一百張只能照名字翻。查不出日期的
放進 `undated/`——把整理它們的那天填進去,會讓一個看得出來的空白變成一個看不出來的謊。
**但日期那一層不判定任何事。** 它是給人翻的,不是第二個權威——一張單走到哪一種終局,看的是
它自己的狀態與紀錄,不是它落在哪個資料夾。
`{單的根目錄}/OPEN.md` 是同一次重算產出的人看版本:所有還在中間態的單,逐張帶著它在哪一格、
位置依據什麼推出來、上次動過多久、是不是自己的單。**停滯只出現在那份清單上**——一張在同一
格待了兩個月的單,那一格就是它正確的位置,「這樣算不算太久」由看的人決定,不由門檻代人
搬走它。
## 五、載入領域知識:這類工作怎麼算 done
`refinement` 判完要立案之後,判斷這件工作屬於哪個領域,載入對應的知識,**並把載了什麼
記在單的狀態裡**。
| 這件工作 | 載入 |
|---|---|
| 會改到程式碼、要進版控 | `swe-knowledge` |
| 不會改程式碼(報告、調查、文件、資料分析) | 沒有適用的領域 |
領域的決定**就在開輪次那一步**,不是之後補的欄位。**這張單的改動會落在哪些地方也是**:
```bash
bash .claude/skills/driving-work-to-done/scripts/spine-loop-state.sh init \
--state {issue}/.spine/loop-state.json --pack swe-knowledge \
--where <工作區路徑> [--where <另一個>]...
bash .claude/skills/driving-work-to-done/scripts/spine-loop-state.sh init \
--state {issue}/.spine/loop-state.json --pack none --why '<為什麼這件工作沒有領域完成條件>'
```
`--where` 給幾次就是幾個地方,值是不透明字串——核心把它記下來,之後每次問路原樣交還給
領域的腳本去求值。**它不是「我現在站在哪」,是「這張單的改動會落在哪」**:一張單住在
`issues/` 而程式碼落在某個產品 repo 是常態,兩者不是同一個地方。宣告不出來就不開輪次,
因為從當下位置推出來的那一份對這種單永遠是錯的那一邊,而它之後每次比對都自洽。
需要知道這張單落在哪裡的時候讀這一支,**不要自己再推一次**:
```bash
bash .claude/skills/driving-work-to-done/scripts/spine-loop-state.sh landing \
--state {issue}/.spine/loop-state.json
```
DP-482 之前開的單狀態裡沒有這份宣告,問路會回 `unlanded`。補記(或在落腳處真的變了的時候
改記,改要帶人的原話):
```bash
bash .claude/skills/driving-work-to-done/scripts/spine-loop-state.sh land \
--state {issue}/.spine/loop-state.json --where <工作區路徑> [--authorization '<人的原話>']
```
`init` 還會跑那個領域宣告的**開工條件**——條件寫在 pack 自己的知識裡,核心只負責找到它、
跑它、不成立就拒絕開輪次。所以核心不認得任何一個領域的條件,換一個領域不用動核心。
它也會拒絕**在同一個地方開第二輪**:同一棵單的目錄樹裡已經有一張走到終局站別的單,而它記下的
身分與現在求出的有**任何一個交集**,就不開。交集就夠了——共用其中任何一個地方,新的一輪
就疊在別人的歷史上,最後只能一起出去。這件事 2026-08-03 真的發生過一次,三份交付紀錄釘在
同一個 head,而中間沒有任何一步說過話。拒絕訊息會指名是哪一張單、交集在哪,以及往下走的
兩條路(把那張單走完,或換一個工作區)。
中途要改判領域(做著做著發現它其實會動到程式碼)用這一支,它是覆蓋不是追加:
```bash
bash .claude/skills/driving-work-to-done/scripts/record-knowledge-pack.sh record \
--state {issue}/.spine/loop-state.json --pack swe-knowledge
```
**「沒有適用的領域」是一個被記下來的選擇,不是欄位空著。** 兩者在檔案裡長得不一樣,
在報告裡也要長得不一樣。
**指名的 pack 載不到就停,不要照常往下走。** 散文說「去載 X」而 X 不在,是完全安靜的:
routing 照樣把工作分派出去,只是分派到一份從未被讀取的程序。這個 repo 有過六支 skill
整段存在期間零載入而沒有人發現。`record-knowledge-pack.sh` 會拒絕一個解析不到 SKILL.md
的 pack 名字——它擋的就是這件事。
## 五之二、這一趟是誰在跑
`init`/`advance`/`record` 寫輪次狀態的時候,順手把「這一趟是誰在跑」記進
`{issue}/.spine/loop-state.json` 的 `holders[]`。**核心不認得任何一種對象**——它掃所有
`SKILL.md` 找這一行,跑它,把印出來的第一行原樣記下來:
```
<!-- {任意前綴}-ACTOR-IDENTITY: {命令} -->
```
形狀跟 `ISSUE-STATE-{命名空間}` 是同一套,但沒有後綴:「現在是誰在跑這一趟」只有一個答案,
而「這張單在哪一格」每個命名空間各有各的權威。**沒有人宣告是一個答案,不是壞掉**——那個
環境裡沒有東西回答得出這個問題,於是它記下這句話,往下走。
為什麼掛在這三個動作上:它們是流程走不過去就不能繼續的三步,所以「凡是走過流程的單都有」。
掛在一份自願寫的宣告上的話,覆蓋率就是「記得寫的那幾個」。
**不覆寫,逐個對象各佔一格。** 只有開輪次那一步寫的話,一張單換手之後那一格永遠是開單
的那個人;每次都覆寫的話,最後一個路過的人就成了「誰在做」。而覆寫的那一版連「不只一個
對象接著同一張單」都表達不出來——那正是要被看見的東西,不是要被收斂成一個的東西。
**推不出來的時候記下理由,不記一個空字串。** 空字串跟「沒有人接」在檔案裡長得一模一樣,
而它們要人做的事不同:一個是去看為什麼推不出來,一個是去找人接。
**這一格不判定任何事。** 它不改變任何一張單走到哪一站,也不是第二個回答「這張單在哪一格」
的地方——那個答案只有一個權威。誰讀它、怎麼印,是讀的那一端的事。
## 六、這一組東西要能整包搬走
`driving-work-to-done` + `refinement` + `engineering` + `verify-ac` + 領域 pack,複製到
另一個 repo 就能用。所以:
- **每一句指令都指向這一組 skill 目錄裡的東西**,不指向 repo 根目錄的腳本、常駐規則、
或任何 git hook。那些在 claude.ai 與 Cowork 不存在——而指過去的那一刻不會有人報錯,
只會安靜地讀不到。
- **不假設命名空間叫什麼**。`issues/{命名空間}/{單}/` 的中間那一段是誰決定的都不影響判定。
- **不假設領域**。核心的散文裡不出現只有軟體工程才成立的詞——它們屬於 `swe-knowledge`,
不屬於這裡。
**這三件事沒有關卡在守,是刻意的。** 以前有一道 `gate-layer-vocabulary` 掃三行宣告,
判「哪些詞不得出現在哪幾支 skill 的散文裡」——那是一段散文在規定另一段散文:它擋不住任何不可逆的事,
但每一次無關的改動都要付錢。判準留在這裡給寫的人讀,寫錯層的代價由「有人把那一層單獨
搬走的時候帶不動」承擔,不由一道關卡代人承擔。
三種寫錯層的方式:
- **核心的散文出現只有軟體工程才成立的詞**(branch、pull request、merge、CI、deploy)。
唯一的例外是凍結用的 `git commit`:凍結的簽名就是那個 commit,跟領域無關。
- **反過來,核心自己的詞出現在某一個產品的知識裡**(停點怎麼分類、輪次狀態檔叫什麼)。
一支產品 skill 重講這些,那段話就不屬於它——它在別的產品也成立,複製過去的那一份會跟
這裡漂開。例外是**指過來**:說「這件事走 `driving-work-to-done`」是路標,不是複製;
判準是它有沒有自己重講一次那些詞的意思。
- **領域 pack 出現只有某一家公司才成立的東西**。公司樣式由每一家自己的
`workspace-config.yaml` 說了算,不在這裡抄第二份。
## 這裡不做的事
- **不判定達成**。那是 `verify-ac`,它有 oracle。
- **不決定量測命令**。那是 `engineering` 的活區。
- **不出貨**。交付紀錄寫成就是這條流程的終點,釋出尾段屬專案私有。
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!