dflow-sdd-ddd 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +824 -1
  2. package/CONTRIBUTING.md +16 -10
  3. package/README.en.md +156 -200
  4. package/README.md +89 -144
  5. package/TEMPLATE-COVERAGE.md +15 -8
  6. package/TEMPLATE-LANGUAGE-GLOSSARY.md +15 -1
  7. package/bin/dflow.js +36 -4
  8. package/docs/commands.en.md +110 -0
  9. package/docs/commands.md +101 -0
  10. package/docs/doctor-uncertainty.en.md +212 -0
  11. package/docs/doctor-uncertainty.md +212 -0
  12. package/docs/evaluating-dflow.en.md +29 -11
  13. package/docs/evaluating-dflow.md +8 -6
  14. package/docs/npm-publish-checklist.md +3 -1
  15. package/docs/release-versioning-policy.md +8 -2
  16. package/docs/upgrading.en.md +196 -0
  17. package/docs/upgrading.md +197 -0
  18. package/docs/using-with-claude-code.en.md +25 -10
  19. package/docs/using-with-claude-code.md +20 -7
  20. package/docs/using-with-codex.en.md +18 -6
  21. package/docs/using-with-codex.md +16 -5
  22. package/docs/using-with-github-copilot.en.md +25 -10
  23. package/docs/using-with-github-copilot.md +21 -8
  24. package/lib/doc-shapes.json +997 -0
  25. package/lib/doctor-checks.js +2654 -0
  26. package/lib/init.js +3583 -107
  27. package/lib/render-diagrams.js +1474 -0
  28. package/lib/render.js +865 -49
  29. package/package.json +2 -2
  30. package/templates/brownfield/references/drift-verification.md +4 -0
  31. package/templates/brownfield/references/finish-feature-flow.md +635 -88
  32. package/templates/brownfield/references/finish-feature-follow-up.md +60 -0
  33. package/templates/brownfield/references/finish-feature-minimal-host.md +406 -0
  34. package/templates/brownfield/references/finish-feature-post-hoc-hotfix.md +95 -0
  35. package/templates/brownfield/references/git-integration.md +160 -15
  36. package/templates/brownfield/references/init-project-flow.md +26 -4
  37. package/templates/brownfield/references/modify-existing-flow.md +412 -87
  38. package/templates/brownfield/references/modify-existing-follow-up.md +121 -0
  39. package/templates/brownfield/references/modify-existing-post-hoc-hotfix.md +82 -0
  40. package/templates/brownfield/references/new-feature-flow.md +61 -6
  41. package/templates/brownfield/references/new-phase-flow.md +57 -7
  42. package/templates/brownfield/references/pr-review-checklist.md +303 -10
  43. package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +158 -34
  44. package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +1 -1
  45. package/templates/brownfield/scaffolding/Git-principles-gitflow.md +75 -6
  46. package/templates/brownfield/scaffolding/Git-principles-trunk.md +82 -8
  47. package/templates/brownfield/scaffolding/_conventions.md +50 -28
  48. package/templates/brownfield/scaffolding/_overview.md +1 -0
  49. package/templates/brownfield/templates/_index.md +151 -7
  50. package/templates/brownfield/templates/analysis.md +79 -0
  51. package/templates/brownfield/templates/behavior.md +1 -0
  52. package/templates/brownfield/templates/context-definition.md +1 -0
  53. package/templates/brownfield/templates/context-map.md +2 -1
  54. package/templates/brownfield/templates/glossary.md +1 -0
  55. package/templates/brownfield/templates/lightweight-spec.md +154 -11
  56. package/templates/brownfield/templates/models.md +1 -0
  57. package/templates/brownfield/templates/phase-spec.md +9 -1
  58. package/templates/brownfield/templates/rules.md +1 -0
  59. package/templates/brownfield/templates/tech-debt.md +1 -0
  60. package/templates/common/references/ddd-modeling-guide.md +33 -16
  61. package/templates/{greenfield → common}/references/dflow-feedback-flow.md +2 -1
  62. package/templates/common/references/flow-rationale-registry.md +130 -0
  63. package/templates/common/skill/SKILL.md +13 -11
  64. package/templates/greenfield/references/drift-verification.md +4 -0
  65. package/templates/greenfield/references/finish-feature-flow.md +625 -89
  66. package/templates/greenfield/references/finish-feature-follow-up.md +60 -0
  67. package/templates/greenfield/references/finish-feature-minimal-host.md +363 -0
  68. package/templates/greenfield/references/finish-feature-post-hoc-hotfix.md +95 -0
  69. package/templates/greenfield/references/git-integration.md +148 -15
  70. package/templates/greenfield/references/init-project-flow.md +28 -8
  71. package/templates/greenfield/references/modify-existing-flow.md +378 -85
  72. package/templates/greenfield/references/modify-existing-follow-up.md +103 -0
  73. package/templates/greenfield/references/modify-existing-post-hoc-hotfix.md +82 -0
  74. package/templates/greenfield/references/new-feature-flow.md +67 -4
  75. package/templates/greenfield/references/new-phase-flow.md +56 -7
  76. package/templates/greenfield/references/pr-review-checklist.md +287 -8
  77. package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +153 -32
  78. package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +5 -2
  79. package/templates/greenfield/scaffolding/Git-principles-gitflow.md +74 -6
  80. package/templates/greenfield/scaffolding/Git-principles-trunk.md +88 -12
  81. package/templates/greenfield/scaffolding/_conventions.md +50 -28
  82. package/templates/greenfield/scaffolding/_overview.md +6 -2
  83. package/templates/greenfield/templates/_index.md +137 -7
  84. package/templates/greenfield/templates/aggregate-design.md +1 -0
  85. package/templates/greenfield/templates/analysis.md +79 -0
  86. package/templates/greenfield/templates/behavior.md +1 -0
  87. package/templates/greenfield/templates/context-definition.md +1 -0
  88. package/templates/greenfield/templates/context-map.md +2 -1
  89. package/templates/greenfield/templates/events.md +4 -1
  90. package/templates/greenfield/templates/glossary.md +1 -0
  91. package/templates/greenfield/templates/lightweight-spec.md +154 -11
  92. package/templates/greenfield/templates/models.md +1 -0
  93. package/templates/greenfield/templates/phase-spec.md +9 -1
  94. package/templates/greenfield/templates/rules.md +1 -0
  95. package/templates/greenfield/templates/tech-debt.md +1 -0
  96. package/templates/brownfield/references/dflow-feedback-flow.md +0 -251
@@ -0,0 +1,212 @@
1
+ # 當 `dflow doctor` 說它沒有把握
2
+
3
+ > **繁體中文** | [English](doctor-uncertainty.en.md)
4
+
5
+ > 本頁隨源碼 `main` 更新,因此可能描述 changelog 仍列在 `## Unreleased` 的行為。`@latest` 安裝的是最新的**已發佈** CLI,不保證已包含下面每一項 `main` 功能:
6
+ >
7
+ > ```bash
8
+ > npm install -g dflow-sdd-ddd@latest
9
+ > ```
10
+ >
11
+ > 本頁所有修法都只是改你自己的 Markdown,因此可以當成向前相容的指引。如果你的 `dflow doctor` 從來不會印出 `[uncertain]`,已安裝的 CLI 可能早於這項功能。這時先把本頁當作未來版本指引;只有 changelog 已納入此功能的發佈版才會出現這類回報。
12
+
13
+ ## `uncertain` 是什麼意思
14
+
15
+ 這一頁大部分在講 `dflow doctor` 對兩個「它會針對內容做出宣稱」的檔案——`dflow/specs/shared/_conventions.md` 與 `dflow/specs/shared/AI-AGENT-GUIDE.md`——回答的那一個問題:**上游模板的規則與設定,在你的檔案裡還在不在?** 只有一個 id 講的是別的東西:你的規格文件裡那一行形狀標記(下面的 `unreadable-shape-marker`)。
16
+
17
+ 要回答它,doctor 必須判斷每一行屬於哪一節,也就是要讀懂 Markdown 的區塊結構。它用的是一個刻意做得很小的讀取器,而有一批形狀是**已知它會讀錯**的。與其用猜的,doctor 現在會直接說出來:
18
+
19
+ ```text
20
+ [uncertain] dflow/specs/shared/_conventions.md, line 42: an HTML comment begins part-way through a line (inline-html-comment)
21
+ ...
22
+ Ran, but cannot be trusted while this shape is present — their silence is NOT a pass, and anything they DO report may be an artefact of the shape: ...
23
+ ```
24
+
25
+ 看到 `[uncertain]` 這行,有三件事成立,而第二件最常被忽略:
26
+
27
+ 1. **不會印出 `All checks passed`。** 處在這個狀態的專案,永遠不會拿到跟真正乾淨的專案一樣的結論。
28
+ 2. **被列名的那幾項檢查是有跑的——但它講的話,兩個方向都不能信。** doctor 是「有問題才講」的工具,所以平常一項檢查沒出聲就代表「這裡沒事」。但對 finding 裡列出的那幾項,沒出聲代表的是**沒有量到任何可信的東西**——不要當成通過。反方向也成立:那幾項裡如果真的冒出一條 `warn`,它也可能是那個形狀把讀取器搞混了,而不是真的漂移。
29
+ 3. **exit code 仍然是 `0`。** 「不確定」不是建置失敗。doctor 從來沒有用非零 exit code 表達任何一條 finding,這次也沒有改變。
30
+
31
+ ## 為什麼不乾脆把那些形狀修掉就好
32
+
33
+ 有些修得動、有些真的修不動,而假裝都修得動正是本頁要避免的事:
34
+
35
+ - 有些的修法等於把讀取器本身重寫,而**這個**讀取器的重寫有紀錄可查:每次都在關掉舊缺陷的同時帶進新的。
36
+ - 有一種修下去會改變「什麼算是一張表格」,連帶把一項無關的格式檢查一起挪動。
37
+ - 而至少有一種形狀——本頁最後一節那個**刻意不回報**的表格縮排缺口——**找不到仲裁者**可以實作:能判定誰對的兩套參照實作彼此不一致,而其中一套根本沒有表格的概念。
38
+
39
+ 所以誠實的做法是:**能安全收窄的地方就收窄,偵測得到的就說出來,其餘的記在原始碼裡。** 偵測「某個形狀在不在」完全不需要那套可能會錯的區塊邊界邏輯——這正是為什麼這些警告可以信,即使它們警告的那件事不能信。
40
+
41
+ ## 各種形狀
42
+
43
+ 每個標題就是 doctor 印在括號裡的偵測器 id。
44
+
45
+ > 這份清單**不是**窮舉。它涵蓋的是目前既已知、又偵測得到的形狀。Markdown 的邊界情況比任何清單都多,**沒有出現在這裡不等於已被驗證安全**——它可能是還沒被發現,也可能是已知但判斷不值得警告(見最後一節)。
46
+
47
+ ### `inline-html-comment`
48
+
49
+ **形狀。** 從一行的中間才開始的 HTML 註解:
50
+
51
+ ```markdown
52
+ Selected Git policy: `gitflow` <!-- was trunk, revisit in Q3 -->
53
+ ```
54
+
55
+ **為什麼讀不準。** doctor 是一行一行分類 Markdown 的。**開頭就是**註解的那一行會開啟一個區塊,doctor 會正確地把它的內容當成看不見的。但從一行中間才開始的註解根本不是區塊,而是 inline span,所以它的內容會被算成活的文件內容。
56
+
57
+ **往哪個方向失敗。** 靜默。你在一行中間註解掉的規則,讀起來仍然「還在」,於是 doctor 會說你的檔案是最新的,而其實它有一部分已經被關掉了。這是最糟的方向,也是它必須被揭露、而不能放著不管的原因。
58
+
59
+ **怎麼改。** 把註解移到自己獨立的一行,而且**要從第 0 欄開始**、不在任何清單項或引用區塊裡面。在那個位置它才會開啟一個真正的 HTML 區塊,內容才會停止被讀取:
60
+
61
+ ```markdown
62
+ <!-- was trunk, revisit in Q3 -->
63
+ Selected Git policy: `gitflow`
64
+ ```
65
+
66
+ 直接刪掉也可以。
67
+
68
+ > ⚠ **縮排到清單項底下是不夠的**,這句話值得特別寫出來,因為那正是照上面那句話做時最自然的動作。縮排在 `- item` 底下的註解仍然**留在那個項目裡面**,doctor 照樣會讀它——見下一個形狀。關鍵是**欄位**,不是「有沒有獨佔一行」。
69
+
70
+ 注意:寫在 code span 裡的註解——`` `<!-- 像這樣 -->` ``——是**會被 render 出來**的,讀者看得到,那不是這個形狀,doctor 也不會回報它。
71
+
72
+ > ⚠ **如果這次指出的註解在 `<textarea>` 裡面,請保持那一行不變**——包括它被報在**這個** id 底下的時候(標籤和註解寫在同一行時就會這樣)。`<textarea>` 的內部是原始文字,把那一行移出去反而會藏起讀者原本看得到的文字。但**不要忽略整體的不確定結論**:doctor 對每種形狀在一個檔案裡只回報第一處,所以這個無害位置可能遮住後面同 id、真的被藏起來的註解。信任受影響的檢查以前,請繼續檢查該檔案其餘看似註解開頭的位置。
73
+
74
+ > ⚠ **Renderer 範圍:**清單所擁有的 raw HTML 若出現沒有 marker 的 continuation,這裡以 Dflow 隨附的 renderer(`dflow render`,由 Marked 驅動)為準。其他 Markdown renderer 可能會顯示被 escape 的註解開頭;若你用別的 renderer 發佈,套用修法前請先檢查它的輸出。
75
+
76
+ > ⚠ **如果註解在 HTML 區塊裡面**(`<details>`、`<div>`、`<pre>` …),只把它移到第 0 欄**不是完整的修法**——你仍然在那個區塊裡面。逐標籤的規則見下面的 `comment-inside-container`。
77
+
78
+ ### `comment-inside-container`
79
+
80
+ **形狀。** 註解獨佔一行,但那一行在某個**容器**裡面。清單項和引用區塊是日常會遇到的兩種:
81
+
82
+ ```markdown
83
+ - Ceremony scaling
84
+ <!-- Escalate-only, no de-escalation. -->
85
+ ```
86
+
87
+ HTML 區塊也是一種容器,而它特別容易讓人踩到——因為那個註解就寫在第 0 欄,看起來完全正常:
88
+
89
+ ```markdown
90
+ <details>
91
+ <!-- Selected Git policy: `trunk` -->
92
+ </details>
93
+ ```
94
+
95
+ **為什麼讀不準。** doctor 不會把容器的**內部**當成獨立的一串區塊去解析,所以在裡面開啟的註解,對 doctor 而言從來沒有開啟過任何 HTML 區塊。它的文字仍然留在「活的文件內容」那一堆裡。決定「算不算容器」的是**這個行為**、不是它的語法長相——所以上面兩個例子請當成舉例,不是完整清單。
96
+
97
+ **往哪個方向失敗。** 在 `dflow render` 裡會靜默;它的 Marked renderer 通常不會顯示註解文字,doctor 卻把註解的內容當成你寫的一般文字在讀。**不管你有沒有把註解關起來,結論都一樣**——關起來也沒用,因為問題出在它待的位置,不是它有沒有結束。兩種形狀裡 `<details>` 那種更危險:被註解掉的設定可以被下面某一行**看得見的內容推翻**,而 doctor 仍然採信藏起來的那一個。
98
+
99
+ > ⚠ **Renderer 範圍:**對清單所擁有的 raw HTML 之 markerless continuation,上面的方向以 `dflow render`(Marked)為準。有些其他 Markdown renderer 反而會顯示被 escape 的註解開頭。若你用別的 renderer 發佈,移動或刪除註解前請先檢查那份輸出。
100
+
101
+ **怎麼改。** 把註解移出那個容器——或直接刪掉。**離開容器**就是整個修法,而「怎麼離開」取決於你在哪一種容器裡:
102
+
103
+ - **清單項或引用區塊**——把註解放到第 0 欄、獨佔一行,前面沒有清單標記、也沒有 `>`。
104
+ - **HTML 區塊,大多數標籤(`<details>`、`<div>` …)**——結束這種區塊的是**空行**,**不是結束標籤**。所以要在區塊和註解之間空一行,或乾脆把註解移到整個區塊上面。
105
+ - **`<pre>`**——它是例外,規則正好相反:它是靠**自己的結束標籤**收尾的。請把註解移到 `</pre>` **下面**。在區塊裡面加空行沒有用,因為空行結束不了它。
106
+
107
+ ⚠ **如果註解同時待在好幾層容器裡面,你要離開的是最外面那一層。** 清單項裡面的 `<pre>`、引用區塊裡面的 `<details>`:只套用裡面那條規則,註解仍然在清單項或引用區塊裡,doctor 會再報一次同樣的 finding。請一層一層往外走,直到註解位在第 0 欄、外面什麼都沒有。
108
+
109
+ ⚠ 中間那條才是最容易踩的:`<details>` 這一類,把註解移到 `</details>` **下面但沒有空行**,它仍然在區塊裡面,doctor 會再報一次同樣的 finding。這條就是 `unclosed-html-block` 那節講的同一個空行規則。⚠ 但**不要把它推廣**——套到 `<pre>` 上,你會加了空行、看著 finding 原封不動,然後完全不知道為什麼。
110
+
111
+ #### `<textarea>` 不屬於這裡講的形狀——但 doctor 有時仍然會報它
112
+
113
+ `<textarea>` 長得像 `<pre>`,行為卻正好相反。它的內部是**原始文字**,所以 `<!-- 像這樣 -->` 會**原封不動顯示給讀者看**。沒有任何東西被藏起來,也就沒有什麼要揭露的——**反過來說,把這種註解移出去,才是那個真正會把它藏起來的編輯。**
114
+
115
+ doctor 仍然會報它,而且是刻意的。要豁免它試過三次,每一次都反而造出「**真的**被藏起來的註解沒人回報」的情況——那正是這整個檢查存在要防的事。保留這個無害位置的回報,比「對一個 doctor 讀錯的檔案給出乾淨結論」安全得多,所以那個豁免被**移除**,而不是再補一次。
116
+
117
+ > **如果你收到 `comment-inside-container`、而這次指出的註解就在 `<textarea>` 裡面,請保持那一行不變,但整體 finding 仍不能結案。** Doctor 對這個 id 在一個檔案裡只回報第一處;信任受影響的檢查以前,請繼續找該檔案後面是否還有看似註解開頭的位置。
118
+
119
+ #### 用 fence 包起來的範例,仍然可能被報
120
+
121
+ doctor 在找這些形狀之前,會先把 fenced code 遮掉,所以放在 ```` ``` ```` 裡面的範例通常不會觸發。但它的 fence 掃描器讀的是**原始的文件行**、從來不會先剝掉容器前綴——所以有一類 fence 它認不出來。已知的有:
122
+
123
+ - 開在**引用區塊裡面**的 fence(反引號前面有 `> `);
124
+ - **原始縮排四格以上**的 fence——在普通的 `- item` 底下,只要你把 fence 縮到那麼深就會發生;
125
+ - 和清單標記**開在同一行**的 fence(`- ```md`)——這一種的原始行以 `-` 開頭,所以下面「縮到三格以內」的修法對它無效,要把 fence 移到自己獨立的一行。
126
+
127
+ > ⚠ 這份清單**不是窮舉**。前一版寫「剛好會漏掉兩種」,而下一輪 review 就找到第三種(`p084gate-x14`)。判準是「fence 的原始行沒有從第 0 欄開始、或前面有容器前綴」,不是一張可以核對完的清單。
128
+
129
+ 這幾種情況裡的註解仍然會被報出來,而且還有第二個容易被忽略的後果:**沒被遮蔽的 fence,裡面的文字會被當成一般的節內容讀進去。** 如果你的範例剛好引用了一條後來在檔案別處被改掉的規則,doctor 可能會把範例當成活的規則、然後回報這個檔案是最新的。所以沒被遮蔽的 fence 不只是吵——**它也可能把真正的漂移藏起來**。
130
+
131
+ 它們的解法**不一樣**:
132
+
133
+ - **縮排那種**——把 fence 的縮排退回兩到三格,回報就會停。這是唯一一個「重新縮排真的有用」的地方,也是上面那條規則的例外。
134
+ - **引用區塊那種**——重新縮排**沒有用**,縮多少都一樣,因為那一行開頭仍然是 `>`,fence 掃描器根本看不到這個 fence。要嘛把範例移出引用區塊,要嘛忽略它。
135
+ - **跟清單標記同一行那種**——重新縮排也沒用,因為原始行是以標記開頭的。把 fence 移到標記下面、自己獨佔一行,或者忽略它。⚠ 這裡**不要**照 CLI 對這個 id 印出來的通用修法做:移掉或刪掉那個註解,會把讀者看得到的範例文字一併拿掉。
136
+
137
+ 把**註解**在容器裡面重新縮排,永遠沒有幫助。⚠ 這句講的是註解。把 **fence** 的縮排退回來是另一件事,而且那是有用的——見上面 fenced 範例那段,那是本頁唯一的例外。
138
+
139
+ ### `unclosed-html-block`
140
+
141
+ **形狀。** 在一行開頭開啟、卻從未關閉的 HTML 區塊——最常見的是編輯到一半留下的 `<!--`。
142
+
143
+ **為什麼讀不準。** 從那一行到檔案結尾全都在那個區塊裡面,所以那些內容不算任何一節的內容,也就無從評估。
144
+
145
+ **往哪個方向失敗。** 兩個方向同時發生,這一條值得讀兩遍。區塊下方出現的 `missing` 或「少了那條規則」可能是這個未關閉區塊造成的、而不是真的漂移;**而且**真的漂移掉的規則如果在它下面,會完全沒有人回報,因為區塊把檢查本來要讀的文字藏起來了。請把這一行以下的所有結果都當成**未知**,不要當成通過。
146
+
147
+ **怎麼改。** 把區塊關起來。如果是 HTML 註解,就是補上 `-->`;其他**帶有結束條件**的區塊型別(`<script>`、`<style>`、`<pre>`、`<textarea>`、`<?`、`<!DOCTYPE`、`<![CDATA[`)各有各的收尾寫法。
148
+
149
+ 只有「帶結束條件」的區塊才可能產生這條 finding。像 `<details>` 這種標籤開啟的是另一種 HTML 區塊,它遇到**空行**就結束,所以它永遠會「關起來」、也就永遠不會走到這條回報——如果你看到 `<details>` 段落把內容吃掉了,你要找的是**缺的那個空行**,不是缺的結束標籤。
150
+
151
+ ### `html-block-type-7`
152
+
153
+ **形狀。** 一個完整的標籤,名字不在 CommonMark 已知的區塊標籤清單裡,獨自站在一個區塊的開頭,正下方緊接著 `---` 或 `===`:
154
+
155
+ ```markdown
156
+ <my-widget>
157
+ ---
158
+ ```
159
+
160
+ **結束標籤也算**——`</my-widget>` 放在同一條底線上面是同一種形狀,回報方式也一樣。自我關閉的寫法同理。
161
+
162
+ **為什麼讀不準。** 這個寫法是 HTML block type 7。它是唯一一種**不能打斷段落**的 HTML 區塊型別,而要正確辨識它需要一個真正的標籤解析器。doctor 沒有實作它。
163
+
164
+ **往哪個方向失敗。** 多半是大聲的:doctor 會比 render 出來的結果更早結束那一節,於是回報出根本不存在的漂移——而一個你重現不出來的 `stale` 本身就是個問題,所以還是把它講明白。⚠ 但**不只是**大聲,這一點先前講得太篤定了:提早結束那一節,也等於把那一節後面的內容一起丟掉,所以位在這個形狀下方的**已退休規則會不再被看到、它的 finding 也就消失了**。請把這一節的結果當成**兩個方向都未知**。
165
+
166
+ **怎麼改。** 在標籤和底下那條底線之間空一行。如果那個標籤是要**展示**而不是要用的,就用 fence 把它包成範例。
167
+
168
+ ### `unreadable-shape-marker`
169
+
170
+ **形狀。** `dflow/specs/` 底下的某份規格文件,它從範本帶過來的形狀標記——`<!-- dflow-shape: {軌別}/{範本} {號碼} -->` 那一行,號碼後面的說明可有可無(見[形狀標記](upgrading.md#形狀標記))——doctor 看不準:標記該在的那一行(第一行;有 frontmatter 就是它收尾之後那一行)格式不對(例如號碼不是正整數,像 `0` 或 `01`);含 `dflow-shape:` 的行不在那個位置(當例子引用的、被註解掉的、放在清單或引用裡的都算;檔案開頭的 BOM(位元組順序標記)擋住 frontmatter 時,它後面那一行標記也算——`dflow render` 一樣看不到那段 frontmatter);文件裡有兩行以上含 `dflow-shape:`;或是那一行指名了這個 CLI 沒有出貨的範本(打錯字,或是只有另一軌才有的範本)。
171
+
172
+ **為什麼讀不準。** 標記是「這份文件是照哪一號範本形狀寫的」唯一的紀錄。那一行壞了,doctor 不去猜:猜出來的號碼可能讓它對一份其實落後的文件保持沉默,也可能讓它去報一份其實沒有落後的文件。doctor 也不去判斷一行不在標準位置的標記是不是有效的:那得跟 `dflow render` 對清單、引用、註解、程式碼區塊的讀法完全一致,而它寧可照實說看不準,也不把一份讀不到的文件報成通過。
173
+
174
+ **往哪個方向失敗。** 只會是沉默,而且只限列出來的那幾份:doctor 沒有判讀它們的形狀,所以它什麼都沒說不代表通過。如果是 feature 的 `_index.md`,doctor 對沒有標記的 dashboard 會做的逐段比對,這時也一樣沒有做。其他檢查都不受影響。
175
+
176
+ **怎麼改。** 每份文件只留一行標記,放在它該在的那一行。當例子引用的、被註解掉的舊標記也會被算進去:改寫成不含 `dflow-shape:` 的字樣。文件如果是從 bundle 的範本副本整份拷過來、第一行是 `<!-- dflow-generated: workflow-bundle -->`,刪掉那一行和它後面的空行(doctor 會點名這種情況)。檔案開頭如果有 BOM 擋在 frontmatter 前面,把檔案存成不帶 BOM 的 UTF-8(doctor 也會點名這種情況)。如果你確定它原本是哪支範本、第幾號,就照那個號碼把那一行寫回去:已安裝的範本裡那一行帶的是現行號碼,直接抄過來會把舊文件標成現行形狀。如果不確定號碼,把壞掉的行刪掉,當成沒有標記的文件處理——號碼由[形狀標記](upgrading.md#形狀標記)那一節的一次性補法決定。⚠ 還沒關帳的 zero-phase feature(沒有 phase、只掛一個小改動的 feature 目錄)裡的文件會被分開列:關帳之前不要動它,關帳後它會搬進 `features/completed/`,不再被檢查。Phase Specs 表是空的、目錄裡卻有 phase spec 的 feature,doctor 判不出是不是 minimal host,也會分開列:是 minimal host 就先別動,不是就照上面改。
177
+
178
+ ## 已知、但刻意不回報的形狀
179
+
180
+ 揭露本身也有代價:一個會在正確檔案上誤報的警告,會教會大家把所有警告都當耳邊風。
181
+
182
+ **畸形的表格分隔列**(格數和標題列不一樣)也在這一節裡,而它的理由不一樣,值得單獨說。
183
+
184
+ GFM 要求分隔列的格數必須和標題列相同,不相同時整塊就**不是表格**、會被當成普通段落文字。doctor 沒有強制這條規則,兩邊對「這裡是不是表格」看法不同,接下來對「這一節到哪裡結束」也就可能不同——所以這個形狀**真的會**害 doctor 讀錯,而且兩個方向都會(節延伸過頭,或提早切斷)。
185
+
186
+ 那為什麼不回報?**因為做過了,而且做不好。** 這個偵測器寫出來之後,連續六輪 review 每一輪都找到一份它會漏掉的文件,而漏掉的後果一律是**靜默**——對已經漂移的檔案印出 `All checks passed`,比不回報更糟。收窄成「只報實測會讀錯的形狀」失敗五次;放寬成「任何格數不符都報」在第六次失敗,因為剩下的那個清單搬到了「怎麼認出一列分隔列」裡面。而其中一輪還量到:**分隔列格數正確時**同樣的靜默失敗也會發生,所以這個偵測器的範圍本來就只是問題的一部分。
187
+
188
+ 耐久的解法是換工具,不是再寫一份更好的形狀清單:`marked`(就是 `dflow render` 用的那支 renderer)已經是這個套件的相依套件,所以節的邊界可以**直接向它拿**,而不是在旁邊猜、再逐個形狀比對差異。那是另一項設計改動,要走自己的評估,所以現在**先誠實地說「這裡我們不檢查」**,而不是留一個會靜默漏掉的檢查。
189
+
190
+ 如果你在追一個說不通的漂移結果,而檔案裡有格數不符的表格分隔列——那是值得先改掉的地方。
191
+
192
+ 還有一個已知缺口——**表格裡面的縮排續行**——是為了另一個理由刻意不回報。它的原型偵測器在 151 份真實檔案裡誤報了 5 次,全部都是被一般的縮排程式碼和範例觸發的。而且目前也沒有任何可用的參照實作能判定這個形狀誰對誰錯:能仲裁的兩套彼此不一致,其中一套還根本沒有表格的概念。對它而言,警告真的比缺口本身更糟。
193
+
194
+ **它不是唯一沒被回報的。** 其他的記在原始碼裡(`lib/doctor-checks.js` 的「what this deliberately does not implement」段),而不是記在本頁,因為它們沒有可以拿來觸發回報的具體形狀——其中範圍最廣的一條是「巢狀容器的內部不會被當成獨立的一串區塊解析」,而上面那兩個註解形狀,正是這一條裡**偵測得到**的具體子案。
195
+
196
+ 所以,如果你正在追一個怎麼看都說不通的漂移結果,而上面那些形狀在你的檔案裡都不存在,表格縮排那條是**其中一個**值得檢查的候選——不是最後一個。**本頁的結尾不是清單的結尾。**
197
+
198
+ **還有一筆刻意不報的,和上面那些不同類:指令檔與 skill 檔「一支都沒有」。** 上面講的都是「同一份檔,doctor 可能讀錯」。這一筆不是讀錯,是**整層不看**。
199
+
200
+ `dflow doctor` 會檢查 `.claude/commands/dflow/`、`.github/prompts/dflow-*.prompt.md` 與三份 `SKILL.md`,但**只檢查已經存在的那些**:少了其中幾支會報、留著 `0.5.0` 舊檔名的殘留會報、Dflow 產生的 `SKILL.md` 落後於目前版本會報。**但整層一支都不存在時,它一個字都不會說。**
201
+
202
+ **失敗情境。** 一個專案從來沒跑過 `dflow configure-agents --command-adapters`,或跑過、而檔案在某次 clone 之後沒有重新產生,於是 `/dflow:*` 一支都打不出來——而 `dflow doctor` 從頭到尾回報 `All checks passed`。這不是假想:一個實際專案跨了六個版本、`.claude/commands/dflow/` 一支都沒有,doctor 全程沉默。
203
+
204
+ **為什麼決定不防。** doctor 分不出兩種人——「我本來就沒要那些檔」和「我有過、掉了」——這兩種狀態在磁碟上長得完全一樣,而且**兩種都合法**。Dflow 從來不記錄一個專案打算用哪些工具(這是 `PROPOSAL-058` 定下的界線,`checkRootAgentShims` 也照它走),而 `PROPOSAL-037` 反過來**建議**採用者把這些衍生檔 gitignore 掉、clone 之後再重新產生——所以一個乾淨 clone「一支都沒有」,正是照建議做出來的樣子。這條偵測規則被規格化過三次,三次都被找出會誤報無辜專案的路徑,其中一版連**每一次全新的 `dflow init`** 都會被報一條。本節開頭那句「會在正確檔案上誤報的警告,會教會大家把所有警告都當耳邊風」,講的就是這個。
205
+
206
+ **殘餘風險由誰承擔。** 採用者。doctor 每次執行都會在報告結尾把這條界線印出來,並指名由使用 Dflow 的 AI 接手確認——⚠ **但那是委派,不是保證**:沒有任何機制強制它發生,也沒有任何檢查驗證它做過。
207
+
208
+ **什麼條件下會重新考慮。** 如果 command adapter 改成預設安裝,「我本來就沒要」的那種人就不存在了,偵測會退化成「在不在」這個單純問題。那是一項獨立的產品決定(它會推翻 `PROPOSAL-074` 把 adapter 維持 opt-in 的明文決定),目前尚未拍板。真的走那條路的話,本頁這一筆要一併重看。
209
+
210
+ ## 如果以上都解釋不了你看到的結果
211
+
212
+ doctor 是唯讀的,它不會改你的檔案,所以本頁提到的任何情況都不可能弄壞什麼東西。一個你解釋不了的漂移回報值得回報給我們——請附上它指到的那一節 `_conventions.md` 內容,以及有印出來的話,那個偵測器 id。
@@ -208,29 +208,47 @@ not to adopt.
208
208
 
209
209
  ## Cost Per Feature: A Rough Estimate
210
210
 
211
- Dflow scales ceremony to change risk through three tiers (see
212
- [`README.md` "Workflow Model"](../README.en.md#workflow-model) for full
213
- detail):
211
+ Dflow scales ceremony to change risk through three tiers (the criteria live in
212
+ `AI-AGENT-GUIDE.md` § Ceremony Scaling; see
213
+ [`README.md` "Workflow Model"](../README.en.md#workflow-model) for the product
214
+ overview):
214
215
 
215
216
  - **T1 Heavy** — new features, new phases, new Aggregates or Bounded
216
- Contexts, architecture changes, new business rules. A full phase-spec
217
+ Contexts, architecture changes, new business rules, data-structure
218
+ changes, and any contract change that breaks a caller (API / event, or a
219
+ required env var / CLI flag / exit code). A full phase-spec
217
220
  with domain modeling, behavior examples, an implementation plan, and
218
221
  verification + finish checks. The cost is real but proportional to
219
222
  the risk being managed.
220
223
  - **T2 Light** — bug fixes (logic errors), UI verification adjustments,
221
- small changes with a business-rule delta. A lightweight spec, focused
224
+ small changes with a business-rule delta, non-breaking contract changes,
225
+ performance-only work. A lightweight spec, focused
222
226
  verification, and confirmation that the fix lands in the correct
223
227
  architectural layer.
224
- - **T3 Trivial** — button colors, copy typos, pure formatting — **no
225
- business-rule, Domain, or data-structure changes**. One line in
226
- `_index.md`; no separate spec file.
228
+ - **T3 Trivial** — a local, meaning-preserving display copy / appearance tweak
229
+ (button colors, copy typos / wording, layout polish) — **no business-rule,
230
+ Domain, or data-structure changes**, and not high-consequence content.
231
+ "Local" means element level on a single screen / component, or a single
232
+ independently-consumed page / file such as a public README or an API
233
+ reference page; a whole-screen rewrite or a cross-screen sweep escalates to
234
+ T2, and so does a cross-page sweep. When hosted
235
+ under an existing feature it is one line in that `_index.md`, with no separate
236
+ spec file; if no owning feature exists, `/dflow:modify-existing` opens a
237
+ minimal (zero-phase) host and records the row there.
238
+
239
+ The list above is a summary. The one source that decides an actual change is
240
+ `AI-AGENT-GUIDE.md` § Ceremony Scaling — the ordered cascade, steps 0–4, first
241
+ match wins.
227
242
 
228
243
  Tier choice is not always manual: `/dflow:new-feature` and
229
244
  `/dflow:new-phase` default to T1; `/dflow:modify-existing` and
230
245
  `/dflow:bug-fix` let the AI judge T1/T2/T3 based on what is actually
231
- changing. Pure typo / formatting commits (e.g., `prettier`,
232
- `dotnet format`) can skip Dflow entirely and just `git commit` — Dflow
233
- is for changes with business semantics or structural impact.
246
+ changing. Pure formatting commits (e.g., `prettier`, `dotnet format`),
247
+ internal comments, and internal-doc typos can skip Dflow entirely and just
248
+ `git commit` (a user-visible typo goes through the cascade: T3 on a single screen or a single independently-consumed page, T2 once it sweeps several or touches high-consequence content). The reverse also holds — invisible
249
+ does not mean untracked: machine-consumed contracts, security / CVE and
250
+ compliance work, and deliberate runtime performance / resource / SLA changes
251
+ all stay inside Dflow.
234
252
 
235
253
  ## Project Language Compatibility
236
254
 
@@ -161,14 +161,16 @@ Dflow 的設計讓試用成本低、退出成本也低:
161
161
 
162
162
  ## 每個 Feature 的成本:概略估算
163
163
 
164
- Dflow 依改動深淺將流程份量調整為三個 tier(完整說明見
165
- [`README.md` "Workflow 模型"](../README.md#workflow-模型)):
164
+ Dflow 依改動深淺將流程份量調整為三個 tier(判準全文見 `AI-AGENT-GUIDE.md` § Ceremony Scaling;
165
+ 產品面說明見 [`README.md` "Workflow 模型"](../README.md#workflow-模型)):
166
166
 
167
- - **T1 Heavy** — 新 feature、新 phase、新 Aggregate 或 Bounded Context、架構變更、新業務規則。需要完整的 phase-spec,包含領域建模、行為例子、實作計畫、以及驗證與收尾檢查。成本確實存在,但與所管理的風險成正比。
168
- - **T2 Light** — bug fix(邏輯錯誤)、UI 驗證調整、有業務規則 delta 的小幅修改。需要 lightweight spec、聚焦驗證、以及確認修復落在正確的架構層。
169
- - **T3 Trivial** — 按鈕顏色、文案 typo、純 formatting — **不動業務規則、不動 Domain 概念、不動資料結構**。只需在 `_index.md` 寫一行,不另開 spec 檔。
167
+ - **T1 Heavy** — 新 feature、新 phase、新 Aggregate 或 Bounded Context、架構變更、新業務規則、資料結構變更,以及會讓呼叫端壞掉的契約變更(API/event,或必填的環境變數/CLI 參數/exit code)。需要完整的 phase-spec,包含領域建模、行為例子、實作計畫、以及驗證與收尾檢查。成本確實存在,但與所管理的風險成正比。
168
+ - **T2 Light** — bug fix(邏輯錯誤)、UI 驗證調整、有業務規則 delta 的小幅修改、不破壞呼叫端的契約調整、純效能調整。需要 lightweight spec、聚焦驗證、以及確認修復落在正確的架構層。
169
+ - **T3 Trivial** — 局部、語意保持的顯示文案/外觀小修(按鈕顏色、文案 typo/措辭、版面 polish)— **不動業務規則、Domain 概念、資料結構**,也非高後果內容。「局部」指單一畫面/元件上的元素層級,或單一獨立閱讀的頁面/檔案(例如公開 README、公開 API reference 頁);整頁改版或跨畫面的掃改升 T2,跨頁的掃改同理。掛在所屬 feature 下時,只需在其 `_index.md` 寫一行,不另開 spec 檔;沒有所屬 feature 時,`/dflow:modify-existing` 會開一個 minimal(zero-phase)host 把該行記在那裡。
170
170
 
171
- Tier 不是每次都由 user 手動決定:`/dflow:new-feature` 與 `/dflow:new-phase` 預設一律 T1;`/dflow:modify-existing` 與 `/dflow:bug-fix` 則由 AI 依實際改動內容判斷 T1 / T2 / T3。純 typo / formatting commit(例如 `prettier`、`dotnet format`)可以完全跳過 Dflow 直接 `git commit` — Dflow 是給有業務語意或結構影響的變更使用的。
171
+ 上面是摘要。判定實際變更的唯一依據是 `AI-AGENT-GUIDE.md` § Ceremony Scaling 的 ordered cascade(步驟 0–4,先命中者勝)。
172
+
173
+ Tier 不是每次都由 user 手動決定:`/dflow:new-feature` 與 `/dflow:new-phase` 預設一律 T1;`/dflow:modify-existing` 與 `/dflow:bug-fix` 則由 AI 依實際改動內容判斷 T1 / T2 / T3。純 formatting commit(例如 `prettier`、`dotnet format`)、內部註解、內部文件的 typo 可以完全跳過 Dflow 直接 `git commit`(使用者看得到的 typo 依 cascade 判:單一畫面、或單一獨立閱讀頁面上的顯示文案是 T3,掃過多個畫面/頁面或高後果內容升 T2)。反過來,人眼看不到不代表不用追蹤:machine-consumed contract、security/CVE 與 compliance 工作、runtime 效能/資源/SLA 變更都仍在 Dflow 內。
172
174
 
173
175
  ## 專案語言相容性
174
176
 
@@ -12,7 +12,9 @@ Replace `<version>` with the version being published, for example `0.1.2`.
12
12
  - [ ] Update `CHANGELOG.md`.
13
13
  - [ ] Confirm `README.md` installation instructions match the release.
14
14
  - [ ] Confirm Greenfield and Brownfield common flow changes are synchronized.
15
- - [ ] Confirm generated templates match skill source where applicable.
15
+ - [ ] Confirm workflow content changes are complete under `templates/` — the
16
+ single content source; there is no separate skill-source copy to
17
+ synchronize.
16
18
  - [ ] Run the lifecycle check in the development repo and confirm it is green,
17
19
  so every proposal this release covers is terminal (`implemented` /
18
20
  `rejected` / `superseded`) and already archived:
@@ -95,8 +95,9 @@ the only place where release history is recorded.
95
95
 
96
96
  ## Greenfield and Brownfield Changes
97
97
 
98
- If a change touches a common SDD flow, update both Greenfield and Brownfield
99
- skill sources unless the release intentionally changes only one track.
98
+ If a change touches a common SDD flow, update the flow under both
99
+ `templates/greenfield/references/` and `templates/brownfield/references/`
100
+ unless the release intentionally changes only one track.
100
101
 
101
102
  Common synchronized flow files include:
102
103
 
@@ -105,6 +106,11 @@ Common synchronized flow files include:
105
106
  - `modify-existing-flow.md`
106
107
  - `new-phase-flow.md`
107
108
  - `finish-feature-flow.md`
109
+ - `finish-feature-follow-up.md`
110
+ - `finish-feature-minimal-host.md`
111
+ - `finish-feature-post-hoc-hotfix.md`
112
+ - `modify-existing-follow-up.md`
113
+ - `modify-existing-post-hoc-hotfix.md`
108
114
  - `drift-verification.md`
109
115
  - `pr-review-checklist.md`
110
116
  - `git-integration.md`
@@ -0,0 +1,196 @@
1
+ # Upgrading an Existing Dflow Project
2
+
3
+ > [繁體中文](upgrading.md) | **English**
4
+
5
+ > This page is the latest guidance and tracks the source `main` branch. Upgrade the CLI to the latest npm release first, then follow this page:
6
+ >
7
+ > ```bash
8
+ > npm install -g dflow-sdd-ddd@latest
9
+ > ```
10
+ >
11
+ > The page describes the behavior of the latest published release; the core principle — who owns what, and what is never touched — applies to older versions as well. Behaviors that require a newer version are called out explicitly.
12
+
13
+ ## The upgrade model
14
+
15
+ Upgrading Dflow is two steps: update the CLI (the line above), then re-run the projection from your project root:
16
+
17
+ ```bash
18
+ dflow configure-agents
19
+ ```
20
+
21
+ `configure-agents` is an idempotent *re-projection*: it refreshes only the layers Dflow itself owns, and **never rewrites or migrates content you authored automatically** — the one case that does rewrite user content is marker adoption you **explicitly accept** in an interactive prompt (its cost is spelled out in the state matrix below). What gets refreshed — and what needs a flag — is in the table below.
22
+
23
+ ## Who owns what: the ownership × flag table
24
+
25
+ | Surface in your project | Examples | Owner | What flagless `dflow configure-agents` does | Flag required |
26
+ |---|---|---|---|---|
27
+ | Starter scaffolding and your specs | `_overview.md`, the body of `_conventions.md`, the header and `## 6.`-and-below of `Git-principles-{policy}.md`, everything you wrote under `dflow/specs/` | **You** | Untouched; the single exception is advancing the `> Dflow Version:` reconciliation line in `_conventions.md` to the current CLI version | — |
28
+ | Workflow bundle | `dflow/specs/shared/dflow-workflows/` (flow docs, blank templates, `.dflow-bundle-manifest.json`) | Dflow | **Re-projected automatically**; files retired by the new version are removed via the manifest diff | — |
29
+ | Marker-delimited regions | `agent-shim` marker blocks inside `CLAUDE.md` / `AGENTS.md` / `.github/copilot-instructions.md`; the `guide-canonical` region of `AI-AGENT-GUIDE.md`; the `git-principles-canonical` region of `Git-principles-{policy}.md` (sections 1-5) | Dflow (inside markers) / you (outside) | **Refreshes the `agent-shim`, `guide-canonical` and `git-principles-canonical` regions in place**; everything outside — `## Project Context`, and the Git principles file header plus everything from `## 6. AI Collaboration Rules (Project Policy)` down — is preserved | — |
30
+ | Tool-native command entries | `.claude/commands/dflow/`, `.github/prompts/dflow-*.prompt.md`, etc., plus the `codex-command-triggers` marker region inside `AGENTS.md` | Dflow | Not regenerated | `--command-adapters` |
31
+ | Project-level skills | `.claude/skills/dflow/`, `.agents/skills/dflow/`, `.github/skills/dflow/` | Dflow | Existing skills are not regenerated; newly selected tools without a skill are offered one (installed by default) | `--skills` (force-regenerate all) |
32
+
33
+ ⚠ **For those last two rows, `dflow doctor` sees only files that are already there.** It reports a partial set of command entries (naming which are missing), `0.5.0`-era filenames left behind, and a Dflow-generated `SKILL.md` that has fallen behind the current CLI. It does **not** report "none of them are there" — that silence is deliberate, and its reasoning and residual risk are written up in [`doctor-uncertainty.en.md`](doctor-uncertainty.en.md) under "Shapes that are known and deliberately not reported". So if you **want** `/dflow:*` after an upgrade, run `dflow configure-agents --command-adapters` and check for yourself rather than waiting for doctor to tell you.
34
+
35
+ One-sentence version: **flagless refreshes the bundle plus the `agent-shim`, `guide-canonical` and `git-principles-canonical` regions; command adapters (including the `codex-command-triggers` region in `AGENTS.md`) and existing skills each need their flag; content you wrote is never rewritten or migrated automatically.**
36
+
37
+ ## How existing files are treated
38
+
39
+ - **Pristine Dflow shims** (fully generated, never edited by you) → regenerated in place.
40
+ - **Files that already contain a Dflow marker block** → only the block's interior is refreshed; everything outside is preserved.
41
+ - **Existing agent files that do not yet point at the canonical guide** → a marker-managed block is appended at the end after you confirm the overall preview.
42
+ - **Agent files you wrote yourself that already point at the canonical guide** → init leaves them untouched (it only warns); an **interactive `configure-agents`** run offers to append the marker-managed block (default **No**), and non-interactive runs always skip with a warning.
43
+ - **A damaged or conflicting `agent-shim` marker in an agent file** → your file is left untouched; the content to merge is written as a merge snippet under `dflow/specs/shared/` for you to merge by hand.
44
+ - **A damaged `codex-command-triggers` marker in `AGENTS.md`** → the untouched-file + merge-snippet handling applies only on runs where `--command-adapters` manages that region; flagless runs leave the damaged trigger region alone and still refresh the same file's `agent-shim` region normally — provided the trigger markers do not overlap or straddle the shim region; when they do, even a flagless run leaves the whole file untouched and falls back to a merge snippet.
45
+ - **A damaged `guide-canonical` marker in `AI-AGENT-GUIDE.md`** → the guide is left untouched; you get instructions to repair or remove the markers (no merge snippet is produced).
46
+ - **An `AI-AGENT-GUIDE.md` created by an older version, without markers** → an interactive `configure-agents` run offers marker adoption. **Mind the cost of accepting**: the guide is rebuilt from the packaged template — only your `## Project Context` is preserved and **every other customized section is replaced**; if you edited other sections, decline and merge by hand instead. Until adopted, `dflow doctor` reports the file as frozen and it is never refreshed automatically.
47
+ - **A damaged `git-principles-canonical` marker in `Git-principles-{policy}.md`** → your file is left untouched; you get instructions to repair or remove the markers (no merge snippet is produced). `dflow doctor` reports this state on its own and never as "predates the markers" — a file broken by an edit must not be offered a rewrite of sections nobody has re-read.
48
+ - **A `Git-principles-{policy}.md` created by an older version, without markers** → an interactive `configure-agents` run offers marker adoption. **This offer is much narrower than the guide's**: only sections 1-5 are replaced with this version's content, while the file header (including the `> Created:` date you filled in) and everything from `## 6. AI Collaboration Rules (Project Policy)` down — your CI / CD section included — is kept exactly as you wrote it. (One normalization applies to the whole file, as it always has: line endings are unified to whichever the file already uses most, so a file with *mixed* endings comes back consistent rather than byte-identical.) Decline only if you customized something inside sections 1-5. Until adopted, `dflow doctor` reports the canonical sections as frozen and they are never refreshed automatically.
49
+ ⚠ **Trunk projects, one extra note**: older starters put adopter choices inside the canonical region — for greenfield, the merge strategy in `## 3.`; for brownfield, that **plus** the "do we require Conventional Commits" choice in `## 2.`. Those *choices* now live under `## 6.`, with the trade-offs left where they were. Because `## 6.` is outside the region, `configure-agents` will **not** add that subsection for you — record your choice there yourself after upgrading.
50
+ - **A `Git-principles-{policy}.md` Dflow cannot recognize** (its `## 1. Branch Structure` and `## 6. AI Collaboration Rules (Project Policy)` headings are not both present exactly once) → left untouched with a warning, and no adoption is offered: without both anchors there is no way to tell where the canonical sections end and yours begin.
51
+
52
+ ## First step after upgrading: `dflow doctor`
53
+
54
+ ```bash
55
+ dflow doctor
56
+ ```
57
+
58
+ doctor is a **read-only** check — it reports and never writes. Upgrade-relevant checks include:
59
+
60
+ - the reconciliation version in `_conventions.md` lagging behind the current CLI
61
+ - policy sections missing from `_conventions.md` (`## Git Policy` / `## AI Commit Policy` / `## Prose Language`) — named individually, with how to restore each
62
+ - policy sections that are no longer machine-readable
63
+ - `_conventions.md` being **missing entirely, or empty**
64
+ - `_conventions.md` **content sections** lagging the current contract — a current rule absent, or wording PROPOSAL-082 retired still present (the escalate-only rule in Ceremony Scaling, the no-BR families in Filling the Templates, the minimal-host exception in SPEC-ID Format). Named section by section, with what to restore
65
+ - a frozen (marker-less) guide, or bundle `§` references pointing at sections that no longer exist
66
+ - the `Git-principles-{policy}.md` starter for your selected Git policy being missing, or its **canonical sections 1-5** differing from this version — reported apart from three other states: markers not yet adopted, markers damaged, and an installed package whose own packaged starter is unusable. Only sections 1-5 are compared, so your own sections never show up as drift
67
+ - feature `_index.md` files under `features/active/` still in an older template shape (`completed/` is not scanned) — for a dashboard without a shape marker; one that carries a marker is judged by the next check
68
+ - spec docs whose **shape marker** is older or newer than the current template's, missing, or unreadable — out of place, damaged, or not the only one (see [Shape markers](#shape-markers))
69
+ - agent files that point at the canonical guide but are not managed by Dflow
70
+ - a **partially installed** set of command entries — `.claude/commands/dflow/` or `.github/prompts/dflow-*.prompt.md` holding some of the 11 but not all, and `0.5.0`-era filenames left behind. ⚠ A set that is entirely absent is **not** reported; see the ownership table above
71
+ - a Dflow-generated `SKILL.md` (Claude, Codex, or Copilot) whose content has fallen behind this CLI — its `description` frontmatter is what a tool matches on to auto-engage, so a stale copy keeps an older trigger boundary. A `SKILL.md` without the Dflow marker is yours and is never reported
72
+ - a `.dflow-bundle-manifest.json` that exists but cannot be read or parsed. A manifest that has never been written is a normal state and stays silent; a damaged one is reported, because it silently disables both the bundle-version check and the edition every other check asks it for
73
+
74
+ ⚠ Several of these checks used to switch themselves off when a value they read was absent — a missing `## Git Policy` section, an edition that could not be inferred, an unreadable packaged template — and said nothing about having done so. They no longer do: where the check can still be made without the value it is now made against every candidate, and where it genuinely cannot be, doctor says which checks did not run. Expect an upgraded project in one of those states to surface findings it was not shown before; they were always true.
75
+
76
+ ## Thorough verification (the baseline procedure)
77
+
78
+ doctor is the first pass. To fully confirm nothing was missed, use the clean-comparison baseline:
79
+
80
+ 1. Run a fresh `dflow init` somewhere else with the **same edition and the same answers** (and the same CLI version).
81
+ 2. Diff it file by file against your project.
82
+ 3. Every difference should classify as one of three things: "your user content", "a known outside-the-markers region", or **"a section a newer template added that your project predates"**. The third class has two routes: `dflow doctor` (previous section) names the missing sections it recognizes and tells you how to restore them; for anything doctor does not name, see `CHANGELOG.md` (currently zh-TW only), where the release entry says what the section is and whether to adopt it — and, where placement matters, where it goes (e.g. P-083 restoring `### SPEC-ID Format` and `### Slug Conventions` to `_conventions.md` notes they belong above `## Prose Language`). Of that pair, doctor now names `### SPEC-ID Format` directly; `### Slug Conventions` has no fingerprint, so it remains a CHANGELOG-only case. Anything that fits none of the three is a missed fix — handle it item by item.
83
+ ⚠ One difference is none of the three and is **not** to be copied across: the `<!-- dflow-shape: ... -->` line at the top of a fresh doc. Its number states which template shape a doc was compared against, so give your existing docs one only through the procedure in [Shape markers](#shape-markers).
84
+
85
+ ## Shape markers
86
+
87
+ Every template a Dflow flow creates a spec doc from carries one line, and the doc takes it along:
88
+
89
+ ```markdown
90
+ <!-- dflow-shape: greenfield/rules.md 1 — keep this line: dflow doctor reads it -->
91
+ ```
92
+
93
+ It records **which track's template, and which shape number of it, the doc was written against** — like the version number printed on a paper form. It is the first line of the doc, or the line right after the frontmatter when the doc has one. The rendered page does not show it; leave it where it is. Doctor reads it from that line only, and the text after the number (`— keep this line: …`) is optional. If any other line in the doc contains `dflow-shape:` — a marker quoted as an example, or an old one commented out, included — doctor does not judge the doc and reports it as unreadable instead: it does not decide which of those lines is the live marker.
94
+
95
+ **Which docs carry one.** The docs flows create from the workflow bundle's templates — `glossary.md`, `context-map.md`, a context's `models.md`, `rules.md`, `behavior.md`, `analysis.md` and `context.md`, `tech-debt.md` (plus `events.md` on greenfield), and in a feature directory `_index.md`, the phase specs and the lightweight specs (plus `aggregate-design.md` on greenfield) — and `shared/_overview.md`. Not `_conventions.md`, `Git-principles-*.md`, `AI-AGENT-GUIDE.md`, the agent snippets, or the ADR folder's README.
96
+
97
+ **What `dflow doctor` does with it.** It compares the number with the current number of the same template, in the CLI you have installed:
98
+
99
+ | The doc's marker | `dflow doctor` |
100
+ |---|---|
101
+ | Same number | Nothing. Wherever the doc differs from the template, that is your decision |
102
+ | Older number | One `info` listing the docs, the two numbers, and what changed in between, in three kinds:<br>**added** — a section, a column or a frontmatter field: you can add these;<br>**renamed, split, moved or removed** — reported only: you decide how to adapt;<br>**notes, comments and section order** — `>` notes, HTML comments, the order of the sections: they do not change the doc's structure, and you (with your AI assistant) decide whether to bring the doc in line |
103
+ | Newer number | One `warn`: your CLI is older than the doc — upgrade it |
104
+ | No marker | One `info` listing the docs; this check does **not** judge their shape (next section). A feature `_index.md` without a marker still gets the older-template check listed above |
105
+ | Unreadable (not on the marker's line, damaged, or more than one line containing `dflow-shape:`) | One `uncertain`, `unreadable-shape-marker` ([doctor-uncertainty.en.md](doctor-uncertainty.en.md)), with the line numbers and what to do |
106
+
107
+ Doctor checks the docs under `dflow/specs/`, except `shared/` — Dflow's own files; of those only `shared/_overview.md` is checked — and, under `features/`, anything outside `active/`: `completed/` and `backlog/` are never checked. When your project's workflow bundle comes from a newer Dflow than the installed CLI, doctor skips this check and says so: it would be comparing your docs against templates older than the ones your project uses.
108
+
109
+ ### Adding markers to docs that have none (once)
110
+
111
+ Docs created before the release that introduced markers have none, so doctor lists them and leaves their shape alone — it will not guess which differences the template made and which you made. Adding the markers is a one-time job, best done with your AI assistant, doc by doc, **with you judging each difference**:
112
+
113
+ 1. **Use the current templates.** If doctor says your workflow bundle is older than the CLI, run `dflow configure-agents` first. `_overview.md` is not in the bundle: use `templates/<track>/scaffolding/_overview.md` in the installed package, or run `dflow init` in a scratch directory.
114
+ 2. **Confirm the track** (greenfield or brownfield) — the marker names it.
115
+ 3. **Compare the doc with its template**: the `##` and `###` headings and their order, each table's header row, the frontmatter fields, and the `>` notes and HTML comments. Ignore example headings and rows (anything with a `{…}` placeholder), other prose, and — in a lightweight spec written in a no-BR family — `## Root Cause` and the change-type subsection under `## Behavior Delta`, which the family replaces on purpose.
116
+ 4. **Judge every difference.** Something the template added after the doc was written → add the shape: the section; or the column, with `{TBD}` in existing rows and a comment above the table saying what the value is, when to backfill it and how to tell it is done; or the frontmatter field. Add the shape, not the content. Something the template renamed, split, moved or removed after the doc was written → decide how to adapt the doc yourself: carrying the template's version in beside yours would leave the old and the new side by side. Something you chose → keep it exactly as it is. (A project that writes one `## Rules` section where the template has three is making a choice; the marker is what lets doctor stop calling it drift.) Notes, comments and section order do not change the doc's structure: bring them in line with the template or keep yours — either is fine.
117
+ 5. **Add the marker line**, copied from the current template, at the top of the doc — or right after its frontmatter.
118
+
119
+ ⚠ **The number is a conclusion you reached, not a step to automate.** A current number on a doc that still has an older shape makes doctor silent about that doc from then on — the one mistake doctor cannot detect.
120
+ ⚠ **Leave a zero-phase feature that has not closed out alone** — a minimal host: a feature directory holding one small change, with an empty Phase Specs table and no phase spec. Its closeout takes exactly two commits and allows only a closed list of changes, so a marker added now would block it. Doctor lists those docs apart; at closeout they move to `features/completed/`, which is not checked. A feature whose Phase Specs table is empty while its directory holds a phase spec is one doctor cannot place, so it lists those docs apart too: leave them alone if the feature is a minimal host, and handle them like the rest if it is not.
121
+ ⚠ **Do not copy a whole template head into an older doc** — for example to pick up the table-formatting comment. The head carries the template's current marker.
122
+
123
+ A prompt you can give your AI assistant:
124
+
125
+ ```text
126
+ For each doc `dflow doctor` lists as having no shape marker — except the ones it says to leave alone until closeout (for a feature doctor cannot place, ask me first whether it is a minimal host) — compare it with its current template under dflow/specs/shared/dflow-workflows/templates/ (for shared/_overview.md: templates/<track>/scaffolding/_overview.md in the installed dflow package). Compare the ## and ### headings and their order, each table's header row, the frontmatter fields, and the > notes and HTML comments; ignore {…} placeholder headings and rows, other prose, and the sections a lightweight spec's no-BR family replaces. List every difference and ask me, one at a time, whether the template added it later, the template renamed, split, moved or removed it later, or I chose it; for a note, a comment or the section order, ask me whether to bring the doc in line. For template additions, add the shape only: the section, the column (existing rows get {TBD}, plus a comment above the table saying what the value is, when to backfill it and how to tell it is done) or the frontmatter field. For a rename, split, move or removal, show me the doc's version and the template's and let me decide how to change the doc — never keep both side by side. Keep my choices as they are. Then copy the template's <!-- dflow-shape: ... --> line into the doc, as its first line or right after its frontmatter. Change nothing else.
127
+ ```
128
+
129
+ ### When a template's number goes up
130
+
131
+ After an upgrade, doctor lists the docs that are behind and what changed. For each **added** item, add the shape as in step 4 above. For each **renamed, split, moved or removed** item, decide how to adapt the doc yourself — adding blindly would leave the old and the new section side by side. **Notes, comments and section order** do not change the doc's structure: compare them with the current template and decide whether to bring the doc in line. When the doc is handled — added to, brought in line, or a difference kept on purpose — change the number on its marker line to the current one; until then doctor reports it on every run.
132
+
133
+ ### What the marker does not cover
134
+
135
+ Each of these was considered and deliberately left open, because closing it would cost every run — or every adopter — more than the failure it prevents. You carry them; where it applies, each says when it would be looked at again.
136
+
137
+ - **A doc created without the marker line.** Nothing makes an AI copy the line when it creates a doc from a template; the line says why it is there, which makes losing it less likely, not impossible. Such a doc falls back to "no marker" — possibly in a new project right after its first feature. Closing this for sure would take an instruction in every flow that creates a doc, read on every run. *Looked at again if* the line turns out to be dropped often in practice.
138
+ - **A marker deleted or damaged later** falls back to "no marker" or "unreadable". Doctor says so, and never treats such a doc as current.
139
+ - **A marker quoted as an example, or an old one commented out**: doctor does not decide whether such a line is the live marker, so it reports the doc as unreadable — one more thing to handle, in exchange for never reporting a doc it cannot read as passing.
140
+ - ⚠ **A valid but wrong number** — for example a template head copied onto an older doc — reads as the current shape, and doctor stays silent. This one cannot be detected: nothing in the doc tells a right number from a wrong one.
141
+ - **Changes outside the shape.** A shape is the `##` / `###` headings and their order, table header rows, frontmatter fields, notes in `>` blocks (tables in them included) and HTML comments — most of what a template tells the AI about filling it in is in its comments, and so are the definitions of a lightweight spec's no-BR families. Fixed label text, the rows of a vocabulary table (such as `rules.md`'s Status Legend), `####` and below, `#` comments in frontmatter, and other prose do not change a template's number, so doctor never reports them. *Looked at again if* such a change turns out to matter to a real project.
142
+ - **Same number, no report — including a section an AI deleted by mistake**, not only one you removed on purpose. That is the price of "same number means your decision".
143
+ - **Unmarked docs at paths the flows do not use** — renamed or moved ones — are not listed as missing a marker; doctor says nothing about them. Within the part of `dflow/specs/` doctor checks (above), a doc that carries a marker is judged by it wherever it sits.
144
+ - **Shape added, number not changed**: doctor reports the doc again on the next run. Change the number when you are done.
145
+ - **On Dflow's side**, a released shape number is protected by a checksum in Dflow's own test suite; a change that rewrites both a shape and its checksum is caught only by review.
146
+ - **The marker records which template shape a doc was compared against — not that its content is right.**
147
+
148
+ ## Extra steps for `0.15.0`
149
+
150
+ > ⚠ **This section applies only to `0.15.0`** (the release containing P-082 /
151
+ > P-083). If you are on 0.14.0, the router wording described below does not exist
152
+ > yet — skip it (`dflow --version` confirms).
153
+
154
+ `0.15.0` replaces the wording that decides **when Dflow engages at all**. The
155
+ old exclusion was unqualified — refactors, renames, chores, formatting and
156
+ dependency bumps never triggered, and the root shim additionally said "you need
157
+ not read the guide first". But the cascade in the same release classifies a
158
+ security / CVE dependency bump, an operational-axis refactor (payment, safety,
159
+ compliance), and a Domain / schema rename as work that **must** enter the
160
+ workflow. Keeping the old wording keeps a trigger that silently declines
161
+ security-class work — and nothing surfaces it on its own, because no test can see
162
+ a trigger that decides not to fire.
163
+
164
+ Two carriers, handled separately:
165
+
166
+ - **The skill** (`.claude/skills/dflow/`, `.agents/…`, `.github/…`) → run
167
+ `dflow configure-agents --skills`. A flagless run does **not** regenerate an
168
+ existing skill (see the ownership table above), so the flag is required.
169
+ - **The root shim** (`CLAUDE.md` / `AGENTS.md` /
170
+ `.github/copilot-instructions.md`) → depends on whether you edited it:
171
+ - **An unedited whole-file Dflow shim** → a flagless `dflow configure-agents`
172
+ regenerates it in place. **Every shim body `dflow init` has generated since
173
+ v0.1.1 is recognized** — all three (the v0.1.1–v0.7.0 pre-bundle form, the
174
+ **0.8.0–v0.9.0** pre-scoping form, and the 0.10.0–0.14.0 scoped form) — so
175
+ none of them is mistaken for a file you wrote.
176
+ **v0.1.0 is the exception**: that release wrote `CLAUDE.md` through a
177
+ different path, from the packaged snippet with project-specific values
178
+ substituted in, so there is no fixed body to match. Such a file is treated
179
+ as one you maintain — `dflow doctor` reports it and the routine paragraph
180
+ has to be replaced by hand.
181
+ - **A file carrying `agent-shim` markers** → only the text inside the markers is
182
+ refreshed; everything outside is preserved.
183
+ - **A file you edited that has no markers** → Dflow leaves it alone. `dflow
184
+ doctor` reports this state; replace the routine paragraph by hand, or accept
185
+ the managed marker block in an interactive `configure-agents` and let it
186
+ regenerate afterwards.
187
+
188
+ To tell the two apart: the new routine paragraph contains "**Routine is narrower
189
+ than it sounds**" and hands the decision back to the guide's § Ceremony Scaling.
190
+ The old one does not.
191
+
192
+ ## Version-compatibility notes
193
+
194
+ - Re-project with the **same CLI version you are aligning to**: upgrade the CLI first, then run `dflow configure-agents`.
195
+ - Avoid running an **older** CLI against a newer project layout — it can project outdated content back over newer files.
196
+ - For version-control recommendations and gitignore snippets for generated artifacts (command adapters / skills), see the "Version-control policy for generated artifacts" section of the [README](../README.en.md) and the per-tool guides in `docs/`.