Living Docs
將文件視為一個與程式碼保持同步的活系統,而不是一個寫一次就腐化的成品。這項紀律的核心是一條主幹——每個知識點恰好有一個歸宿,該歸宿被索引,且沒有文件就不得進行結構性變更——以及多種依附於此的文件類型:一份憲法、ADR、BDR、PRD、議題、研究、架構圖和一個語義上下文索引。
此技能與技術棧無關。它管轄的是文件如何被組織與維護,而非專案使用什麼技術。
核心不變量 (主幹)
這些不變量適用於所有文件類型。其餘都是細節。
- 文件優先。 在將內容發布到任何外部平台(工單系統、維基)之前,先在儲存庫中撰寫主體(
docs/…)。儲存庫檔案是事實的來源;外部副本是鏡像。 - 每個事實一個歸宿。 每個概念、決策或需求只能存在於一個檔案中。禁止重複——透過交叉引用而非複製。複製的文字就是等待發生的漂移。
- 未索引即不存在。 每個文件都必須能從索引中觸及(一個
index.md列表在其目錄中,以及專案指南連結的根目錄docs/index.md)。不允許孤兒檔案。 - 取代,永不改寫歷史。 決策和需求是僅能附加的記錄。當某些事物改變時,標記舊記錄為「已被取代」並撰寫新記錄——絕不偷偷編輯過去。
- 沒有文件,不得進行結構性變更。 新增模組、移動檔案、變更綱要、新增資料流 → 在同一項變更中更新相關文件及其圖表。不允許「之後再補文件」。
如有疑問,請從這五條不變量重新推導出正確的行動。以下的規則檔案只是將這些不變量應用於每種文件類型。
格式:符合 OKF 規範
五項不變量管轄組織與生命週期;而開放知識格式則管轄檔案格式,以確保文件集具有可移植性且可被代理解析。系統中的每個文件同時也是一個 OKF 概念。在撰寫或檢查格式時,請載入 okf-knowledge-format 技能(它會提供規範)。
OKF 是一個輕量、可替換的依賴項——並非基礎(存在版本風險)。 OKF 是 v0.1 且來自單一供應商;向後不相容的 v0.2 是真實可能發生的。上述的不變量 不依賴於 OKF——它們僅依賴於一小組 frontmatter 欄位,因此 OKF 的故障不會連帶影響治理層。請明確區分邊界:
- Living Docs 所需的(事實合約
scripts/lint-docs.sh會強制執行):一個非空的type,以及在已取代記錄上的status+superseded_by。這些是我們擁有的;它們 無論 OKF 如何變化都會保留。- 繼承自 OKF(格式慣例):保留的
index.md/log.md、套件根目錄的okf_version、相對於套件的連結、# References標題(§8)。如果 OKF 改變,只有 這一行會受到影響——在okf-knowledge-format技能中重新固定版本並調整。
兩條規則適用於每個概念檔案:
- 帶有必填
type的 Frontmatter。 每個非保留的.md文件都以一個 YAML frontmatter 區塊開頭,其type指定了文件種類(Constitution、PRD、ADR、BDR、Issue、Context、Architecture View、Research、Reference)。建議使用:title、description、tags、timestamp。Living-docs 新增了生產者金鑰:status、supersedes、superseded_by。狀態移至 frontmatter——不再有**Status:**主體行。 - 保留檔案 + 相對於套件的連結。 套件根目錄為
docs/。目錄列表為index.md(OKF §6,無 frontmatter——除了套件根目錄的docs/index.md,它帶有okf_version: "0.1")。可選的log.md記錄目錄歷史(§7)。使用以/前綴的套件相對路徑進行交叉連結(/adr/0007-slug.md);在# References標題(§8)下列出來源,每個條目按rules/citation-conventions.md格式化——ABNT NBR 6023 結構,務必攜帶連結,並使用專案文件語言中的連接性標籤(預設為英文:Available at: <URL>. Accessed on: <date>),詳見rules/doc-language.md。
文件鏈
每項變更都遵循此鏈結,從基本的事實來源向下到程式碼:
flowchart LR
C[constitution] --> P[PRD]
P --> A[ADR]
P --> B[BDR]
A --> I[issues]
B --> I
I --> K[code]
| 產物 | 角色 |
|---|---|
| constitution | 基本的事實來源:產品是什麼、核心資料模型、不可協商的事項。所有其他文件都隸屬於其下。 |
| PRD | 系統必須做什麼以及為什麼——功能/產品需求規格。 |
| ADR | 系統如何被建構——架構/實作決策及其理由。 |
| BDR | 系統必須可觀察地做什麼——輸入、輸出、副作用、Given/When/Then 場景——以及每個場景如何被測試(測試設計矩陣;「如何測試」的單一歸宿,一個執行議題會連結它)。 |
| issues | 執行切片——可追溯到 ADR/BDR 的離散工作單元。 |
| code | 實作——上述所指定的每一個行為、結構和介面,都已實現。 |
何時啟用
- 為專案建立文件(建立
docs/結構、文件索引、ADR/問題/BDR/憲法目錄)。 - Living-docs 首次在專案中執行(專案指南中無
## Living Docs區塊)→ 詢問強制模式問題並保存答案 → 請參閱強制模式。 - 在現有/棕地專案中採用 living-docs(決策已做出但未記錄)→ 遵循程序 → 在現有專案中採用 living docs:盤點決策,在記錄任何 ADR 之前先與使用者確認,絕不單靠推論回填。
- 撰寫或編輯ADR(架構/實作決策)→ 載入
rules/adr-conventions.md+templates/adr.md。 - 撰寫或編輯PRD(產品/功能需求規格)→ 載入
rules/prd-conventions.md+templates/prd.md。 - 撰寫或編輯BDR(可觀察行為——輸入、輸出、Given/When/Then 場景,以及每個場景如何被測試的測試設計矩陣)→ 載入
rules/bdr-conventions.md+templates/bdr.md。一個測試策略決策(非預設層級/技術、基準偏差)是一個帶tags: [testing]的 ADR,而非新的記錄類型(沒有「TDR」)。 - 指定非功能性需求(效能、可用性、安全性、規模)→ 一個品質屬性場景,綁定到 PRD 中的一個衡量工具(
rules/prd-conventions.md規則 9 +templates/prd.md);該決策 + 適合度函式放在一個 ADR 中。非新的文件類型。 - 建立或修訂憲法(基礎範圍、資料模型、不可協商的事項)→ 載入
rules/constitution-conventions.md+templates/constitution.md。 - 建立或編輯議題/工單 → 載入
rules/issue-workflow.md+templates/issue.md。 - 記錄研究(技術評估、外部權衡)→ 載入
research-artifacts技能。它擁有 OKF 研究筆記格式(每個筆記單一檔案,無按研究建立的子資料夾)、來源紀律以及研究 → 決策 → 議題的可追溯鏈結,並連結回這裡以取得 ADR/BDR/議題產物。與deep-research技能搭配使用。 - 繪製或更新架構、資料流或工具呼叫圖表 → 載入
rules/architecture-diagrams.md+templates/architecture-index.md。 - 定義文件中使用的術語或縮寫 → 將其新增至詞彙表(
docs/context/glossary.md),每個術語一個歸宿 → 載入rules/glossary-conventions.md+templates/glossary.md。 - 文件變得太大或關注點混合 → 拆分為語義索引 → 載入
rules/semantic-index.md+templates/context-index.md。 - 在任何結構性變更後強制執行無漂移維護規則 → 載入
rules/maintenance-invariant.md。 - 撰寫或檢查任何文件的OKF 格式(frontmatter
type、保留的index.md/log.md、相對於套件的連結、# References)→ 載入okf-knowledge-format技能。 - 決定文件的書寫語言(預設為英文;使用者可以在工作階段開始時覆蓋並鎖定)→ 載入
rules/doc-language.md。
文件對應表
| 類型 | 位於 | 目的 | 可變性 |
|---|---|---|---|
| 專案指南 | CLAUDE.md / README.md(根目錄) | 進入點:範圍、技術棧、文件索引、強制性工作流程 | 活躍——自由編輯 |
| 憲法 | docs/constitution.md | 基本的事實來源:產品範圍、資料模型、不可協商的事項 | 批准後僅能附加(修訂日誌) |
| 上下文索引 | docs/context/index.md + 分組檔案 | 領域與模組詞彙,語義分組 | 活躍——自由編輯 |
| 詞彙表 | docs/context/glossary.md | 術語與縮寫定義一次,使用文件語言(縮寫詞條保留原樣) | 活躍——自由編輯 |
| 架構 | docs/architecture.md 或 docs/architecture/ + 索引 | 活的 Mermaid 圖表:結構、資料模型、流程、工具呼叫 | 活躍——必須與程式碼匹配 |
| ADR | docs/adr/NNNN-slug.md | 一個架構/實作決策 | 僅能附加(取代) |
| BDR | docs/bdr/NNNN-slug.md | 一個可觀察行為決策 | 僅能附加(取代或修正) |
| PRD | docs/prd/NNNN-slug.md | 一個功能/產品需求規格 | 接受後僅能附加 |
| 議題 | docs/issues/NNNN-slug.md | 工單系統鏡像(主體),每個工單一個 | 主體可編輯;已發布副本隨之更新 |
| 研究 | docs/research/NNNN-<slug>.md(單一檔案,無子資料夾;序號開頭,日期在 frontmatter timestamp 中;以 # References 結尾) | 附有來源的外部證據 | 僅能附加(證據有日期) |
每個目錄都帶有其自己的 index.md 列表(OKF §6,無 frontmatter)。專案指南的「文件索引」連結到套件根目錄的 docs/index.md。索引合約請參閱 rules/semantic-index.md。
程序
在新專案中設定 living docs
- 詢問強制模式問題(請參閱強制模式 → 首次執行問題)在所有動作之前,因為尚未保存偏好設定。將答案記錄在專案指南的
## Living Docs區塊中;如果使用者沒有偏好,預設為strict。 - 建立專案指南(
CLAUDE.md或等效檔案),其中包含文件索引章節和維護規則章節(複製rules/maintenance-invariant.md中的措辭)。使用templates/claude-hard-rules.md作為專案指南硬規則章節的起點——它已經包含了## Living Docs強制區塊;在提交前填入佔位符。 - 建立
docs/及其專案所需的目錄(adr/、bdr/、issues/、prd/、research/、context/)。從templates/constitution.md中植入docs/constitution.md。新增套件根目錄的docs/index.md(帶有okf_version: "0.1"),並從第一天起就為每個目錄提供其自己的index.md列表——即使幾乎是空的。 - 用任何現有的領域詞彙植入上下文索引(
docs/context/index.md),並用文件已假設的術語和縮寫(rules/glossary-conventions.md)植入詞彙表(docs/context/glossary.md)。隨著概念的命名而發展兩者。 - 用系統已有的高層級 Mermaid 視圖植入架構文件(
docs/architecture.md)。一旦成長,升級為docs/architecture/目錄 + 索引(rules/architecture-diagrams.md)。 - 將任何已做出的決策記錄為 ADR,以避免重新爭論——但在記錄前先與使用者確認每一個(請參閱在現有專案中採用 living docs,步驟 3-5);絕不單靠推論來回填 ADR。
在現有專案中採用 living docs(棕地)
一個現有的程式碼庫已經體現了從未寫下來的決策。這裡的失敗模式是代理透過推論回填 ADR 並將其呈現為已定案——記錄了使用者從未被要求確認的決策。因此,採用是一個引出練習,而非抄錄練習。
- 詢問強制模式問題(首次執行)並保存
## Living Docs區塊,與新專案完全相同。 - 建立框架而不做決定。 建立
docs/+ 每個目錄的index.md、套件根目錄的docs/index.md,並從程式碼、README和代理指南(CLAUDE.md/AGENTS.md) 中已存在的詞彙植入詞彙表/上下文索引。這是機械性的——此處不做任何決定。 - 先閱讀現有上下文,然後盤點決策——作為候選項,而非記錄。 收集專案已有的內容:程式碼本身,加上
README、代理指南(CLAUDE.md/AGENTS.md)、套件清單以及任何設計註解或評論。從中產生一個列表,列出專案似乎體現的關鍵決策(技術棧、邊界、資料模型、主要權衡)。還不要撰寫 ADR。 - 將盤點結果呈現給使用者並確認每一項。 對於每個候選項,陳述推論出的決策以及它似乎已排除的替代方案,並要求使用者確認、更正或捨棄它——深入探討關鍵的決策(如果已安裝
grill-me)。使用者擁有決策權;代理僅是浮現程式碼所暗示的內容。 - 僅將已確認的決策記錄為 ADR。 這些是原始記錄——它們不取代任何東西。捕獲所選選項以及使用者已確認的被拒絕的替代方案。使用者捨棄的候選項,或者其理由實際上沒有人知道的候選項,不會被憑空創造為 ADR。
- 用系統已有的高層級 Mermaid 視圖植入架構文件(
rules/architecture-diagrams.md),然後繼續執行下面的維護循環。
維護 living docs(每次任務)
- 在編碼之前: 從專案指南中讀取
## Living Docs強制模式(如果該區塊不存在,則這是首次執行——詢問首次執行問題並保存答案)。然後讀取相關的憲法、ADR、BDR 和上下文索引。 - 針對變更範圍檢查文件: 你的任務是否觸及任何領域、模組或與文件相關的資料流?從相關的 ADR/BDR/PRD/架構圖中讀取相關部分。
- 在開始工作之前更新文件: 如果任務引入了一個新的決策或行為,草擬 ADR 或 BDR。如果任務改變了現有決策,草擬一個取代記錄(新的 ADR/BDR;別忘了
supersedes/superseded_by)。如果任務新增了資料結構或流程,更新架構圖。在提交任何程式碼變更之前完成此操作。 - 以文件變更作為程式碼工作的一部分進行編碼和提交。 程式碼變更和其文件變更位於同一個提交中——分開的提交表示「之後再補文件」。
- 最後執行 linter。 執行
scripts/lint-docs.sh(它檢查所有五項不變量——孤兒檔案、缺少的索引、缺少的 frontmatter、遺失的取代鏈)。在將工作標記為完成之前修復任何失敗。 - 如果這不是最終提交,請重複步驟 2-5。
強制模式
首次執行問題
以下問題必須在 living-docs 技能首次啟動時向使用者提出。詢問後,將答案記錄在專案指南的 ## Living Docs 區塊中。如果使用者不確定,預設為 strict。
「Living Docs 可以三種模式執行。
- strict ─ 任何偏離文件優先紀律(缺失的 frontmatter、孤兒檔案、缺少的取代鏈、缺少的索引)都會導致
scripts/lint-docs.sh(每當我檢查文件時會執行)中的硬性錯誤。這是預設值——它防止文件漂移。- advisory ─ linter 會輸出警告,但不會阻擋工作。當你希望逐步採用紀律而不中斷正在進行的工作時使用。
- off ─ 此專案中不檢查文件紀律。當專案不使用此技能時使用——例如,如果這是一個僅用於特定任務的一次性載入。
你想要哪個模式?」
模式行為
| 模式 | 行為 |
|---|---|
strict | 所有由 scripts/lint-docs.sh 檢查的非符合項目都會以非零狀態碼失敗。在我開始工作前,以及在最終提交前,我都會執行它。 |
advisory | 相同的檢查,但失敗輸出為警告。狀態碼始終為 0。 |
off | 不執行文件一致性檢查或維護。此技能僅在要求時提供範本。 |
## Living Docs 區塊應精確遵循此格式:
## Living Docs
- **模式:** strict
- **狀態:** 活躍