Stage
概述
Stage 是一輪工程變更的串聯文件——它不是替代任何一個技能產出物,而是記錄每個技能產出了什麼、這些產出之間是什麼關係、以及這一輪變更的完整故事。
Stage 回答四個問題:
- 我們本來要做什麼?(MISSION + 應然文件)
- 實現工作如何被安全委派?(Task Contract 前向索引)
- 我們實際做成了什麼?(實然文件 + ADR)
- 為什麼會有差異?(應然 vs 實然差異 + 學習摘要)
STAGE.md
(串聯層 / 索引 + 敘事)
│
┌────────┬────────┬────┴────┬────────────┬────────┬────────┐
│ │ │ │ │ │ │
MISSION 應然文件 實現計畫 Task Contract 實然文件 驗證
(目標) (設計) (plan+todo) (委派邊界) (結果) (證據)
│
ADR
(強制,每個 Stage 至少一篇)
何時使用
Stage 建立完全由使用者決定。 僅在使用者顯式請求時建立,無自動觸發條件。
使用者通常以以下方式發起:
- "建立 Stage" / "開始一個 Stage"
- "為這輪工作建 Stage"
- "封版 Stage" / "Seal Stage"
/plan輸出計畫後,使用者對"是否需要 Stage 文件?"回答"是"
典型適用場景(供使用者參考,非觸發規則):
- 跨越多個任務、構成一個邏輯整體的變更
- 跨越多個模組的新功能
- 改變內部結構但行為不變的重構
- 生產環境缺陷的完整修復鏈
- 需要記錄架構決策的任何變更
不會自動觸發:
- 單個孤立任務或機械性變更不自動建立
- 純文件更新不自動建立
- Agent 不會根據任務數量或跨模組程度自行判斷——必須使用者確認
delegated-task-contract 需要所屬 Stage 時也不得自動觸發 Stage 建立;如果尚無 Stage,它必須停下並請求使用者顯式決定。目錄歸屬、單向索引、狀態同步和封版門禁統一遵循 Stage 與 Task Contract 聯動規則。
Stage 類型
| 類型 | 動機 | 成功標準 | 應然 vs 實然 | 文件重心 |
|---|---|---|---|---|
| feat | 添加新能力 | 新行為出現且符合規範 | 有差異是正常的,必須記錄 | spec + api-contract + api-doc |
| opt | 改善已有行為 | 指標達到目標值 | 簡要記錄最佳化效果對比 | 效能基線 + 最佳化結果 |
| debug | 修復錯誤行為 | 問題不再復現 + 回歸測試覆蓋根因路徑 | 應然=實然(修復即目標) | 現象 + 根因 + 修復策略 + 預防措施 |
| refactor | 改變內部結構,行為不變 | 所有已有行為保持不變,回歸測試全綠 | 應然=實然是硬性要求 | 架構設計 + 結構變更說明 |
Stage 生命週期
/plan 輸出後 實現過程中 全部實現完成後 /ship 執行時
│ │ │ │
▼ ▼ ▼ ▼
建立骨架 維護文件與 Contract 索引 封版 STAGE.md 檢查 Stage 存在
(MISSION + (狀態、偏離、證據摘要) (終態門禁、實然文件、 (pre-launch
應然文件路徑、 ADR、差異分析、 checklist
實現計畫連結) 驗證結果、學習摘要) 阻斷項)
建立(骨架階段)
在 /plan 輸出 tasks/plan.md 和 tasks/todo.md 後,Agent 詢問使用者是否需要 Stage 文件。使用者確認後:
- 建立
stages/<stage-id>/目錄(stage-id為 kebab-case 簡短標題) - 建立
STAGE.md骨架,預填:- 類型(feat | opt | debug | refactor)
- 狀態設為
draft - 決策者
- MISSION(從 spec 中提取)
- 應然文件路徑(標記為 TODO)
- 實現計畫連結(填入
tasks/plan.md和tasks/todo.md) - Task Contracts 前向索引表(初始為空)
- 實然文件(標記為 TODO——實現完成後填寫)
- ADR(標記為 TODO——每個 Stage 至少一篇,實現完成後填寫)
- 驗證結果(標記為 TODO)
- 在
stages/INDEX.md中追加一行
填充(建構階段)
在實現過程中:
- 普通任務完成時無需修改
STAGE.md;但 Contract 首次落盤、狀態變化或回傳 deviation / evidence 時必須同步 - 當應然文件(spec、api-contract)產出時,更新對應連結,去掉 TODO 標記
- Contract 只由
STAGE.md前向索引;不要在 Contract 中添加 Stage 欄位或回鏈 - 非
none的 Contract deviation 同步到"應然 vs 實然差異"表,不等到封版時憑記憶補寫
封版(完成後)
所有任務完成且驗證通過後,Agent 提醒使用者封版。使用者確認後:
- 對照
task-contract/與索引表,確認沒有遺漏、失效連結或狀態漂移 - 確認所有 Contract 正文狀態均為
COMPLETED或CANCELLED;任一DRAFT、READY或BLOCKED_BY_ARCHITECTURE都會阻止封版 - 填充實然文件連結(api-doc、ADR)
- 填寫應然 vs 實然差異表(含"是否回溯更新應然文件"列),納入 Contract 報告的有意義偏離
- 填寫驗證結果並連結 Contract 的 Required Evidence
- 提煉學習摘要("下次這樣做"和"下次別這樣做")
- 狀態改為
done - 更新
stages/INDEX.md對應行狀態
檢查(發布前)
/ship 的 pre-launch checklist 中包含:
- "□ 重大變更是否有對應的 Stage 文件?"——如果本輪工作曾建立 Stage,此為阻斷項
Stage 模板
以下是 stages/<stage-id>/STAGE.md 的規範模板:
# Stage: [簡短標題]
**類型**: feat | opt | debug | refactor
**日期**: YYYY-MM-DD — YYYY-MM-DD
**狀態**: draft | in-progress | done | abandoned | superseded | split
**決策者**: @username
---
## MISSION(本輪目標)
<!-- feat / opt / refactor 使用標準 MISSION -->
- **目標**: [一句話描述本輪要達成什麼]
- **使用者**: [誰會受益]
- **成功標準**: [如何知道完成了——具體、可驗證的條件]
- **約束**: [綁定限制——技術、資源、時間]
- **不做**: [顯式排除的內容及原因]
<!-- debug 類型替換為以下結構:-->
<!--
- **現象**: [使用者做了什麼、看到了什麼、應該看到什麼]
- **影響**: [影響範圍、持續時間、資料完整性風險]
- **根因假設**: [初步判斷——實現完成後更新為確認根因]
- **修復策略**: [止血方案 + 根因修復 + 預防措施]
- **成功標準**: [問題不再復現、回歸測試覆蓋根因路徑、同類問題有靜態檢查]
-->
→ 詳見 [MISSION.md](./MISSION.md)
---
## 應然文件(我們計畫怎麼做)
| 文件 | 來源技能 | 說明 |
|------|---------|------|
| [spec/xxx.md](./spec/xxx.md) | spec-driven-dev | 功能規範 |
| [design/api-contract.md](./design/api-contract.md) | api-and-interface | API 契約 |
| [design/xxx.md](./design/xxx.md) | — | [補充說明] |
> 實現開始前填充。若某類文件本輪不涉及,刪除對應行。
---
## 實現計畫
| 文件 | 來源技能 | 說明 |
|------|---------|------|
| [tasks/plan.md](./tasks/plan.md) | planning-and-task | 技術方案 |
| [tasks/todo.md](./tasks/todo.md) | planning-and-task | 原子任務列表 |
---
## Task Contracts(委派執行邊界)
> 僅索引需要 `delegated-task-contract` 門禁的可寫委派。Contract 正文、狀態和 Required Evidence 以對應檔案為準;本表只儲存前向連結與摘要,不把 Stage 回鏈寫入 Contract。
| Task | Contract | 狀態 | Deviation / Evidence |
|------|----------|------|----------------------|
| [Task ID] | [Task ID](./task-contract/TASK-XXX.md) | DRAFT \| READY \| BLOCKED_BY_ARCHITECTURE \| COMPLETED \| CANCELLED | [阻斷、偏離、證據或取消原因;無則寫 `—`] |
> 尚無 Contract 時保留表頭並刪除範例行。Contract 首次落盤及每次狀態、偏離或證據變化後同步本表。
---
## 實然文件(我們實際做成了什麼樣)
> 實現完成後填充本節。
| 文件 | 來源技能 | 說明 |
|------|---------|------|
| [docs/api/xxx.md](./docs/api/xxx.md) | documentation-and-adrs | 實際 API 文件 |
| [docs/adr/XXX-title.md](./docs/adr/XXX-title.md) | documentation-and-adrs | 架構決策記錄(必填,每個 Stage 至少一篇) |
### ADR(必填)
每個 Stage **必須**產出至少一篇 ADR。ADRs 記錄關鍵的架構決策及其上下文。
| ADR | 決策內容 | 替代方案 |
|-----|---------|---------|
| [ADR-XXX](./docs/adr/XXX.md) | [一句話描述決策] | [被拒絕的方案及原因] |
**ADR 內容要求:**
- 記錄"為什麼選擇 A 而不是 B"
- 列出被考慮並拒絕的替代方案及拒絕原因
- 描述決策的約束條件和後果
- 如果該決策與已有 ADR 相關,顯式引用
**不同類型 Stage 的 ADR 重心:**
| Stage 類型 | ADR 典型內容 |
|-----------|-------------|
| **feat** | 為什麼選這個架構/框架/協定;資料模型的設計取捨 |
| **opt** | 為什麼選這個最佳化策略;為什麼不選其他方案(如快取 vs 索引最佳化) |
| **debug** | 根因為什麼會產生;為什麼選這個修復方案;預防措施的設計 |
| **refactor** | 為什麼選這個新結構;為什麼不統一某些邊界情況;新舊結構的對比 |
---
## 應然 vs 實然差異
> 實現完成後填寫。記錄計畫與實際之間的每個有意義的偏離。
Contract 的 `Required Evidence` 報告非 `none` deviation 時,在驗收該 Contract 的同時把偏離同步到本表;不要只在 Contract 中留痕。
| 差異 | 應然(計畫) | 實然(結果) | 原因 | 是否回溯更新應然文件 |
|------|------------|------------|------|-------------------|
| [簡述] | [計畫怎麼做] | [實際怎麼做] | [為什麼偏離] | 是 / 否 |
**"是否回溯更新應然文件"列說明:**
- **是**:該差異被認定為正確的設計方向,已回頭修改 spec 或 api-contract 使其與實然一致
- **否**:該差異是臨時妥協或折中,應然文件保留原樣以便後續 Stage 參考
- 所有標"否"的差異行是下一輪 backlog 的候選輸入
---
## 驗證結果
| 檢查項 | 狀態 | 證據 |
|--------|------|------|
| [驗收標準 1] | ✅ / ❌ | [測試報告、效能資料、截圖等] |
| [驗收標準 2] | ✅ / ❌ | [證據] |
| 無回歸 | ✅ / ❌ | CI 運行連結 |
→ 詳見 [VERIFY.md](./VERIFY.md)
---
## 學習摘要
> 封版時填寫。不超過兩句話。
- **下次這樣做**:[本輪做對了什麼——值得在其他 Stage 中複用]
- **下次別這樣做**:[本輪做錯了什麼——應該避免、警惕或改進]
---
## 關聯
- **上一輪 Stage**: [STAGE-XXX](../stage-XXX/STAGE.md)(或"無")
- **下一輪計畫**: [簡述,或"無"]
增量(封版後追加)
Stage 封版(狀態變為 done)後,如果發現小問題需要修補,但不構成一個新的 Stage,可在 STAGE.md 末尾追加增量章節:
---
## 增量 1(2026-07-28)
- **變更**: [簡述修補了什麼]
- **原因**: [為什麼封版後還需要這個修補]
- **影響範圍**: [哪些檔案/模組]
追加增量時:
- Stage 狀態保持
done,不退回in-progress - 增量條目按時間順序追加
- 如果修補涉及新的 ADR 決策,追加到實然文件的 ADR 表中並標註
[增量 1] - 累計 3 個以上增量時,考慮是否應該新建一個 Stage 而非繼續追加
INDEX.md
stages/INDEX.md 是所有 Stage 的導航入口。每個 Stage 建立和封版時維護。
# Stage 索引
| ID | 標題 | 類型 | 狀態 | 涉及模組 | 日期 |
|----|------|------|------|---------|------|
| 001 | raft-election-optimization | opt | done | consensus, rpc | 2026-07-15 — 2026-07-17 |
| 002 | wal-checksum-verification | feat | done | storage, wal | 2026-07-18 — 2026-07-20 |
| 003 | replica-sync-refactor | refactor | done | replication, net | 2026-07-22 — 2026-07-23 |
| 004 | multi-az-placement | feat | abandoned | placement, scheduler | 2026-07-23 |
維護規則:
- Stage 建立時追加一行,狀態為
draft - Stage 封版時更新狀態為
done - Stage 狀態變為
abandoned、superseded或split時同步更新 涉及模組列出受影響的頂層模組/目錄,便於按模組檢索
狀態模型
| 狀態 | 含義 | 何時使用 |
|---|---|---|
draft | 骨架已建立,實現尚未開始 | Stage 建立後 |
in-progress | 正在實現中 | 實現期間(可選使用) |
done | 按計畫完成,已封版 | 所有任務完成、驗證通過、學習摘要已寫 |
abandoned | 中途放棄 | 方向錯了、需求取消、被更高優先級打斷 |
superseded | 被另一個 Stage 覆蓋 | Stage-B 的範圍吞掉了 Stage-A |
split | 拆分成了多個更小的 Stage | Stage 過大,拆分為獨立子 Stage |
abandoned 的處理:
- 更新 MISSION 章節,追加一段"放棄原因"
- ADR 表中至少保留一篇,記錄"為什麼不繼續做"
- 學習摘要照常填寫——放棄的教訓往往比成功的更有價值
- 被放棄的 Stage 中已完成的部分程式碼/文件是否需要回滾,由決策者決定並在 ADR 中記錄
關聯章節的"下一輪計畫"改為"無(已放棄)"
superseded 的處理:
- 更新 MISSION 章節,追加一段"被哪個 Stage 取代及原因"
- 在
關聯章節添加"被取代於: STAGE-XXX" - 狀態改為
superseded - 不在被取代的 Stage 上繼續追加增量——所有後續工作轉移到取代它的 Stage
split 的處理:
- 更新 MISSION 章節,追加一段"拆分為哪些子 Stage 及原因"
- 在
關聯章節添加"拆分為: STAGE-XXX, STAGE-YYY" - 狀態改為
split - 原始 Stage 不再追加增量——所有工作轉移到子 Stage
目錄結構
stages/
INDEX.md ← 索引,每行一個 Stage
001-raft-election-optimization/
STAGE.md ← Stage 串聯文件
MISSION.md ← 詳細目標描述(可選,複雜專案推薦)
spec/ ← 應然:功能規範
design/ ← 應然:協定契約、資料佈局
tasks/
plan.md ← 實現計畫
todo.md ← 任務列表
task-contract/ ← 委派執行邊界,與 tasks/spec 平級
TASK-001.md
TASK-002.md
docs/
protocol/ ← 實然:協定文件、RPC 介面
adr/ ← 實然:架構決策記錄(必填)
verify/ ← 驗證證據
fault-injection-report.md
consistency-check.txt
perf-before-after.json
002-wal-checksum/
...
...
除 Task Contract 的歸屬路徑外,目錄結構是推薦範式。核心約束是:STAGE.md 必須存在,每個 Stage 至少包含一篇 ADR;如果存在 Task Contract,它必須位於該 Stage 的
task-contract/下並由STAGE.md前向索引。
與其他技能的互動
| 技能 | 互動方式 |
|---|---|
| spec-driven-development | Stage 的 MISSION 從 spec 的 Objective 提取 |
| planning-and-task-breakdown | /plan 輸出後,Agent 詢問是否建立 Stage 骨架 |
| delegated-task-contract | Contract 儲存到當前 Stage 的 task-contract/;STAGE.md 單向索引其狀態、偏離和證據,Contract 不反向索引 Stage |
| api-and-interface-design | 應然文件中的協定契約(gRPC/protobuf)和實然文件中的介面文件都連結到 Stage |
| failure-injection-testing | 涉及容錯與故障復原時,故障注入方案和混沌實驗報告連結到 Stage 實然文件 |
| consistency-and-durability-verification | 涉及儲存或狀態複製時,一致性/持久性校驗報告連結到 Stage 驗證結果 |
| 智慧體原生實現流程 | 全部任務完成並驗證後,Agent 提醒封版 Stage |
| documentation-and-adrs | ADR 是 Stage 的必填產出;每個 Stage 至少一篇 |
| shipping-and-launch | /ship 檢查 Stage 是否存在(本輪曾建立則阻斷) |
常見合理化藉口
| 合理化藉口 | 現實 |
|---|---|
| "這輪改動太小,不需要 Stage" | 如果改動小到不需要 Stage,那它可能也不需要 ADR。但使用者已經決定建立 Stage——相信使用者的判斷。 |
| "需求太簡單,應然和實然不會有什麼差異" | 差異無所不在——即使最簡單的變更也可能在實現中偏離計畫。Stage 的核心價值恰好是記錄這些差異。 |
| "先把程式碼寫了,Stage 之後補" | 封版前的 Stage 是活的目錄,不需要一次性寫完。但事後補寫意味著差異分析依賴記憶——記憶是不可靠的。 |
| "這個不需要 ADR" | 每個 Stage 都有至少一個值得記錄的決策——哪怕只是"我們選擇了最簡單的實現方式,因為當前約束不允許更複雜的方案"。 |
"已經 abandoned 了,學習摘要沒意義" | 放棄的教訓往往比成功的更有價值。記錄"為什麼放棄"至少和記錄"為什麼成功"同等重要。 |
| "差異表裡標'否'就夠了,不需要解釋" | 差異表的每一行都是未來決策的輸入。標"否"的行告訴下一個接手的人"這裡有技術債,而且是有意留下的"。 |
| "INDEX.md 可以以後補" | INDEX.md 的價值隨 Stage 數量增長——第一個 Stage 時不覺得,第十個時就成了必需品。從一開始就維護。 |
紅旗警告
- 建立了 STAGE.md 但 MISSION 為空——骨架的價值在 MISSION,沒有目標的 Stage 只是佔位符
- 實然文件有 API 文件但沒有對應 ADR——違反了"每個 Stage 至少一篇 ADR"的規則
- 差異表為空但使用者提到過實現中的偏離——差異沒有被捕獲
- 學習摘要寫"無"或"一切順利"——每個 Stage 都有教訓,找不到說明反思不夠深
abandoned的 Stage 沒有"放棄原因"——遺失了最有價值的資訊- INDEX.md 中某行長期處於
draft狀態——要么推進實現,要么標記為abandoned,不要讓骨架腐爛 - 增量章節累計 3+ 條但未考慮拆分新 Stage——說明本輪範圍判斷有誤,應反思而非繼續追加
- 決策者欄位為空——多人協作時這會導致決策追溯鏈斷裂
task-contract/中存在未被STAGE.md索引的檔案,或索引連結指向不存在的 Contract- Contract 狀態、deviation 或 evidence 已變化,但 Stage 表格仍保留舊摘要
- Contract 反向連結
STAGE.md,導致所屬關係被雙向維護 - 仍有
DRAFT、READY或BLOCKED_BY_ARCHITECTUREContract 就把 Stage 標記為done
驗證
建立 Stage 骨架後:
-
stages/<stage-id>/STAGE.md存在 - Stage 類型(feat | opt | debug | refactor)已填寫
- 狀態為
draft - 決策者已填寫
- MISSION 已填寫(標準格式或 debug 格式,根據類型選擇)
- 實現計畫連結指向
tasks/plan.md和tasks/todo.md - "Task Contracts(委派執行邊界)"章節和空的前向索引表已建立
-
stages/INDEX.md已追加對應行
封版 Stage 後:
- 實然文件連結已填充
- ADR 至少一篇,已連結到實然文件表
- 應然 vs 實然差異表已填寫(無差異則顯式寫"無差異"並簡要說明原因)
- 差異表中每行都標了"是否回溯更新應然文件"
- 驗證結果表已填寫,每個檢查項有狀態和證據
-
task-contract/中每份 Contract 都被前向索引,且 Contract 中沒有 Stage 欄位或回鏈 - 索引映像狀態與 Contract 正文一致,所有 Contract 均為
COMPLETED或CANCELLED - Contract 的 deviation、完成證據和取消原因已同步到對應摘要或差異章節
- 學習摘要已填寫(兩句話,非空泛)
- 狀態改為
done(或其他終態) -
stages/INDEX.md對應行狀態已同步更新