dflow-sdd-ddd 0.14.0 → 0.16.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 (100) hide show
  1. package/CHANGELOG.md +915 -0
  2. package/CONTRIBUTING.md +11 -1
  3. package/README.en.md +160 -212
  4. package/README.md +93 -147
  5. package/TEMPLATE-COVERAGE.md +13 -6
  6. package/TEMPLATE-LANGUAGE-GLOSSARY.md +15 -1
  7. package/bin/dflow.js +90 -4
  8. package/docs/closeout-check.en.md +204 -0
  9. package/docs/closeout-check.md +204 -0
  10. package/docs/commands.en.md +112 -0
  11. package/docs/commands.md +103 -0
  12. package/docs/doctor-uncertainty.en.md +212 -0
  13. package/docs/doctor-uncertainty.md +212 -0
  14. package/docs/evaluating-dflow.en.md +29 -11
  15. package/docs/evaluating-dflow.md +8 -6
  16. package/docs/release-versioning-policy.md +6 -0
  17. package/docs/upgrading.en.md +196 -0
  18. package/docs/upgrading.md +197 -0
  19. package/docs/using-with-claude-code.en.md +13 -4
  20. package/docs/using-with-claude-code.md +13 -4
  21. package/docs/using-with-codex.en.md +13 -4
  22. package/docs/using-with-codex.md +13 -4
  23. package/docs/using-with-github-copilot.en.md +13 -4
  24. package/docs/using-with-github-copilot.md +13 -4
  25. package/lib/closeout-check.js +690 -0
  26. package/lib/doc-shapes.json +1195 -0
  27. package/lib/doctor-checks.js +2500 -24
  28. package/lib/init.js +2861 -143
  29. package/lib/render-diagrams.js +1474 -0
  30. package/lib/render.js +865 -49
  31. package/package.json +2 -2
  32. package/templates/brownfield/references/drift-verification.md +4 -0
  33. package/templates/brownfield/references/finish-feature-flow.md +648 -98
  34. package/templates/brownfield/references/finish-feature-follow-up.md +60 -0
  35. package/templates/brownfield/references/finish-feature-minimal-host.md +427 -0
  36. package/templates/brownfield/references/finish-feature-post-hoc-hotfix.md +95 -0
  37. package/templates/brownfield/references/finish-feature-record-correction.md +45 -0
  38. package/templates/brownfield/references/git-integration.md +205 -26
  39. package/templates/brownfield/references/init-project-flow.md +23 -3
  40. package/templates/brownfield/references/modify-existing-flow.md +439 -88
  41. package/templates/brownfield/references/modify-existing-follow-up.md +122 -0
  42. package/templates/brownfield/references/modify-existing-post-hoc-hotfix.md +200 -0
  43. package/templates/brownfield/references/new-feature-flow.md +110 -37
  44. package/templates/brownfield/references/new-phase-flow.md +59 -9
  45. package/templates/brownfield/references/pr-review-checklist.md +328 -10
  46. package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +151 -34
  47. package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +1 -1
  48. package/templates/brownfield/scaffolding/Git-principles-gitflow.md +85 -8
  49. package/templates/brownfield/scaffolding/Git-principles-trunk.md +88 -10
  50. package/templates/brownfield/scaffolding/_conventions.md +50 -28
  51. package/templates/brownfield/scaffolding/_overview.md +1 -0
  52. package/templates/brownfield/templates/_index.md +158 -10
  53. package/templates/brownfield/templates/analysis.md +79 -0
  54. package/templates/brownfield/templates/behavior.md +1 -0
  55. package/templates/brownfield/templates/context-definition.md +1 -0
  56. package/templates/brownfield/templates/context-map.md +2 -1
  57. package/templates/brownfield/templates/glossary.md +1 -0
  58. package/templates/brownfield/templates/lightweight-spec.md +154 -11
  59. package/templates/brownfield/templates/models.md +1 -0
  60. package/templates/brownfield/templates/phase-spec.md +9 -1
  61. package/templates/brownfield/templates/rules.md +1 -0
  62. package/templates/brownfield/templates/tech-debt.md +1 -0
  63. package/templates/common/references/ddd-modeling-guide.md +33 -16
  64. package/templates/{greenfield → common}/references/dflow-feedback-flow.md +2 -1
  65. package/templates/common/references/flow-rationale-registry.md +146 -0
  66. package/templates/common/skill/SKILL.md +13 -11
  67. package/templates/greenfield/references/drift-verification.md +4 -0
  68. package/templates/greenfield/references/finish-feature-flow.md +639 -100
  69. package/templates/greenfield/references/finish-feature-follow-up.md +60 -0
  70. package/templates/greenfield/references/finish-feature-minimal-host.md +383 -0
  71. package/templates/greenfield/references/finish-feature-post-hoc-hotfix.md +95 -0
  72. package/templates/greenfield/references/finish-feature-record-correction.md +45 -0
  73. package/templates/greenfield/references/git-integration.md +193 -26
  74. package/templates/greenfield/references/init-project-flow.md +23 -3
  75. package/templates/greenfield/references/modify-existing-flow.md +395 -87
  76. package/templates/greenfield/references/modify-existing-follow-up.md +104 -0
  77. package/templates/greenfield/references/modify-existing-post-hoc-hotfix.md +200 -0
  78. package/templates/greenfield/references/new-feature-flow.md +116 -35
  79. package/templates/greenfield/references/new-phase-flow.md +58 -9
  80. package/templates/greenfield/references/pr-review-checklist.md +311 -8
  81. package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +146 -32
  82. package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +5 -2
  83. package/templates/greenfield/scaffolding/Git-principles-gitflow.md +84 -8
  84. package/templates/greenfield/scaffolding/Git-principles-trunk.md +94 -14
  85. package/templates/greenfield/scaffolding/_conventions.md +50 -28
  86. package/templates/greenfield/scaffolding/_overview.md +6 -2
  87. package/templates/greenfield/templates/_index.md +145 -10
  88. package/templates/greenfield/templates/aggregate-design.md +1 -0
  89. package/templates/greenfield/templates/analysis.md +79 -0
  90. package/templates/greenfield/templates/behavior.md +1 -0
  91. package/templates/greenfield/templates/context-definition.md +1 -0
  92. package/templates/greenfield/templates/context-map.md +2 -1
  93. package/templates/greenfield/templates/events.md +4 -1
  94. package/templates/greenfield/templates/glossary.md +1 -0
  95. package/templates/greenfield/templates/lightweight-spec.md +154 -11
  96. package/templates/greenfield/templates/models.md +1 -0
  97. package/templates/greenfield/templates/phase-spec.md +9 -1
  98. package/templates/greenfield/templates/rules.md +1 -0
  99. package/templates/greenfield/templates/tech-debt.md +1 -0
  100. package/templates/brownfield/references/dflow-feedback-flow.md +0 -251
@@ -11,7 +11,7 @@ Crossing any step gate above also updates the host feature's `_index.md` Resume
11
11
 
12
12
  All other step transitions are **step-internal**: announce "Step N complete, entering Step N+1" and proceed without waiting. See AI-AGENT-GUIDE.md § Workflow Transparency for the full transparency protocol and confirmation signals.
13
13
 
14
- **Ceremony adjustment when triggered by `/dflow:bug-fix`**: treat as lightweight — use the Lightweight Spec Template (see `templates/lightweight-spec.md`) instead of the full spec, and Step 4 (extraction) may default to "defer and record in tech-debt.md" unless the bug itself is in extractable logic. T2 still generates a concise `Implementation Tasks` checklist (see Step 4).
14
+ **Ceremony when triggered by `/dflow:bug-fix`**: the command does **not** set a tier — run the same ordered cascade as any other modification (Part A below). Most functional defects land **T2**, so the Lightweight Spec Template (`templates/lightweight-spec.md`) is the usual outcome, and Step 4 (extraction) may default to "defer and record in tech-debt.md" unless the bug itself is in extractable logic; T2 still generates a concise `Implementation Tasks` checklist (see Step 4). That is the usual landing, not a fixed set: the cascade also puts defects below T2 and above it, through any of its steps — not only via a Domain structural redesign. Let the cascade decide.
15
15
 
16
16
  ## Mindset
17
17
 
@@ -31,40 +31,114 @@ through `/dflow:bug-fix`.
31
31
 
32
32
  This step has two parallel concerns:
33
33
 
34
- **Part A — Determine the Ceremony Tier (T1 / T2 / T3)**
35
-
36
- Dflow runs three ceremony tiers (full table in AI-AGENT-GUIDE.md § Ceremony Scaling).
37
- For a modification, AI judges which tier fits before deciding what to
38
- produce:
39
-
40
- | Tier | When to choose | Production |
41
- |---|---|---|
42
- | **T1 Heavy** | Architectural change / new BR / new Domain concept / new data structure → escalate to `/dflow:new-phase` (if extending an active feature) or `/dflow:new-feature` (if it's truly a new concern) | Full phase-spec via the appropriate flow |
43
- | **T2 Light** | Bug fix / UI input validation tweak / flow branch change — **has BR Delta** but no Domain or data-structure overhaul | Independent `lightweight-{date}-{slug}.md` placed in feature directory + outbound-link row in `_index.md` Lightweight Changes |
44
- | **T3 Trivial** | Button colour / copy fix / typo / formatting / pure comments — **all four T3 criteria** must hold (no BR change, no Domain concept change, no data structure change, only UI surface / comments / formatting) | **Inline row in `_index.md` Lightweight Changes only** (no independent spec file) |
45
-
46
- If any T3 criterion fails → drop to T2. If Domain / BR / data structure
47
- is touched → escalate to T1.
48
-
49
- **Below T3** (pure typo, formatting commit) → tell the developer Dflow
50
- doesn't track this and they can `git commit` directly.
34
+ **Part A — Determine the Ceremony Tier (T1 / T2 / T3 / below workflow)**
35
+
36
+ The tier has **one source**: `AI-AGENT-GUIDE.md` § Ceremony Scaling — the
37
+ ordered cascade, steps 0–4, where **the first step that matches wins**. **Open
38
+ that section and classify from it before going further.** Do not classify from
39
+ memory, from this flow's step headings, or from a summary: the cases that
40
+ actually decide a tier — new work versus a modification, what stays below
41
+ workflow, how far a T3 may reach, inbound contracts, compound requests — are
42
+ settled there, and a second copy of those criteria here would be a second answer
43
+ to the same question.
44
+
45
+ Two of the cascade's outcomes leave this flow entirely: genuinely new work
46
+ (`/dflow:new-feature`) and a change Dflow does not track. Take those two exits as
47
+ the guide states them rather than continuing through the steps below.
48
+
49
+ **Tier-aware routing (don't run heavier ceremony than the tier needs):**
50
+
51
+ - **T3** → locate the host, then **skip the Domain / extraction work**: go to the
52
+ branch gate, implement, and record the inline `_index.md` row. Do **not** create
53
+ or update any spec file, and do **not** run the Step 2 Document-Current-Behavior
54
+ baseline capture, the Step 3 delivery-layer analysis, or the Step 4
55
+ Evaluate-Extraction-Opportunity step (a T3 produces no baseline / extraction /
56
+ tech-debt entries unless the request is itself about them).
57
+ - **T2** → a lightweight-spec at the depth the change needs; run the
58
+ behavior-capture / layer steps only where the change actually touches them.
59
+ - **Observation-only (tier-exempt, step 0)** → record the capture where it belongs
60
+ (BC-layer `behavior.md` and `analysis.md`, `domain/analysis.md` for a
61
+ cross-context flow, for role reach and for whatever else no one context owns,
62
+ a hotspot in the copy that holds the knowledge it is stuck on,
63
+ `tech-debt.md`, the host's Resume Pointer) and stop there; create either
64
+ `analysis.md` from `templates/analysis.md` the first time there is something to
65
+ record.
66
+ When the baseline capture needs its own host (no active feature to attach
67
+ it to), open a **baseline minimal host**: a related **completed** feature makes it
68
+ a follow-up (Step 1.6 minimal variant), otherwise it is standalone (Step 1.7) —
69
+ both are tier-exempt, cut `feature/{SPEC-ID}-{slug}`, and record a `Tier = baseline`
70
+ row rather than a change. Do not invent a spec for it, and do not read the
71
+ cascade's "below workflow" as permission to skip the record. A baseline
72
+ minimal host does not stop at the capture: it goes on through Step 6 and
73
+ offers its first checkpoint (`spec-baseline`) at § 6.5 (Step 1.7 says how).
74
+ A capture about no bounded context at all — the role reach of functions that
75
+ belong to no context yet, say — is not a baseline capture and opens no host:
76
+ with no active feature to attach it to, record it and offer to commit that
77
+ record on its own.
78
+ - **T1** → escalate to `/dflow:new-phase` (extending an active feature) or
79
+ `/dflow:new-feature` (a truly new concern); full ceremony via that flow.
51
80
 
52
81
  **Part B — Locate the Feature this Change Belongs To**
53
82
 
54
- Walk through these in order:
83
+ Walk through these in order to **classify** the change. Do **not** jump to
84
+ Step 1.5 / 1.7 mid-list: the in-flight overlap scan (item 4) and the hotfix
85
+ check below both run first, and the actual routing to Step 1.5 / 1.6 / 1.7 /
86
+ 1.8 / Step 2 happens at this step's closing transition.
55
87
 
56
88
  1. **Active features**: scan `dflow/specs/features/active/*/_index.md`. Does
57
89
  the change belong inside an existing active feature directory? If
58
90
  yes, use that as the host (T1 → `/dflow:new-phase`; T2 → place
59
91
  lightweight-spec inside; T3 → inline row in that `_index.md`).
92
+ **Exception — a minimal (zero-phase) host that has already taken its
93
+ implementation (or `spec-baseline`) checkpoint is not an eligible host.** A
94
+ minimal host is fixed at two commits and **every** Lightweight Changes row
95
+ must belong to the first one (Step 1.7), so once that checkpoint has landed
96
+ it can accept nothing further, however well it fits. It does **not** become
97
+ this change's host, and for the rest of this walk it does not count as one —
98
+ keep scanning, and let the routing at this step's closing transition proceed
99
+ as if it were not there. (Item 4 still surfaces it as an overlap; that is
100
+ information for the developer, not a host.) **Before** that checkpoint lands
101
+ the host is still open, and a compound request legitimately records more than
102
+ one **T2 / T3** artifact under it ("minimal means zero-phase, not
103
+ one-artifact", Step 1.7) — but **never a phase**: a minimal host is
104
+ *defined* by carrying no `phase-spec-*`, so it is not an eligible host for a
105
+ **T1** at any point, before or after that checkpoint. Keep scanning, exactly
106
+ as above.
107
+ **Exception — an already-merged T2 / T3 emergency fix** (the callout
108
+ below): it is already on the mainline, so an in-flight host cannot hold
109
+ it. It takes **Step 1.8** and gets a host of its own there, however well
110
+ a related active feature seems to fit — Step 1.8 says why. A **T1**
111
+ post-hoc is unaffected and uses this route normally.
60
112
  2. **Completed features**: scan `dflow/specs/features/completed/*/_index.md`
61
113
  Goals & Scope sections. If the change description is semantically
62
- related to a completed feature, this becomes the **completed feature
63
- reopen** scenario — go to Step 1.5 below.
64
- 3. **Standalone**: if no related feature exists (active or completed),
65
- this is a new concern. For T1, use `/dflow:new-feature`. For T2 / T3
66
- on a standalone bug, see Step 1.5 — `/dflow:bug-fix` will create a
67
- minimal feature directory to host the lightweight-spec.
114
+ related to a completed feature, this is the **completed-feature-reopen**
115
+ case (Step 1.5, routed to at the closing transition) — with **two
116
+ exceptions that never reach the Step 1.5 A/B/C prompt**: a **T2 / T3**
117
+ already-merged emergency fix documented after the fact takes **Step 1.8**
118
+ (the callout below), and an **observation-only baseline capture** takes
119
+ **Step 1.6** directly (Part A already routed it). This scan still runs for
120
+ both — each needs to know whether a related completed feature exists in
121
+ order to pick its own host (follow-up when one relates, standalone
122
+ otherwise). (A **T1** post-hoc is not a Step 1.8 case at all and does reach
123
+ Step 1.5 normally.)
124
+ 3. **Standalone**: if no related feature exists (active or completed) that can
125
+ host this change — a host item 1 ruled **ineligible** does not count as one —
126
+ this is a new concern. For T1, use `/dflow:new-feature`. A standalone
127
+ T2 / T3 needs a **minimal host feature directory** to hold the change —
128
+ its open → record → close lifecycle is the **standalone** case (Step 1.7,
129
+ routed to at the closing transition). Do not improvise a host and do not
130
+ leave an empty one behind. (If a related active feature genuinely fits
131
+ after all, use it as the host instead.)
132
+ **Exception — an already-merged T2 / T3 emergency fix** (the callout
133
+ below): finding nothing related does **not** make it an ordinary standalone.
134
+ It still routes through **Step 1.8**, which picks standalone itself and
135
+ supplies what this item cannot — the `reconciled (...)` checkpoint, the
136
+ per-tier hotfix trace, and reconcile-instead-of-re-implement. Coming to
137
+ Step 1.7 straight from here drops all of that. A **T1** post-hoc is
138
+ unaffected and uses this route normally. An observation-only **baseline
139
+ capture** with nothing related also reaches Step 1.7, but by **Part A's**
140
+ observation-only routing, not by this item — it is tier-exempt, so this
141
+ item's "standalone T2 / T3" wording does not describe it.
68
142
  4. **In-flight overlap scan (cross-branch)**: this branch's `active/` is not
69
143
  everything in flight. Run the in-flight scan (classification and dedup
70
144
  rules in `AI-AGENT-GUIDE.md` § Status / Control Commands) — `git fetch`
@@ -75,19 +149,51 @@ Walk through these in order:
75
149
  awaiting integration, or unknown — or an unfinished feature — semantically
76
150
  overlaps this change, surface it and wait for the developer to decide
77
151
  before creating anything new (stale branches are non-blocking).
152
+ **Exception — an already-merged T2 / T3 emergency fix** (the callout
153
+ below): run the scan, but a surfaced overlap is **information, not a
154
+ blocker**. The fix is already on the mainline, so no unmerged feature branch
155
+ can host it (Step 1.8 says why) — there is no routing choice left to wait
156
+ for. Report the overlap as notice that a merge reconciliation is coming
157
+ (`finish-feature-flow.md` Step 5), then let Step 1.8 proceed: do not offer
158
+ the in-flight feature as a host and do not hold host creation on it.
159
+ Step 1.7's overlap scan states the same rule at the point of use. A **T1**
160
+ post-hoc is unaffected and waits normally, and so does a **baseline
161
+ capture** — an overlapping in-flight feature may well be the right place to
162
+ attach the capture, which is precisely the decision this item asks for.
78
163
 
79
164
  > **Why scan completed too?** Completed features are frozen history
80
165
  > and **cannot accept** any T2 / T3 directly
81
166
  > (would break the "completed = frozen" semantic). Reopen routes through
82
- > a new follow-up feature instead — see Step 1.5.
83
-
84
- **→ Transition (step-internal)**: Step 1 complete. Announce "Step 1 complete (tier {T1/T2/T3} decided, host feature {SPEC-ID-slug / new / follow-up} identified). Entering Step 1.5 / Step 2 as appropriate." and continue.
85
-
86
- ## Step 1.5: Completed-Feature Reopen Detection (only if Step 1 found a related completed feature)
167
+ > a new follow-up feature instead — see Step 1.5, or Step 1.8 (**T2 / T3**
168
+ > post-hoc hotfix) / Step 1.6 (baseline capture), which reach the same
169
+ > follow-up host without the A/B/C prompt.
170
+
171
+ > **Already-merged emergency fix?** If this change was hotfixed to production
172
+ > **before** any Dflow ceremony ran and you are now documenting it after the
173
+ > fact, **the tier Part A decided routes it**:
174
+ > - **T2 / T3 post-hoc** → **Step 1.8** (post-hoc mode) rather than opening a
175
+ > fresh host here — it picks the host linkage and reconciles instead of
176
+ > re-implementing.
177
+ > - **T1 post-hoc** → **not** a minimal-host case. It keeps the normal
178
+ > phase-bearing route (`/dflow:new-phase` or `/dflow:new-feature`, as Part A
179
+ > says), documenting the merged work there. Step 1.8 does not admit it, and
180
+ > a T1 must never be given a zero-phase host.
181
+ >
182
+ > Every pointer to Step 1.8 below carries this same T2 / T3 restriction.
183
+
184
+ **→ Transition (step-internal)**: Step 1 complete. Announce "Step 1 complete (classification {T1/T2/T3 / baseline (tier-exempt)} decided, host feature {SPEC-ID-slug / new / follow-up} identified). Entering Step 1.5 / 1.6 / 1.7 / 1.8 / Step 2 as appropriate." and continue. An observation-only **baseline** capture carries **no tier** — announce it as `baseline (tier-exempt)`, never as T1 / T2 / T3.
185
+
186
+ ## Step 1.5: Completed-Feature Reopen Detection (only if Step 1 found a related completed feature — and this is a normal modification, not a T2 / T3 post-hoc hotfix or a baseline capture)
87
187
 
88
188
  If Step 1 Part B identified a semantically related completed feature, AI
89
189
  must explicitly disambiguate the user's intent **before** writing any
90
- files:
190
+ files. **Skip this step entirely for a T2 / T3 post-hoc hotfix (Step 1.8) or an
191
+ observation-only baseline capture (Part A routes it straight to Step 1.6)** —
192
+ each picks its own host without this prompt (follow-up when a completed
193
+ feature relates, standalone otherwise), and asking it anyway lets Option B
194
+ file a related hotfix or capture as an independent standalone, losing the
195
+ `follow-up-of` lineage and both reverse-link transitions. (A **T1** post-hoc
196
+ is a normal reopen and belongs in this prompt.)
91
197
 
92
198
  ```
93
199
  "I notice this change overlaps with completed feature
@@ -98,10 +204,14 @@ Is this a follow-up to that feature, or an independent new concern?
98
204
 
99
205
  Option A — follow-up of `{SPEC-ID}-{slug}`
100
206
  → Build a new feature with a fresh SPEC-ID and `follow-up-of:
101
- {SPEC-ID}` link back to the original. Inherits BR Snapshot baseline
102
- from the BC's rules.md.
207
+ {SPEC-ID}` link back to the original. A BC-bearing follow-up inherits
208
+ its BR Snapshot baseline from the BC's rules.md; a no-BC follow-up
209
+ inherits nothing (see Step 1.6).
103
210
  Option B — independent new requirement
104
- → Run /dflow:new-feature normally; no link to the completed feature.
211
+ → Route by the tier Part A already decided: T1 → run /dflow:new-feature
212
+ normally; T2 / T3 → this is an independent standalone change, go to
213
+ Step 1.7 (do NOT send a T2/T3 to new-feature — its intake would bounce
214
+ it right back here). No link to the completed feature either way.
105
215
  Option C — actually I think it's just a tiny lightweight tweak, no
106
216
  new feature needed
107
217
  → Refused. Completed features are frozen — even T3 inline rows must
@@ -113,54 +223,241 @@ Option C — actually I think it's just a tiny lightweight tweak, no
113
223
  **Wait for the developer's explicit choice (A / B / C).**
114
224
 
115
225
  If A (follow-up): proceed to **Step 1.6: Create Follow-up Feature**.
116
- If B (independent): tell the developer to `/dflow:new-feature`; this
117
- flow ends.
226
+ If B (independent): route by tier — **T1** → `/dflow:new-feature` (this flow
227
+ ends); **T2 / T3** → Step 1.7 (standalone minimal host).
118
228
  If C: gently re-explain (per decision 17) that completed features
119
229
  cannot accept direct T2 / T3 writes; offer Option A (follow-up with
120
230
  just a T3 inline row) as the lightweight equivalent.
121
231
 
122
- ## Step 1.6: Create Follow-up Feature (only if user picked Option A)
123
-
124
- Build the follow-up feature using the same machinery as
125
- `/dflow:new-feature` (see `new-feature-flow.md` Steps 3.5 and 4), with
126
- these follow-up-specific differences:
127
-
128
- - **New SPEC-ID** (today's date sequence — do NOT reuse the original
129
- SPEC-ID): e.g. original `SPEC-20260201-003-訂單折扣` → follow-up
130
- `SPEC-20260424-002-訂單折扣-匯率擴充` (or any new slug)
131
- - **New slug**: not required to equal the original slug; pick whatever
132
- best describes the follow-up scope
133
- - **`_index.md` Metadata**: `follow-up-of: {原 SPEC-ID}` is REQUIRED
134
- (uncomment the optional line in the template; can be a YAML array if
135
- the follow-up spans multiple originals)
136
- - **`_index.md` Goals & Scope** auto-prepended note:
137
- ```
138
- > 本 feature 為 `{原 SPEC-ID}-{原 slug}` 的 follow-up,原 feature
139
- > 完成於 `{date}`,詳見 `completed/{原 SPEC-ID}-{原 slug}/_index.md`。
140
- ```
141
- - **`_index.md` Current BR Snapshot baseline**: AI reads the BC's
142
- `dflow/specs/domain/{context}/rules.md` and inherits the BRs that are
143
- in-scope for this follow-up. Mark each inherited row with First Seen
144
- = `inherited from rules.md` and Last Updated = (empty until the new
145
- feature's first phase Delta touches it)
146
-
147
- **Reverse-link into the old `_index.md`**: AI also updates
148
- `dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md` —
149
- uncomment the Follow-up Tracking section (if not already present) and
150
- add a row:
151
-
152
- ```
153
- | {新 SPEC-ID} | {新 slug} | {today} | in-progress |
154
- ```
155
-
156
- This update is **part of the same change set** (offer to commit
157
- both at once; commit message should mention "Add follow-up reference to
158
- `{新 SPEC-ID}`"). The reverse link is a derived index — the new
159
- feature's `follow-up-of` field is the authoritative source.
160
-
161
- After the follow-up feature is set up, this flow hands off to the
162
- `/dflow:new-phase` flow (or stays in this flow at Step 2 for the first
163
- phase's content).
232
+ ## Step 1.6: Create Follow-up Feature (Step 1.5 Option A, a completed-only baseline capture, or the follow-up linkage chosen at Step 1.8)
233
+
234
+ **Open `references/modify-existing-follow-up.md` and follow it there.** This
235
+ step's rules live in that file and are not repeated here.
236
+
237
+
238
+ ## Step 1.7: Open a Standalone Minimal Host (no active feature hosts this change, and no completed feature is being taken as its follow-up)
239
+
240
+ A standalone T2 / T3 — one with no active host and no completed feature
241
+ taken as its follow-up — or a **baseline capture** with no related feature
242
+ (brownfield) — has no feature that will host it, yet the host-ledger
243
+ invariants (SPEC-ID, branch, Checkpoint Log, and the `_index.md` as the
244
+ authoritative record) still apply. Open a **minimal host**: a feature
245
+ directory that carries the change's lightweight artifacts — or one baseline
246
+ capture — and **never a phase-spec**. The lifecycle is
247
+ **open → record → close, two commits** (implementation — or baseline capture
248
+ — then closeout).
249
+
250
+ **"Minimal" means zero-phase, not one-artifact.** A compound standalone
251
+ request is split into its atomic changes, each run through the cascade, with
252
+ the **highest tier governing the host** and **each lower-tier part still
253
+ recording its own artifact under that same host** (`AI-AGENT-GUIDE.md`
254
+ § Ceremony Scaling, Unit of classification). So one minimal host may carry a
255
+ T2 lightweight-spec **and** one or more T3 inline rows — that is the correct
256
+ shape, not a reason to open a second standalone host, and never a reason to
257
+ drop the T3 evidence. A **baseline capture** is the exception: it is
258
+ observation-only and carries its own capture alone.
259
+
260
+ **Open — do this here, before writing the change:**
261
+
262
+ 1. **Confirm it is standalone.** The test is a **condition**, not a list of
263
+ routes: *no active feature hosts this change, and no completed feature is
264
+ being taken as its follow-up.* Whatever brought you here — Part B item 3
265
+ (nothing related found), Step 1.5 **Option B** (a related completed feature
266
+ the developer settled as an independent concern), Step 1.8's standalone
267
+ linkage, Part A's observation-only routing for a baseline with no related
268
+ feature, or a route added later — it belongs here exactly when that
269
+ condition holds. If an **active** feature genuinely hosts this change, stop
270
+ and record it there instead — do not open a redundant host. If a
271
+ **completed** feature is the right home, that is a follow-up (Step 1.6),
272
+ not a standalone. Do **not** re-run Step 1.5 to decide: an Option B arrival
273
+ already answered there, and Part A (baseline) / Step 1.8 (post-hoc hotfix)
274
+ each made the choice themselves.
275
+
276
+ **Overlap scan.** For every arrival except a T2 / T3 post-hoc hotfix, an
277
+ overlap the in-flight scan (Part B item 4) surfaced must be settled before
278
+ you create anything. For a **post-hoc hotfix** the condition above holds even when a
279
+ related feature is in flight — the fix is already merged on the mainline, so
280
+ no unmerged feature branch can host it (Step 1.8 says why) — and a surfaced
281
+ overlap is **information, not a blocker**: it tells the developer a merge
282
+ reconciliation is coming (`finish-feature-flow.md` Step 5).
283
+ 2. **Assign the identifiers** per `_conventions.md` § SPEC-ID Format
284
+ (`SPEC-YYYYMMDD-NNN`). For a **functional bug**, also assign its
285
+ **BUG-NUMBER** here (issue-tracker number, else `max+1` over the existing
286
+ `BUG-*` across `dflow/specs/**`, active + completed). Collision-check
287
+ **before creating anything** in step 3: no `active/` or `completed/`
288
+ directory and no local or remote branch already carries this SPEC-ID (or
289
+ BUG-NUMBER) or the branch name you will cut (stale branches are non-blocking
290
+ but are never reused).
291
+
292
+ **What a collision means depends on who owns the number.** A SPEC-ID, and a
293
+ **locally allocated** `max+1` BUG-NUMBER, are this flow's to hand out — a
294
+ collision is an allocation clash and nothing more, so re-assign the day
295
+ counter (or take the next BUG-NUMBER) and re-check. A **tracker-owned**
296
+ BUG-NUMBER is not: the issue tracker owns that identity, and renaming
297
+ tracker issue 42 to `BUG-43` to dodge a collision silently severs the record
298
+ from the issue it is about. **Never renumber a tracker-owned BUG-NUMBER.**
299
+ A collision there is reporting something real — this work is already
300
+ recorded, or a stale branch is still carrying it — and it is settled that
301
+ way with the developer, as duplicate / existing work or branch-history
302
+ cleanup. All identifiers are settled here, before the host exists.
303
+
304
+ For a **post-hoc hotfix** (Step 1.8), also run the branch-base check in
305
+ `references/modify-existing-post-hoc-hotfix.md` item 2 here, before step 3
306
+ creates anything: step 4 cuts from the base branch it settles.
307
+ 3. **Create the minimal `_index.md`** from `templates/_index.md` at
308
+ `dflow/specs/features/active/{SPEC-ID}-{slug}/_index.md`, carrying all
309
+ **seven required sections** that template names — the Metadata front
310
+ matter, Goals & Scope, Phase Specs, Current BR Snapshot, Lightweight
311
+ Changes, Checkpoint Log, Resume Pointer. (`Follow-up Tracking` is the
312
+ template's **optional** eighth section; a standalone host gets one only if
313
+ it later grows follow-ups of its own.) "Minimal" means the sections are
314
+ thin, not missing:
315
+ - Metadata `status: in-progress`; `branch:` = the branch you cut in
316
+ step 4. This field is **authoritative** — the branch gate and any
317
+ lightweight-spec frontmatter read their branch from it.
318
+ - Goals & Scope: one or two sentences. A standalone change need not touch
319
+ a bounded context; if it does not, say so plainly in Goals & Scope
320
+ rather than inventing one. (A baseline capture names the context it
321
+ captures — that is a real BC, not `none`.)
322
+ - Phase Specs: **leave the table empty** — a minimal host has no
323
+ phase-spec.
324
+ - Current BR Snapshot: fill it only if the change carries a BR delta; a
325
+ no-BR / T3 host leaves it empty (finish-feature Step 1 reads an
326
+ intentionally empty snapshot as a no-BR feature, not a validation
327
+ failure).
328
+ - Lightweight Changes, Checkpoint Log, Resume Pointer: start them; the
329
+ record and the two checkpoints land here as you go.
330
+ 4. **Branch gate — by change class.** A **functional bug** cuts
331
+ `bugfix/BUG-{NUMBER}-{slug}`, using the BUG-NUMBER assigned and
332
+ collision-checked in step 2. **Otherwise** — a standalone non-bug **T2 / T3**, or a **baseline
333
+ capture** — cut `feature/{SPEC-ID}-{slug}`. The `_index.md` `branch:` field must equal the
334
+ branch cut here. (See `references/git-integration.md` § Commit Checkpoints,
335
+ Branch Gate & AI Commits.)
336
+
337
+ **Record + commit — rejoin the normal flow.** Follow this flow's tier-aware
338
+ routing (Part A): a **T2** writes its lightweight-spec (classic BR form or
339
+ the matching no-BR family variant — shapes are defined in
340
+ `templates/lightweight-spec.md`) and runs the Step 2–6 record **to the depth
341
+ Part A set** — that range names the route, not an instruction to run every item
342
+ in it. In particular a **no-BC** T2 — one whose host Goals & Scope says it
343
+ touches no bounded context — does not acquire one by walking Step 2: it does no
344
+ Domain-file work there (Step 2 carries the same guard at its own site), so
345
+ closeout's no-BC branch has nothing fictitious to skip past. A **T3** skips
346
+ the Domain / extraction work and records an inline row in `_index.md`
347
+ Lightweight Changes — **one row per atomic T3 change**, so a compound request
348
+ records each of them here (see "minimal means zero-phase, not one-artifact"
349
+ above). A **baseline capture** is observation-only: it records the capture in
350
+ its BC-layer documents and/or `domain/analysis.md` and one `Tier = baseline`
351
+ row in `_index.md`, and its first checkpoint is named `spec-baseline` with
352
+ Result `committed` (never `implementation` — there is no implementation
353
+ work). Otherwise the **implementation commit is checkpoint 1**. Either way,
354
+ checkpoint 1 is offered at the end of Step 6 (§ 6.5), after Step 6 has written
355
+ its record, and recorded in the Checkpoint Log. A baseline capture skips Step 5
356
+ — there is nothing to implement — so once the capture is recorded it goes
357
+ through the Step 5 → Step 6 gate into Step 6, not straight to a commit. (For a
358
+ **post-hoc** host, Step 5 is skipped as well and checkpoint 1 is the
359
+ **documentation** commit instead; see Step 1.8 and Step 5's guard.)
360
+
361
+ **Every artifact gets a Lightweight Changes row, and every row is written
362
+ *before* checkpoint 1.** A **T3**'s row *is* its whole record; a **T2**'s row is
363
+ the outbound link to its lightweight-spec; a **baseline** capture's is its
364
+ `Tier = baseline` row — all three are rows, and closeout requires one per
365
+ artifact. Write them now, carrying the tier, the description and the
366
+ implementation paths (for a baseline, the documents it captured into). The
367
+ **only** part that may appear afterwards is the `Commit` cell, which cannot
368
+ exist until its commit does: closeout's allow-list admits that cell and no other
369
+ change **to the row**, so a row added after checkpoint 1 **blocks**. (The
370
+ allow-list separately admits the Checkpoint Log rows, the Resume Pointer and the
371
+ Current BR Snapshot; the first two are what "Finalize + close" writes after
372
+ checkpoint 1.)
373
+
374
+ **Name the implementation paths in the artifact.** Closeout's evidence checks
375
+ assert that a commit *touches the implementation paths this change describes* —
376
+ which is only mechanical if the artifact actually declares them. So a **T2**'s
377
+ lightweight-spec names the source paths it changes, and a **T3**'s row
378
+ Description names them alongside its one-line description and tag. Paths, not a
379
+ diff — enough to compare a commit against. A **baseline capture** declares the
380
+ documents it wrote instead; that is its counterpart. An artifact that
381
+ declares none leaves that check nothing to compare, and finish-feature treats a
382
+ missing declaration as a **block**, not a pass.
383
+
384
+ **Before checkpoint 1 — Step 6 finalizes the record.** Step 6's completion
385
+ checklist runs before checkpoint 1, so everything it writes rides that commit.
386
+ For **every** T2, 6.3 sets the lightweight-spec `status: completed`. **Only when
387
+ that T2 is BC-bearing**, 6.3 also refreshes the host's Current BR Snapshot — a
388
+ no-BC T2 has no snapshot to refresh. A **T3** or a **baseline capture** has no
389
+ spec file and no snapshot to refresh; Step 6 only re-verifies its row.
390
+
391
+ **Finalize + close — after checkpoint 1.** Before `/dflow:finish-feature`,
392
+ write what cannot exist until checkpoint 1 does, for every tier: each row's
393
+ commit evidence (the two surfaces below) and the Resume Pointer advanced to the
394
+ closeout-ready state.
395
+
396
+ **Commit evidence goes to two surfaces, always — every row, every tier.** They
397
+ answer different questions, so filling one is never filling the other, and
398
+ finish-feature Step 1 reads both:
399
+
400
+ - **Checkpoint Log Result** — what happened at the *lifecycle checkpoint*.
401
+ - **Lightweight Changes row `Commit`** — the commit carrying *that row's own
402
+ artifact*. Every row needs one; a blank cell fails closeout — **and so does a
403
+ placeholder**. `{hash}`, `{pending}`, `(待 commit)`, anything
404
+ `git cat-file -t` cannot resolve to a commit: it counts as **unfilled**, not
405
+ as filled. Leave the cell empty until the hash exists.
406
+
407
+ The **mode** changes only *which hash* each surface carries:
408
+
409
+ - **Normal** (T2 or T3) — Checkpoint Log Result `committed ({hash})` and the
410
+ row's `Commit` cell both name **checkpoint 1**, the single commit that
411
+ carried the artifact, the implementation and Step 6's record together. Two
412
+ cells, one hash; fill both.
413
+ - **Post-hoc hotfix** (Step 1.8; T2 or T3) — the Checkpoint Log Result stays
414
+ `reconciled ({merged-hotfix-hash})`, **never overwrite it** — only closeout
415
+ corrects it, through `references/modify-existing-post-hoc-hotfix.md` item 6 —
416
+ while the row's `Commit` cell carries the **documentation** commit's hash.
417
+ This is the one mode where the two values genuinely differ (Step 1.8 item 4).
418
+ - **Baseline capture** — the `spec-baseline` checkpoint's Result
419
+ `committed ({hash})` and the `Tier = baseline` row's `Commit` cell both name
420
+ that capture commit, the one that carried what it captured. Two cells,
421
+ one hash; fill both.
422
+
423
+ **A declined checkpoint still owes its hash.** If the developer answered **N**
424
+ at the checkpoint-1 offer and made that commit themselves — the change together
425
+ with Step 6's record — the Checkpoint Log row was written `skipped` honestly —
426
+ the AI did not commit — but it is now
427
+ **incomplete, not final**: complete it here to `committed ({hash})` with the
428
+ developer's actual hash. **That completion is for a normal checkpoint 1** (or a
429
+ `spec-baseline` one). On a **post-hoc** host the Result stays
430
+ `reconciled ({merged-hotfix-hash})` — a declined documentation commit is
431
+ completed by filling each Lightweight Changes row's `Commit` cell once the
432
+ developer's commit lands, never by overwriting the reconciliation hash, which
433
+ records a different commit entirely. A row left reading `skipped` blocks closeout, and
434
+ finish-feature cannot tell "declined then committed" from "never committed" on
435
+ your behalf. The **closeout** row is the deliberate exception — it carries no
436
+ hash at all, because no later commit of this host carries it
437
+ (`references/git-integration.md` § Commit checkpoints). Its **Result is still
438
+ read** afterwards — finish-feature's post-commit gate rejects `failed` there. A
439
+ declined closeout stays `skipped` because that value records the declined offer
440
+ honestly, not because the row goes unread.
441
+
442
+ In every case leave the host `status: in-progress` until closeout — do not flip
443
+ the host to `completed` early and do not invent a spec file for a T3. Then
444
+ `/dflow:finish-feature` performs the zero-phase closeout, and its **closeout
445
+ commit is checkpoint 2** — it includes the `git mv` archival. The two
446
+ checkpoints each record their own Checkpoint Log
447
+ row (implementation or baseline capture, then closeout); they are asserted
448
+ separately, never merged into one.
449
+
450
+ ## Step 1.8: Hotfix T2 / T3 Post-Hoc (documenting an already-merged emergency change that Part A classified T2 or T3)
451
+
452
+ **Open `references/modify-existing-post-hoc-hotfix.md` and follow it there.**
453
+ This step's rules live in that file and are not repeated here.
454
+
455
+ ⚠ Do not record a post-hoc hotfix from this heading alone. That file carries the
456
+ host-linkage choice, the `reconciled ({merged-hotfix-hash})` checkpoint Result,
457
+ the identity citation an **uncited** hash blocks closeout for, and the per-tier
458
+ hotfix trace. Reconstructed from this heading, post-hoc mode collapses into
459
+ re-implementing a fix that is already on the mainline — which Step 5's guard
460
+ forbids and closeout inspects that checkpoint's changed paths for.
164
461
 
165
462
  ## Step 2: Document Current Behavior (if no spec exists)
166
463
 
@@ -176,7 +473,17 @@ Create a spec with status `in-progress` that includes:
176
473
  - Current business rules (extracted from delivery/entrypoint code)
177
474
  - The proposed change clearly marked — use the **Delta** format below
178
475
 
179
- If baseline domain docs are missing, create them from templates before filling content:
476
+ > **No-BC guard — never manufacture a bounded context to satisfy this step.**
477
+ > The creations below apply only when the change actually touches one. A
478
+ > **no-BC** change — a standalone appearance sweep, say, whose host Goals &
479
+ > Scope states it touches no bounded context — records **N/A** here and moves
480
+ > on. Inventing a `{context}` it does not have plants fictitious Domain files
481
+ > that finish-feature's no-BC closeout branch **skips past rather than
482
+ > removes**, so they survive into the archive as permanent fiction. Same rule
483
+ > as Step 6.3's tier-conditional note: state the verdict, do not manufacture
484
+ > the artifact an item names.
485
+
486
+ If baseline domain docs are missing **for a change that does touch a bounded context**, create them from templates before filling content:
180
487
  - `dflow/specs/domain/glossary.md` → `templates/glossary.md`
181
488
  - `dflow/specs/domain/{context}/models.md` → `templates/models.md`
182
489
  - `dflow/specs/domain/{context}/rules.md` → `templates/rules.md`
@@ -230,7 +537,8 @@ When the feature being modified has no existing spec, take the opportunity to do
230
537
  2. Extract all business rules found (if/else conditions, calculations, validations)
231
538
  3. Identify domain concepts (potential Entities, Value Objects, Services)
232
539
  4. Check for duplicated logic across pages
233
- 5. Record findings in the appropriate domain docs (`models.md`, `rules.md`) and `tech-debt.md`
540
+ 5. Identify the system-level knowledge no single context document holds — an ordered flow that crosses contexts (always the domain-root copy), the lifecycle a status field moves through, a figure computed rather than stored, a mechanism no single rule explains, which roles reach the function (always the domain-root copy), and any spot in those this system keeps working around pending a domain decision (in the copy that holds the knowledge it is stuck on)
541
+ 6. Record findings in the appropriate domain docs (`models.md`, `rules.md`, and `analysis.md` — the owning context's copy, or `dflow/specs/domain/analysis.md` when no one context owns what you found, created from `templates/analysis.md` the first time there is something to record) and `tech-debt.md`
234
542
 
235
543
  This is an **opportunistic** strategy — "capture while we're already here." Do not force a full codebase scan; scope it to the modified feature and its immediate neighbors. Share what you find:
236
544
 
@@ -240,6 +548,7 @@ the related delivery/entrypoint code. I found:
240
548
  - 3 business rules in {entrypoint file} (documented in rules.md)
241
549
  - Duplicated validation logic shared with {other entrypoint} (recorded in tech-debt.md)
242
550
  - A potential Money value object hiding in the calculation at line {N}
551
+ - The approval status moves through four states, two of them set by the batch job (recorded in analysis.md)
243
552
  This gives us a better baseline before we make our change."
244
553
  ```
245
554
 
@@ -275,6 +584,17 @@ Record each finding in `dflow/specs/migration/tech-debt.md` with:
275
584
  - [ ] {File}:{Line} — {Description} — Severity: {High|Medium|Low}
276
585
  ```
277
586
 
587
+ ### System-Level Knowledge to Record
588
+ Look for what this change depends on and no single context document holds:
589
+ - **Cross-context flows** — ordered steps owned by more than one context (always the domain-root copy)
590
+ - **Lifecycles** — a status field and the transitions it moves through
591
+ - **Read models and derived figures** — a number computed rather than stored
592
+ - **Mechanisms** — behavior no single rule explains
593
+ - **Function / role index** — which roles reach this function, and what data each one sees (always the domain-root copy)
594
+ - **Hotspots** in any of the above — what this change worked around, pending a domain decision (in the copy that holds the knowledge it is stuck on)
595
+
596
+ Record each finding in `dflow/specs/domain/{context}/analysis.md` when one context owns what it describes and in `dflow/specs/domain/analysis.md` when no one context does, creating the file from `templates/analysis.md` the first time there is something to record. That template's sections carry the notation.
597
+
278
598
  **→ Transition (step-internal)**: Step 3 complete. Announce "Step 3 complete (delivery/entrypoint layer analyzed, tech debt recorded). Entering Step 4: Evaluate Extraction Opportunity." and continue.
279
599
 
280
600
  ## Step 4: Evaluate Extraction Opportunity
@@ -358,12 +678,27 @@ If the lightweight checklist looks larger than a short-fix checklist, AI must pa
358
678
  Announce to developer:
359
679
  > "Extraction decision made — {extract now / defer and record}. Ready to start implementation? `/dflow:next` to proceed, or adjust the extraction scope first."
360
680
 
361
- > Branch gate (policy-aware): a feature branch is mandatory for every tier (T1 / T2 / T3) under both Git policies (`_conventions.md` § Git Policy). If you are already on this work's `feature/{SPEC-ID}-{slug}` (or `bugfix/{BUG-ID}-{slug}`) branch — e.g. the change belongs to the active feature you are already in — the gate is satisfied and nothing new is created. Otherwise (on the base branch the project cuts from, or an unrelated branch) the AI offers to create/switch to the correct branch, switch to an existing matching one, or override and record it in the `_index.md` Checkpoint Log. Dflow does not need to know which branch is your base. See `references/git-integration.md` § Commit Checkpoints, Branch Gate & AI Commits.
681
+ > Branch gate (policy-aware): a feature branch is mandatory for every tier (T1 / T2 / T3) under both Git policies (`_conventions.md` § Git Policy). If you are already on this work's `feature/{SPEC-ID}-{slug}` (or `bugfix/{BUG-ID}-{slug}`) branch — e.g. the change belongs to the active feature you are already in — the gate is satisfied and nothing new is created. Otherwise (on the base branch the project cuts from, or an unrelated branch) the AI offers to create/switch to the correct branch, switch to an existing matching one, or override and record it in the `_index.md` Checkpoint Log. Dflow does not need to know which branch is your base. **Minimal-host exception (Step 1.6 follow-up variant / Step 1.7 standalone / Step 1.8 post-hoc): the override is not available.** Those hosts assert branch equality against the `_index.md` `branch:` value they cut by change class, so working them on an unrelated branch would falsify the host's own authoritative field — switch to the host's branch instead. See `references/git-integration.md` § Commit Checkpoints, Branch Gate & AI Commits.
362
682
 
363
683
  Wait for confirmation before entering Step 5.
364
684
 
365
685
  ## Step 5: Implement the Change
366
686
 
687
+ > **Post-hoc hotfix (Step 1.8) — skip this step.** The implementation already
688
+ > landed on the mainline before any ceremony ran; that is the whole premise of
689
+ > post-hoc mode, and Step 1.8 item 2 forbids redoing it. There is nothing to
690
+ > implement here. Go straight to the Step 5 → Step 6 gate and on through Step 6;
691
+ > checkpoint 1 (§ 6.5) then commits **documentation only** — the T2 spec or T3
692
+ > row, this host's `_index.md` and what Step 6 wrote, and no source.
693
+ > Re-implementing the fix on this branch would satisfy the letter
694
+ > of the checkpoint while breaking §8's reconciliation contract, which is why
695
+ > closeout inspects that commit's changed paths.
696
+
697
+ > **Baseline capture (a baseline minimal host, Step 1.7) — skip this step.**
698
+ > There is nothing to implement. Once the capture is recorded, go through the
699
+ > Step 5 → Step 6 gate into Step 6; checkpoint 1 (§ 6.5) is the `spec-baseline`
700
+ > commit of what the capture wrote.
701
+
367
702
  If extracting to Domain layer:
368
703
 
369
704
  ```csharp
@@ -402,24 +737,28 @@ protected void Calculate()
402
737
  Announce to developer:
403
738
  > "Implementation appears complete. Ready to update artifacts (spec, rules.md, models.md, glossary, tech-debt)? `/dflow:next` to proceed."
404
739
 
405
- > Commit checkpoint (per `references/git-integration.md` § Commit Checkpoints, Branch Gate & AI Commits): offer to commit, then record the result in the `_index.md` Checkpoint Log. Tier sets the count — T2 commits the merged spec+implementation here (closeout is the second checkpoint); T3 is a single commit.
740
+ A **baseline capture** implemented nothing, so it announces instead:
741
+ > "Baseline capture recorded. Ready to update artifacts? `/dflow:next` to proceed."
406
742
 
407
- Wait for confirmation before entering Step 6. This step gate is where the completion checklist is triggered — do not skip.
743
+ Wait for confirmation before entering Step 6. This step gate is where the completion checklist is triggered — do not skip. It offers **no** commit: checkpoint 1 is offered at the end of Step 6 (§ 6.5).
408
744
 
409
745
  ## Step 6: Update Artifacts
410
746
 
411
747
  Triggered by the Step 5 → Step 6 Step Gate. AI runs the completion checklist in the order below; do **not** skip a section. `Implementation Tasks` checks apply to both `phase-spec.md` and `lightweight-spec.md` (T3 inline-only has no task section).
412
748
 
749
+ > **Tier-conditional (matches the Part A routing — the checklist must not undo it).** A **T3** produces no spec file and no Domain-document updates: for a T3, 6.1's spec and Domain items and all of 6.3 are **N/A** except the `_index.md` row — which is **already written** (Step 1.7 for a minimal host, at record time otherwise), so this checklist **re-verifies** it and never creates it — record them as N/A, and do not create a spec or a Domain file to make an item pass. A **baseline capture** is tier-exempt and likewise produces **no spec file**: 6.1's spec items and 6.3's spec item are **N/A** — do not create one to make an item pass. Its **Domain documents are not N/A**, but this checklist does not create them either: the capture wrote them before checkpoint 1, so here they are **re-verified**, exactly as a T3's row is. A **no-BR family T2** has a spec but no BR delta: its **BR-derived** items are N/A (6.1 says the same). "No BR delta" is **not** "no Domain delta" — decide each Domain document from the actual change, not from the BR line. A family (b) contract change that touches a documented behavior still updates `behavior.md`; a family (e) defect in an extracted model still updates `models.md` if the shape moved. "Do not skip a section" means work through every section and state each verdict — including N/A — not manufacture the artifact an item names.
750
+
413
751
  ### 6.1 Verification — AI runs independently
414
752
 
415
753
  Items marked *(post-6.3)* are re-verified after the documentation merge in 6.3 lands:
416
754
 
417
755
  - [ ] Every ADDED / MODIFIED / REMOVED / RENAMED entry in the Delta section is covered by implementation or tests
756
+ - [ ] **No-BR family evidence** — when the spec's Behavior Delta is a `BR:` / `BR Delta:` none line instead of delta entries, verify *that family's* evidence is present and substantive: (a) `Output Footprint`; (b) `Contract Delta` + `**Downstream consumers**`; (c) `Operational Rationale` + `**Trace**`; (d) `Performance Delta` + `**SLA / resource context**`; (e) `Governing BR-IDs` + root cause + a regression check; (f) `Change Rationale` with `**Before**` / `**After**` + `**Regression**`. For such a spec the **BR-derived** items in this checklist are **N/A** — say so explicitly rather than passing them on an empty delta set, and never add a BR or a `behavior.md` anchor just to make an item pass. Domain documents are **not** automatically N/A: judge each from the actual change (a family (b) contract change that touches a documented behavior still updates `behavior.md`). When a change matches more than one family (an operational refactor that also shifts SLA), **every** matching family's evidence must be present — one BR line, all matching evidence sections. A spec written in the classic BR-delta form, or a bug spec written with the older single `BR:` line, is accepted as-is
418
757
  - [ ] Domain layer has **no** delivery-framework references (grep `src/Domain/`)
419
758
  - [ ] Extracted logic (if Step 4 decided "extract now") lives under `src/Domain/` as framework-pure code
420
759
  - [ ] `Implementation Tasks` section (`phase-spec.md` or `lightweight-spec.md`): all tasks checked, or unchecked items explicitly labelled as follow-up
421
760
  - [ ] *(post-6.3)* `dflow/specs/domain/{context}/behavior.md` has a section anchor for every `BR-*` in ADDED / MODIFIED entries; REMOVED entries' anchors have been deleted (mechanical input for `/dflow:verify`)
422
- - [ ] *(post-6.3)* every ADDED / MODIFIED / RENAMED BR's `Last updated` in `dflow/specs/domain/{context}/rules.md` is later than this spec's `created` date (mechanical drift guard)
761
+ - [ ] *(post-6.3)* every ADDED / MODIFIED / RENAMED BR's `Last updated` in `dflow/specs/domain/{context}/rules.md` is **not earlier than** this spec's `created` date (mechanical drift guard). ⚠ **Not earlier**, not *later*: `Last updated` is set to **today**, so a spec created and swept on the same day — the modal case for this tier — gives `Last updated == created`. Requiring *later* blocks it with no legitimate escape (post-dating the row fabricates a record). Same operator as `new-feature-flow.md` § 8.1; the two must not diverge.
423
762
 
424
763
  If any item fails, report the gap and pause — don't proceed to 6.2.
425
764
 
@@ -435,10 +774,16 @@ Ask these one-by-one.
435
774
 
436
775
  ### 6.3 Documentation updates
437
776
 
438
- - [ ] Update or create the feature / bug spec; set `status: completed`
777
+ > **Table-cell formatting**: keep table cells concise — separate multiple short items with `<br>` (never chain them into one line with ;/; separators), and move long narrative detail out of the cell into a document section (full convention: the formatting comment at each spec doc's head).
778
+
779
+ - [ ] Update or create the feature / bug spec; set `status: completed` — **T3 and baseline: N/A** (no spec file exists; the `_index.md` inline row — a T3 row, or a `Tier = baseline` row — is the record, and the host's own status is not touched)
780
+ - [ ] **BC-bearing T2, on every host** — refresh the host `_index.md` Current BR Snapshot from this spec's final delta (`templates/_index.md` regenerates it when a T2 lightweight-spec is finalized; on a minimal host this is the refresh Step 1.7 places before checkpoint 1). A spec with no BR delta leaves the Snapshot as it is. N/A for a no-BC T2, a T3 and a baseline capture
781
+ - [ ] The items below are the Domain sweep — **N/A for a T3**. For a **no-BC change** (one whose host Goals & Scope says it touches no bounded context) the **BC-scoped** items are N/A — everything under `dflow/specs/domain/{context}/`: there is no `{context}` to sweep, and inventing one plants the fiction Step 2's no-BC guard refuses. The **global** documents are *not* covered by that: `glossary.md`, `domain/analysis.md` and `migration/tech-debt.md` belong to no bounded context, and a no-BC operational T2 can genuinely rename a term, change which roles reach a function, or discover migration debt — judge those three from the actual change, as always. For a no-BR family T2 only the *BR-derived* items are N/A; run each remaining item where this change actually touches that document
439
782
  - [ ] `dflow/specs/domain/{context}/rules.md` — business rules updated
440
783
  - [ ] `dflow/specs/domain/{context}/models.md` — domain model updated
784
+ - [ ] `dflow/specs/domain/{context}/analysis.md` — lifecycles, derived figures or mechanisms no single rule explains this change found or altered, in the owning context's copy, which may not be this host's; any spot this change worked around pending a domain decision, in those or in a rule or unrecorded knowledge that belongs there; and any open row there this change settled (created from `templates/analysis.md` the first time there is something to record; N/A when there is none)
441
785
  - [ ] `dflow/specs/domain/glossary.md` — new / renamed terms (mirror any RENAMED delta entries here)
786
+ - [ ] `dflow/specs/domain/analysis.md` — ordered cross-context flows, role reach, or anything else no one context owns, that this change found or altered; any spot this change worked around pending a domain decision, in those or in unrecorded knowledge that belongs here; and any open row there this change settled (created from `templates/analysis.md` the first time there is something to record; N/A when there is none)
442
787
  - [ ] `dflow/specs/domain/{context}/behavior.md` — update scenarios to reflect Delta result (merge final state, not Delta markup). Sub-steps:
443
788
  - Promote any Activity 3 (Spec Writing) draft sections (from B3 mid-sync) to formal sections
444
789
  - Update the corresponding `rules.md` anchor's `last-updated` date (B4)
@@ -469,9 +814,15 @@ file move at this point. The whole feature directory moves to
469
814
  If this modification was a **T3 inline-only** change, no spec file
470
815
  exists — archival is just leaving the row in `_index.md` Lightweight Changes.
471
816
 
472
- If the modification was a **standalone follow-up feature** (created
473
- via Step 1.6), the same rule applies: this flow does not archive the
474
- new follow-up directory; that happens at `/dflow:finish-feature` time.
817
+ If the modification opened a **standalone minimal host** (Step 1.7) or a
818
+ **follow-up feature** (created via Step 1.6, including its minimal
819
+ variant), the same rule applies: this flow does not archive the host
820
+ directory — the closeout `git mv` happens at `/dflow:finish-feature` time
821
+ (checkpoint 2 of the two-checkpoint minimal-host lifecycle).
475
822
 
476
823
  Only announce "change complete" after the appropriate archival step
477
824
  above (or the Step 6.3 docs sweep) is done.
825
+
826
+ ### 6.5 Commit checkpoint (checkpoint 1)
827
+
828
+ > Commit checkpoint (per `references/git-integration.md` § Commit Checkpoints, Branch Gate & AI Commits): fold the offer into the "change complete" announcement, then record the result in the `_index.md` Checkpoint Log. This commit is **checkpoint 1**: it carries the change — the spec or row plus the implementation — **and** everything Steps 2–6 wrote. Tier sets the count — T2 commits the merged spec+implementation here (closeout is the second checkpoint); T3 is a single implementation commit. The entries that carry this commit's hash — the Checkpoint Log Result and each Lightweight Changes `Commit` cell naming it — are written after the commit and ride the host's next commit; on a phase-bearing host, `/dflow:finish-feature` Step 4 backfills any `Commit` cell still unfilled at closeout. **Minimal host exception (Step 1.7 standalone *and* the Step 1.6 follow-up variant)**: a minimal host takes no host commit between checkpoint 1 and closeout, so **every row rides checkpoint 1 itself** — a T3 row included, written into `_index.md` *before* this commit, because finish-feature Step 1 reads **checkpoint 1's committed `_index.md`** for it. Only the entries that carry the hash come later: Step 1.7's "Finalize + close" writes them, and they ride the closeout commit. And a minimal host takes a second **closeout** checkpoint too: **every** minimal host records **two** checkpoints (implementation — or `spec-baseline` for a baseline — then closeout), for T3, T2, and baseline alike. **Post-hoc hotfix (Step 1.8) — the same two checkpoints, but the first carries no implementation**: the fix is already on the mainline, so checkpoint 1 is the **documentation** commit (spec / row, `_index.md` and what Step 6 wrote, no source), and its Checkpoint Log Result is `reconciled ({merged-hotfix-hash})` rather than `committed`. "Commits the merged spec+implementation" above describes a normal host and does **not** apply here.