# Version Sequencing

> 版本序列規劃——規格完備後把待決清單收束為版本序列（每版一個整合測試），再開首版票。含 multi-round-review 完備檢查、切分軸選擇、待決 blockedBy 綁版本、地基先行開票。序列是順序不是閘門，不綁定完整敏捷。觸發詞：版本規劃、版本序列、整合測試順序、排版本、開票規劃、里程碑、milestone、roadmap。Use when 規格完成後、寫第一張實作票前。Do NOT use for 單一版本內的規劃波（用 version-bootstrap）。

- Skill: `tarrragon/version-sequencing` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tarrragon/version-sequencing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tarrragon/version-sequencing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- License: MIT
- Author: tarrragon (https://skillmd.com/u/tarrragon)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/tarrragon/version-sequencing

---


# Version Sequencing

規格完備之後、第一張實作票之前的全盤排序工作流。產物是一串**整合測試的順序**，以及首版的可派發票。每個版本對應一個整合測試，該測試全綠即版本完成。

它防的失效形態：使用者急著寫程式看結果，跳過整體規劃直接開工，功能之間的依賴在實作中才逐一撞見。

**版本層級用語**：中版本承載一個方向（對應一個整合測試），小版本是中版本內的修正。

## 四條不變量（本 skill 的全部承諾）

| # | 不變量 | 防什麼 |
|---|--------|--------|
| 1 | **每版一個整合測試作為完成定義** | 「這版好了沒」變成有客觀答案的問題，不是感覺題 |
| 2 | **序列是順序，不是閘門** | 開工不需要先想完所有情況；未預期的變體進小版本修正 |
| 3 | **延後的決策必須綁 ticket** | 待決事項有觀察者；「以後再說」不會變成永遠不會被觸發的清單 |
| 4 | **驗收斷言指名外部固定值** | oracle（判定對錯的標準答案）不在執行者手上；否則空實作也能讓驗收全綠 |

### 不變量 4 對散文型產物的落地形態

規格、提案、skill 這類散文產物沒有測試可跑，但仍適用不變量 4。對散文，外部固定值的形態是**可重跑的命令與其固定輸出**：

| 散文型驗收 | 不合格（oracle 在執行者手上） | 合格（外部固定值） |
|-----------|---------------------------|------------------|
| 這份文件審過了嗎 | 「三輪都完成了」 | frame 判定表逐格有記錄；每條 finding 附一條可重跑命令與其輸出 |
| 這個引用正確嗎 | 「確認過了」 | `test -f <path>` 為真；`grep -c <錨點> <path>` 非零 |
| 這個宣稱成立嗎 | 「查證屬實」 | `grep -c seed state-storage.md` = 0 |

**缺這個形態的後果**：沒有外部固定值可判定「審過了沒」，就沒有東西擋得住 push。本 skill 的第一步要求規格文件走審查，而規格文件正是散文；此形態未定義時，該要求無法被驗證是否履行。

### 不變量 2 的適用上限

**實作發現切分軸本身失效時（例如管線的某一段根本不存在），該回頭改序列，此時不適用不變量 2。** 判別問「這個發現推翻的是某一版的內容，還是版本之間的依賴」。前者進小版本，後者重排序列；兩者同時被推翻時以後者為準，因為依賴錯了，內容對不對已不重要。

附註：不變量 2 的前半（不必先清空待決）可由不變量 1 與 3 推出，每版有完成定義且待決有觀察者時，未清空的待決不會靜默消失。後半（未預期變體進小版本、不回頭改序列）是獨立承諾。

### 不變量 1 對小版本的適用

小版本是修正不是新能力，**不另立整合測試**，但必須有一條測試涵蓋它修的那個變體，併入所屬中版本的整合測試。該條測試由小版本票的驗收條件承載，未附此測試的小版本票不得完成。

**刻意不綁定完整敏捷流程。** 這四條與 scrum、sprint、story point 全部無關。把整套敏捷綁進來等於把方法論偏好硬編進工作流，而偏瀑布的使用者用這四條照樣成立。「中版本定方向、小版本做調整」可由四條推出，不是額外規則。

## 六步工作流

### 1. 規格完備檢查（必經 multi-round-review）

對全部規格文件執行 `multi-round-review` skill（至少三輪，frame 切換）。**這一步不可省**：審查的價值是把「本來就在、只是沒被寫下來」的待決事項拓出來，把文件改乾淨只是副產品。單輪或人工盤點會漏掉結構性不可見的三類：未被寫下的內容、跨篇皆未承接的前提、只在真實個案上才停住的判準。

**輸入集合**：專案的全部規格層文件。判準是「描述系統該做什麼、且下游會據以實作的文件」——提案、規格、使用案例、domain 邊界文件屬之；變更記錄、流程規範、建置指令不屬之（它們記做過什麼與怎麼做，不記該做什麼）。開始前先把清單列出來，審查範圍以此為準。

**frame** 指審查時採取的提問角度（例如事實查核、冷讀、情境可想像性、自我適用）。frame 切換指每一輪換一組角度，使各輪的 finding 不重疊。停止判準見 `multi-round-review` skill；做完的判準不是輪數，是停止訊號成立。

**產出契約**：待決清單，每項標明「它擋住哪一個能力」。沒有標阻擋對象的待決不算收束完成。清單需有持久載體（決策記錄文件或 ticket 皆可），且步驟 4 逐項取用時以該載體為輸入。留在對話中的清單在步驟 4 無法被取用，等同未產出。

### 2. 選切分軸

候選軸至少三個。下表即三個候選，可直接採用為候選集，但仍須比較後擇一，不得因表已列出而略過比較：

| 軸 | 特性 |
|----|------|
| **資料管線** | 與 domain 依賴圖同構。前一段綠了下一段才有輸入，「這版能不能開始」有客觀答案。多數專案的預設傾向 |
| 畫面 | 每版有可見成果，但每個畫面各自把整條管線帶起來，前幾版重複建同樣的地基 |
| 使用案例（UC） | 驗收條件現成，但 UC 之間共用大量基礎設施，切分邊界反覆重疊 |

預設傾向不豁免比較。專案形態（純後端、純工具、資料密集）會改變答案。

**比較工具**：`wrap-decision` skill（W 階段擴增選項 + premortem）。需結構化評分時改用 `design-decision-framework` skill。兩者目前彼此零引用，這是已知的框架缺口，不是讀者需要解決的分歧。

**最小合格產出**：選定的軸，加上未選中的各軸為什麼不選。不選的理由須各指名本專案的一個具體物件（哪個畫面、哪個 UC、哪一段管線）；只複述上表特性欄不算比較。

### 3. 版本序列落為提案

序列寫成一份提案文件（走專案的提案機制），每個版本三件事齊備：

| 欄位 | 內容 |
|------|------|
| 整合測試斷言 | 這版全綠的判準是什麼，**指名外部固定值**（真實語料的已知答案、可重跑的計數），不接受「執行者自己說做完了」 |
| 斷言來源文件 | 斷言取自哪份規格（狀態矩陣、事件契約……），使測試與規格互相追溯 |
| 阻擋清單 | 已知的未知。標明本地待決或外部依賴，**不要求開工前清空**（見不變量 2） |

**版本啟動閘門**：某版的提案缺整合測試斷言、或斷言未指名外部固定值時，該版不得開出任何實作票。這是不變量 1 的觀察者，形態是前置條件而非動作，因此不需要另一個觀察者來保證它發生。

首版是地基版，除非該版的提案不含任何地基產物。`foundation-design` skill 的產物票在「首版開票」那一步開出，功能票 `blockedBy` 它們。

### 4. 待決綁版本

步驟 1 的待決清單逐項綁到「它擋住的那個版本」，載體是 ticket 與 blockedBy。時間、量化閾值、外部事件都不是合法 trigger，須先包裝為 ticket（同專案的決策 trigger 綁定規則）。

外部依賴（上游 repo 的票）標為 external blocker，不混入本地待辦。**綁定方向**：建一張本地追蹤票，該票 `blockedBy` 外部依賴；受阻的版本再 `blockedBy` 該追蹤票。不要讓版本直接 `blockedBy` 外部物件，外部定案時沒有本地載體會浮現。

**為什麼不「現在一次全部解決」**：多項待決在沒有實作經驗前定不準，定完又改。**為什麼不「碰到再說」**：無觀察者的待決會持續無人觸發，直到以事故形式被動浮現。綁版本是兩者之間唯一有觸發機制的選項。

### 5. 首版開票

- 一票一事（atomic）：一個 action + 一個 target。標題含連接詞「與」「和」是拆分訊號
- 地基波（W1）先行，功能波（W2）內各票儘量互不相依、可並行。「波」指一批可同時開始的票，不是時間單位
- 票的 why 寫「這件事**為什麼難**」而非重述它是什麼。把步驟 1 審查的發現落進票面，執行者不必重走一次發現過程
- 驗收條件指名外部固定值（同步驟 3 的原則），並警惕「資料來源缺席時驗收反而更好過」的形態。對照函式永遠回空也能讓「逐項標記」類驗收全數通過

### 6. 序列維護

| 事件 | 動作 | 誰在何時檢查 |
|------|------|------------|
| 實作撞到規格未預估的變體 | 開**小版本**票修正並回填規格 | 撞到的執行者當場開票；事件自帶觸發，無須額外觀察者 |
| 外部依賴（external blocker）定案 | 回頭確認對應版本的阻擋是否解除、定案內容是否改變順序 | 步驟 4 建立的本地追蹤票，`blockedBy` 綁定使其定案時浮現 |
| 某版的整合測試遲遲無法定義 | 那是真阻擋，該版的前置待決此時才需要先做 | 步驟 3 的版本啟動閘門。斷言未就緒即無法開票，狀態本身即訊號 |

**「誰在何時檢查」欄必須填具體承擔者**（票、事件、或前置條件），不能填動作。動作不能保證自己發生。

## 與其他 skill 的分工

| skill | 關係 |
|-------|------|
| `multi-round-review` skill | 步驟 1 的必經工具 |
| `wrap-decision` skill | 步驟 2 的比較工具（含 premortem） |
| `foundation-design` skill | 地基票的**入口與內容來源**。它是路由層，逐維度決定本專案的地基產物是什麼；本 skill 在「版本序列落為提案」那一步決定這些票屬於哪一版，在「首版開票」那一步開出。**同一批票，兩邊不重複建** |
| `version-bootstrap` skill | **下游**。本 skill 產出版本序列與各版提案；version-bootstrap 執行該版的規劃波展開。其 pipeline 含本 skill 未涵蓋的步驟，交接後由它負責 |

**層名約定**：`foundation-design` 是**路由層**（指名權威、定每個維度的產物）；`version-bootstrap` 是**編排層**（在規劃流程的特定步驟安排執行）；本 skill 是**排序層**（決定各版順序）。三者不同名不同職。

**與 version-bootstrap 的交接契約**（三項，缺一則下游的強制檢查會空跑通過）：

| 交接物 | 本框架的位置 | 由誰寫入 | 誰在何時檢查 |
|--------|------------|---------|------------|
| 該版的提案清單 | `docs/todolist.yaml` 該版本的 `proposals` | 本 skill 步驟 3，於該版**啟動時**寫入 | 版本啟動閘門（步驟 3）：清單為空即不得開票 |
| 提案間的依賴 | `docs/proposals-tracking.yaml` 各提案的 `depends_on` | 本 skill 步驟 4 綁定待決時一併回填 | 步驟 4 的完成條件。**無依賴時須顯式寫 `depends_on: []` 而非留 `null`**，否則「確認無依賴」與「未回填」在下游輸出同形 |
| 提案的目標版本 | 同上的 `target_version` | 同上 | 同上。序列已定而此欄為 `null` 時，下游無從驗證排序矛盾 |

**為什麼「誰在何時檢查」欄不可省**：version-bootstrap 的跨提案依賴檢查讀 `depends_on` 比對 `target_version`。實測 `depends_on` 零筆的專案，該檢查回報 `[OK] 無跨提案依賴排序矛盾`、exit=0，與真正檢查過完全同形。回填未發生時沒有任何輸出會提醒。

**位置欄是本框架的慣例，不是契約本身。** 契約的內容是那三項資訊必須存在且可被下游讀取；專案的提案機制不是這兩個 yaml 時，等價安放即可。但不可省略，省略時下游不會報錯，只會空跑通過。

## 移植前置條件

本 skill 是**框架綁定**的：它以框架資產的路徑為主題，依賴的基礎設施不隨它移動（同 `version-bootstrap`、`ticket`、`doc`，皆不宣告 `portable`）。搬進新專案前確認：

- [ ] 有具 `blockedBy` 語意的 ticket 系統？步驟 4、5、6 全部依賴它
- [ ] 有提案機制（任何形式的持久文件）？步驟 3 的載體，也是版本啟動閘門的判定對象
- [ ] 有 `multi-round-review`？步驟 1 明示人工盤點會漏三類，無此 skill 時該風險由使用者承擔

**缺項時進入降級模式，並記錄降級。** 缺項與其後果記入該版提案的「阻擋清單」欄，並建一張補齊該基礎設施的票。缺 ticket 系統時不變量 3 無法成立（它要求綁 ticket），該版的待決管理退回無觀察者狀態，此事實須寫入阻擋清單。無降級記錄的使用不構成完成本流程。

## Examples

**待決按軸重排後阻擋消失（桌面文件視覺化專案）**：審查把待決從 5 項拓到 19 項，看起來全部擋在前面。按資料管線軸把每項綁到「它擋住的版本」後發現，前兩版（展示殼、來源判定 gate）完全不被任何待決擋住，可立刻開工；上游外部依賴只擋第三版之後。同一份清單，按文件來源看是 19 個阻擋，按管線看是兩個可動的版本。排序軸本身就是資訊。

**gate 版的整合測試以真實環境為斷言（同專案）**：第二版的測試斷言是「本機全部真實專案各自進入正確的 gate 分支」，答案由實測得出（非框架專案 N 個／無型別表 M 個／可載入 K 個）。這類斷言沒有省力路徑，數字是外部固定值，改錯即紅。

**切分軸失效而須重排（不變量 2 的適用上限，同專案）**：四層鏈 PROP→SPEC→UC→Ticket 按資料管線軸排版本，實作到第三跳時發現 UC→Ticket 在上游的 16 條語意邊中無對應邊，管線的某一段根本不存在。這推翻的不是某一版的內容，是版本之間的依賴，因此重排序列而非開小版本。

## Common Issues

| 症狀 | 原因 | 處置 |
|------|------|------|
| 待決清單越長越不敢開工 | 把序列當閘門，以為要先清空 | 逐項問「它擋住哪個版本的整合測試」。在現有序列涵蓋範圍內擋不住任何一版的就不是阻擋；若序列本身可能不完整，先回步驟 2 複查切分軸 |
| 這版做完了沒？收尾一再延後，或有人問「算完成了嗎」 | 完成定義不是整合測試，是感覺 | 回到不變量 1：沒有整合測試的版本不成立 |
| 實作中撞到一個問題，翻出待決清單發現三個月前就記過 | 待決無觀察者（違反不變量 3）。它的真實浮現形態是事故，不是有人定期翻清單 | 逐項補 blockedBy 綁定；綁不到任何版本的二者擇一：立刻決策，或自待決清單移除 |
| 首版開了十張票但互相卡死 | 地基與功能混在同一波 | 地基波先行；功能票 blockedBy 地基票，功能票之間儘量無相依 |
| 驗收全綠但功能其實沒做 | 驗收 oracle 在執行者手上；或資料來源缺席時反而更好過 | 驗收改為指名外部固定值；對「逐項標記」類驗收檢查空實作是否也能通過 |
| 檢查工具回報 `[OK]` 或「無問題」，但你不確定它有沒有讀到東西 | 「沒東西可檢查」與「檢查通過」在輸出上同形 | 確認被檢查的欄位或檔案非空；空集合的通過不是通過 |
| 同一段管線已經開了第三張小版本票 | 修的可能不是內容而是切分軸 | 由開該票的執行者觸發回步驟 2 複查切分軸（見不變量 2 的適用上限）|

---

版本紀錄在同目錄的 `CHANGELOG.md`。

