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
@@ -17,7 +17,7 @@ All other step transitions are **step-internal**: announce "Step N complete, ent
17
17
  6) because Clean Architecture's layered structure already separates
18
18
  concerns — there's no delivery/entrypoint extraction step to perform.
19
19
 
20
- **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 3 may default to "no DDD impact, fix in place" unless the bug itself is in Domain logic. T2 still generates a concise `Implementation Tasks` checklist (see Step 3).
20
+ **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 3 may default to "no DDD impact, fix in place" unless the bug itself is in Domain logic; T2 still generates a concise `Implementation Tasks` checklist (see Step 3). 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.
21
21
 
22
22
  ## Step 1: Assess the Change — Ceremony Tier + Feature Linkage + Layer
23
23
 
@@ -29,40 +29,103 @@ through `/dflow:bug-fix`.
29
29
 
30
30
  This step has three parallel concerns:
31
31
 
32
- **Part A — Determine the Ceremony Tier (T1 / T2 / T3)**
33
-
34
- Dflow runs three ceremony tiers (full table in AI-AGENT-GUIDE.md § Ceremony Scaling).
35
- For a modification, AI judges which tier fits before deciding what to
36
- produce:
37
-
38
- | Tier | When to choose | Production |
39
- |---|---|---|
40
- | **T1 Heavy** | Architectural change / new BR / new Aggregate or VO / new Domain Event / 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 |
41
- | **T2 Light** | Bug fix / UI input validation tweak / flow branch change — **has BR Delta** but no Aggregate / data-structure overhaul | Independent `lightweight-{date}-{slug}.md` placed in feature directory + outbound-link row in `_index.md` Lightweight Changes |
42
- | **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) |
43
-
44
- If any T3 criterion fails → drop to T2. If Domain / BR / data structure
45
- is touched → escalate to T1.
46
-
47
- **Below T3** (pure typo, formatting commit) → tell the developer Dflow
48
- doesn't track this and they can `git commit` directly.
32
+ **Part A — Determine the Ceremony Tier (T1 / T2 / T3 / below workflow)**
33
+
34
+ The tier has **one source**: `AI-AGENT-GUIDE.md` § Ceremony Scaling — the
35
+ ordered cascade, steps 0–4, where **the first step that matches wins**. **Open
36
+ that section and classify from it before going further.** Do not classify from
37
+ memory, from this flow's step headings, or from a summary: the cases that
38
+ actually decide a tier — new work versus a modification, what stays below
39
+ workflow, how far a T3 may reach, inbound contracts, compound requests — are
40
+ settled there, and a second copy of those criteria here would be a second answer
41
+ to the same question.
42
+
43
+ Two of the cascade's outcomes leave this flow entirely: genuinely new work
44
+ (`/dflow:new-feature`) and a change Dflow does not track. Take those two exits as
45
+ the guide states them rather than continuing through the steps below.
46
+
47
+ **Tier-aware routing (don't run heavier ceremony than the tier needs):**
48
+
49
+ - **T3** → still do Part B (host) and Part C (layer), then **skip the Domain /
50
+ DDD-impact work**: go to the branch gate, implement, and record the inline
51
+ `_index.md` row. Do **not** create or update any spec file, do **not** run the
52
+ Step 2 baseline Domain-file check, and do **not** run the Step 2 → Step 3
53
+ DDD-impact gate.
54
+ - **T2** → a lightweight-spec at the depth the change needs; run the Domain /
55
+ layer steps only where the change actually touches them.
56
+ - **Observation-only (tier-exempt, cascade step 0)** → recording existing
57
+ behaviour or a decision **without changing output** carries no tier. Capture
58
+ it in the relevant Domain document (`models.md` / `rules.md` /
59
+ `behavior.md` / `events.md` / `analysis.md` — greenfield carries `events.md`
60
+ as a first-class Domain document, so an observation about an existing Domain
61
+ Event lands there; an observation no single context document holds goes to
62
+ `analysis.md`, in `domain/analysis.md` for a cross-context flow, for role reach
63
+ and for whatever else no one context owns, a hotspot in the copy that holds
64
+ the knowledge it is stuck on, and in the owning context's copy otherwise,
65
+ created from `templates/analysis.md` the first time there is
66
+ something to record) and stop — do not read the cascade's "below
67
+ workflow" as permission to skip the record. Greenfield has no
68
+ baseline-capture host of its own (that hosted baseline flow is a Brownfield
69
+ concern); a greenfield observation lands in the Domain docs the project keeps,
70
+ creating one only where the list above says to.
71
+ - **T1** → escalate to `/dflow:new-phase` (extending an active feature) or
72
+ `/dflow:new-feature` (a truly new concern); full ceremony via that flow.
49
73
 
50
74
  **Part B — Locate the Feature this Change Belongs To**
51
75
 
52
- Walk through these in order:
76
+ Walk through these in order to **classify** the change. Do **not** jump to
77
+ Step 1.5 / 1.7 mid-list: the in-flight overlap scan (item 4) and the hotfix
78
+ check below both run first, and the actual routing to Step 1.5 / 1.7 / 1.8 /
79
+ Step 2 happens at this step's closing transition.
53
80
 
54
81
  1. **Active features**: scan `dflow/specs/features/active/*/_index.md`. Does
55
82
  the change belong inside an existing active feature directory? If
56
83
  yes, use that as the host (T1 → `/dflow:new-phase`; T2 → place
57
84
  lightweight-spec inside; T3 → inline row in that `_index.md`).
85
+ **Exception — a minimal (zero-phase) host that has already taken its
86
+ implementation checkpoint is not an eligible host.** A minimal host is fixed
87
+ at two commits and **every** Lightweight Changes row must belong to the first
88
+ one (Step 1.7), so once that checkpoint has landed it can accept nothing
89
+ further, however well it fits. It does **not** become this change's host, and
90
+ for the rest of this walk it does not count as one — keep scanning, and let
91
+ the routing at this step's closing transition proceed as if it were not
92
+ there. (Item 4 still surfaces it as an overlap; that is information for the
93
+ developer, not a host.) **Before** that checkpoint lands the host is still
94
+ open, and a compound request legitimately records more than one **T2 / T3**
95
+ artifact under it ("minimal means zero-phase, not one-artifact", Step 1.7) —
96
+ but **never a phase**: a minimal host is *defined* by carrying no
97
+ `phase-spec-*`, so it is not an eligible host for a **T1** at any point,
98
+ before or after that checkpoint. Keep scanning, exactly as above.
99
+ **Exception — an already-merged T2 / T3 emergency fix** (the callout
100
+ below): it is already on the mainline, so an in-flight host cannot hold
101
+ it. It takes **Step 1.8** and gets a host of its own there, however well
102
+ a related active feature seems to fit — Step 1.8 says why. A **T1**
103
+ post-hoc is unaffected and uses this route normally.
58
104
  2. **Completed features**: scan `dflow/specs/features/completed/*/_index.md`
59
105
  Goals & Scope sections. If the change description is semantically
60
- related to a completed feature, this becomes the **completed feature
61
- reopen** scenario — go to Step 1.5 below.
62
- 3. **Standalone**: if no related feature exists (active or completed),
63
- this is a new concern. For T1, use `/dflow:new-feature`. For T2 / T3
64
- on a standalone bug, see Step 1.5 — `/dflow:bug-fix` will create a
65
- minimal feature directory to host the lightweight-spec.
106
+ related to a completed feature, this is the **completed-feature-reopen**
107
+ case (Step 1.5, routed to at the closing transition) — **unless** this is a
108
+ **T2 / T3** already-merged emergency fix you are documenting after the fact.
109
+ That one never reaches the Step 1.5 A/B/C prompt: it takes **Step 1.8** (the
110
+ callout below), which picks its own host — follow-up or standalone — itself.
111
+ This scan still runs for it: Step 1.8 needs to know whether a related
112
+ completed feature exists. (A **T1** post-hoc is not a Step 1.8 case at all
113
+ and does reach Step 1.5 normally.)
114
+ 3. **Standalone**: if no related feature exists (active or completed) that can
115
+ host this change — a host item 1 ruled **ineligible** does not count as one —
116
+ this is a new concern. For T1, use `/dflow:new-feature`. A standalone
117
+ T2 / T3 needs a **minimal host feature directory** to hold the change —
118
+ its open → record → close lifecycle is the **standalone** case (Step 1.7,
119
+ routed to at the closing transition). Do not improvise a host and do not
120
+ leave an empty one behind. (If a related active feature genuinely fits
121
+ after all, use it as the host instead.)
122
+ **Exception — an already-merged T2 / T3 emergency fix** (the callout
123
+ below): finding nothing related does **not** make it an ordinary standalone.
124
+ It still routes through **Step 1.8**, which picks standalone itself and
125
+ supplies what this item cannot — the `reconciled (...)` checkpoint, the
126
+ per-tier hotfix trace, and reconcile-instead-of-re-implement. Coming to
127
+ Step 1.7 straight from here drops all of that. A **T1** post-hoc is
128
+ unaffected and uses this route normally.
66
129
  4. **In-flight overlap scan (cross-branch)**: this branch's `active/` is not
67
130
  everything in flight. Run the in-flight scan (classification and dedup
68
131
  rules in `AI-AGENT-GUIDE.md` § Status / Control Commands) — `git fetch`
@@ -73,11 +136,35 @@ Walk through these in order:
73
136
  awaiting integration, or unknown — or an unfinished feature — semantically
74
137
  overlaps this change, surface it and wait for the developer to decide
75
138
  before creating anything new (stale branches are non-blocking).
139
+ **Exception — an already-merged T2 / T3 emergency fix** (the callout
140
+ below): run the scan, but a surfaced overlap is **information, not a
141
+ blocker**. The fix is already on the mainline, so no unmerged feature branch
142
+ can host it (Step 1.8 says why) — there is no routing choice left to wait
143
+ for. Report the overlap as notice that a merge reconciliation is coming
144
+ (`finish-feature-flow.md` Step 5), then let Step 1.8 proceed: do not offer
145
+ the in-flight feature as a host and do not hold host creation on it.
146
+ Step 1.7's overlap scan states the same rule at the point of use. A **T1**
147
+ post-hoc is unaffected and waits normally.
76
148
 
77
149
  > **Why scan completed too?** Completed features are frozen history
78
150
  > and **cannot accept** any T2 / T3 directly
79
151
  > (would break the "completed = frozen" semantic). Reopen routes through
80
- > a new follow-up feature instead — see Step 1.5.
152
+ > a new follow-up feature instead — see Step 1.5, or Step 1.8 when the
153
+ > reopen is a **T2 / T3** post-hoc hotfix (it reaches the same follow-up host
154
+ > without the A/B/C prompt).
155
+
156
+ > **Already-merged emergency fix?** If this change was hotfixed to production
157
+ > **before** any Dflow ceremony ran and you are now documenting it after the
158
+ > fact, **the tier Part A decided routes it**:
159
+ > - **T2 / T3 post-hoc** → **Step 1.8** (post-hoc mode) rather than opening a
160
+ > fresh host here — it picks the host linkage and reconciles instead of
161
+ > re-implementing.
162
+ > - **T1 post-hoc** → **not** a minimal-host case. It keeps the normal
163
+ > phase-bearing route (`/dflow:new-phase` or `/dflow:new-feature`, as Part A
164
+ > says), documenting the merged work there. Step 1.8 does not admit it, and
165
+ > a T1 must never be given a zero-phase host.
166
+ >
167
+ > Every pointer to Step 1.8 below carries this same T2 / T3 restriction.
81
168
 
82
169
  **Part C — Identify the Affected Layer (Clean Architecture)**
83
170
 
@@ -85,15 +172,19 @@ This still matters for picking the right fix location:
85
172
  - Domain invariant broken → Domain fix
86
173
  - Application orchestration issue → Application fix
87
174
  - Infrastructure bug (DB, external service) → Infrastructure fix
88
- - API contract change → Presentation fix (becomes T1 if behaviour changes)
175
+ - API contract change → Presentation fix (the tier comes from the cascade's contract axis, not from "behaviour changed" — classify in the guide, as Part A says)
89
176
 
90
- **→ Transition (step-internal)**: Step 1 complete. Announce "Step 1 complete (tier {T1/T2/T3} decided, host feature {SPEC-ID-slug / new / follow-up} identified, layer {Domain/Application/Infrastructure/Presentation}). Entering Step 1.5 / Step 2 as appropriate." and continue.
177
+ **→ Transition (step-internal)**: Step 1 complete. Announce "Step 1 complete (tier {T1/T2/T3} decided, host feature {SPEC-ID-slug / new / follow-up} identified, layer {Domain/Application/Infrastructure/Presentation}). Entering Step 1.5 / 1.7 / 1.8 / Step 2 as appropriate." and continue.
91
178
 
92
- ## Step 1.5: Completed-Feature Reopen Detection (only if Step 1 found a related completed feature)
179
+ ## 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)
93
180
 
94
181
  If Step 1 Part B identified a semantically related completed feature, AI
95
182
  must explicitly disambiguate the user's intent **before** writing any
96
- files:
183
+ files. **Skip this step entirely for a T2 / T3 post-hoc hotfix** — Step 1.8
184
+ picks its own host (follow-up or standalone) without this prompt, and asking it
185
+ anyway lets Option B file a related hotfix as an independent standalone, losing
186
+ the `follow-up-of` lineage and both reverse-link transitions. (A **T1**
187
+ post-hoc is a normal reopen and belongs in this prompt.)
97
188
 
98
189
  ```
99
190
  "I notice this change overlaps with completed feature
@@ -104,10 +195,14 @@ Is this a follow-up to that feature, or an independent new concern?
104
195
 
105
196
  Option A — follow-up of `{SPEC-ID}-{slug}`
106
197
  → Build a new feature with a fresh SPEC-ID and `follow-up-of:
107
- {SPEC-ID}` link back to the original. Inherits BR Snapshot baseline
108
- from the BC's rules.md.
198
+ {SPEC-ID}` link back to the original. A BC-bearing follow-up inherits
199
+ its BR Snapshot baseline from the BC's rules.md; a no-BC follow-up
200
+ inherits nothing (see Step 1.6).
109
201
  Option B — independent new requirement
110
- → Run /dflow:new-feature normally; no link to the completed feature.
202
+ → Route by the tier Part A already decided: T1 → run /dflow:new-feature
203
+ normally; T2 / T3 → this is an independent standalone change, go to
204
+ Step 1.7 (do NOT send a T2/T3 to new-feature — its intake would bounce
205
+ it right back here). No link to the completed feature either way.
111
206
  Option C — actually I think it's just a tiny lightweight tweak, no
112
207
  new feature needed
113
208
  → Refused. Completed features are frozen — even T3 inline rows must
@@ -119,54 +214,223 @@ Option C — actually I think it's just a tiny lightweight tweak, no
119
214
  **Wait for the developer's explicit choice (A / B / C).**
120
215
 
121
216
  If A (follow-up): proceed to **Step 1.6: Create Follow-up Feature**.
122
- If B (independent): tell the developer to `/dflow:new-feature`; this
123
- flow ends.
217
+ If B (independent): route by tier — **T1** → `/dflow:new-feature` (this flow
218
+ ends); **T2 / T3** → Step 1.7 (standalone minimal host).
124
219
  If C: gently re-explain (per decision 17) that completed features
125
220
  cannot accept direct T2 / T3 writes; offer Option A (follow-up with
126
221
  just a T3 inline row) as the lightweight equivalent.
127
222
 
128
- ## Step 1.6: Create Follow-up Feature (only if user picked Option A)
129
-
130
- Build the follow-up feature using the same machinery as
131
- `/dflow:new-feature` (see `new-feature-flow.md` Steps 3.5 and 4), with
132
- these follow-up-specific differences:
133
-
134
- - **New SPEC-ID** (today's date sequence — do NOT reuse the original
135
- SPEC-ID): e.g. original `SPEC-20260201-003-訂單折扣` → follow-up
136
- `SPEC-20260424-002-訂單折扣-匯率擴充` (or any new slug)
137
- - **New slug**: not required to equal the original slug; pick whatever
138
- best describes the follow-up scope
139
- - **`_index.md` Metadata**: `follow-up-of: {原 SPEC-ID}` is REQUIRED
140
- (uncomment the optional line in the template; can be a YAML array if
141
- the follow-up spans multiple originals)
142
- - **`_index.md` Goals & Scope** auto-prepended note:
143
- ```
144
- > 本 feature 為 `{原 SPEC-ID}-{原 slug}` 的 follow-up,原 feature
145
- > 完成於 `{date}`,詳見 `completed/{原 SPEC-ID}-{原 slug}/_index.md`。
146
- ```
147
- - **`_index.md` Current BR Snapshot baseline**: AI reads the BC's
148
- `dflow/specs/domain/{context}/rules.md` and inherits the BRs that are
149
- in-scope for this follow-up. Mark each inherited row with First Seen
150
- = `inherited from rules.md` and Last Updated = (empty until the new
151
- feature's first phase Delta touches it)
152
-
153
- **Reverse-link into the old `_index.md`**: AI also updates
154
- `dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md` —
155
- uncomment the Follow-up Tracking section (if not already present) and
156
- add a row:
157
-
158
- ```
159
- | {新 SPEC-ID} | {新 slug} | {today} | in-progress |
160
- ```
161
-
162
- This update is **part of the same change set** (offer to commit
163
- both at once; commit message should mention "Add follow-up reference to
164
- `{新 SPEC-ID}`"). The reverse link is a derived index — the new
165
- feature's `follow-up-of` field is the authoritative source.
166
-
167
- After the follow-up feature is set up, this flow hands off to the
168
- `/dflow:new-phase` flow (or stays in this flow at Step 2 for the first
169
- phase's content).
223
+ ## Step 1.6: Create Follow-up Feature (Step 1.5 Option A, or the follow-up linkage chosen at Step 1.8)
224
+
225
+ **Open `references/modify-existing-follow-up.md` and follow it there.** This
226
+ step's rules live in that file and are not repeated here.
227
+
228
+
229
+ ## 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)
230
+
231
+ A standalone T2 / T3 — one with no active host and no completed feature
232
+ taken as its follow-up — has no feature that will host it, yet the
233
+ host-ledger invariants — SPEC-ID, branch, Checkpoint Log, and the
234
+ `_index.md` as the authoritative record — still apply. Open a **minimal
235
+ host**: a feature directory that carries the change's lightweight
236
+ artifacts and **never a phase-spec**. The lifecycle is
237
+ **open → record → close, two commits** (implementation, then closeout).
238
+
239
+ **"Minimal" means zero-phase, not one-artifact.** A compound standalone
240
+ request is split into its atomic changes, each run through the cascade, with
241
+ the **highest tier governing the host** and **each lower-tier part still
242
+ recording its own artifact under that same host** (`AI-AGENT-GUIDE.md`
243
+ § Ceremony Scaling, Unit of classification). So one minimal host may carry a
244
+ T2 lightweight-spec **and** one or more T3 inline rows — that is the correct
245
+ shape, not a reason to open a second standalone host, and never a reason to
246
+ drop the T3 evidence.
247
+
248
+ **Open — do this here, before writing the change:**
249
+
250
+ 1. **Confirm it is standalone.** The test is a **condition**, not a list of
251
+ routes: *no active feature hosts this change, and no completed feature is
252
+ being taken as its follow-up.* Whatever brought you here — Part B item 3
253
+ (nothing related found), Step 1.5 **Option B** (a related completed feature
254
+ the developer settled as an independent concern), Step 1.8's standalone
255
+ linkage, or a route added later — it belongs here exactly when that
256
+ condition holds. If an **active** feature genuinely hosts this change, stop
257
+ and record it there instead — do not open a redundant host. If a
258
+ **completed** feature is the right home, that is a follow-up (Step 1.6),
259
+ not a standalone. Do **not** re-run Step 1.5 to decide: an Option B arrival
260
+ already answered there, and Step 1.8 made its choice itself.
261
+
262
+ **Overlap scan.** For every arrival except a T2 / T3 post-hoc hotfix, an
263
+ overlap the in-flight scan (Part B item 4) surfaced must be settled before
264
+ you create anything. For a **post-hoc hotfix** the condition above holds even when a
265
+ related feature is in flight — the fix is already merged on the mainline, so
266
+ no unmerged feature branch can host it (Step 1.8 says why) — and a surfaced
267
+ overlap is **information, not a blocker**: it tells the developer a merge
268
+ reconciliation is coming (`finish-feature-flow.md` Step 5).
269
+ 2. **Assign the identifiers** per `_conventions.md` § SPEC-ID Format
270
+ (`SPEC-YYYYMMDD-NNN`). For a **functional bug**, also assign its
271
+ **BUG-NUMBER** here (issue-tracker number, else `max+1` over the existing
272
+ `BUG-*` across `dflow/specs/**`, active + completed). Collision-check
273
+ **before creating anything** in step 3: no `active/` or `completed/`
274
+ directory and no local or remote branch already carries this SPEC-ID (or
275
+ BUG-NUMBER) or the branch name you will cut (stale branches are non-blocking
276
+ but are never reused).
277
+
278
+ **What a collision means depends on who owns the number.** A SPEC-ID, and a
279
+ **locally allocated** `max+1` BUG-NUMBER, are this flow's to hand out — a
280
+ collision is an allocation clash and nothing more, so re-assign the day
281
+ counter (or take the next BUG-NUMBER) and re-check. A **tracker-owned**
282
+ BUG-NUMBER is not: the issue tracker owns that identity, and renaming
283
+ tracker issue 42 to `BUG-43` to dodge a collision silently severs the record
284
+ from the issue it is about. **Never renumber a tracker-owned BUG-NUMBER.**
285
+ A collision there is reporting something real — this work is already
286
+ recorded, or a stale branch is still carrying it — and it is settled that
287
+ way with the developer, as duplicate / existing work or branch-history
288
+ cleanup. All identifiers are settled here, before the host exists.
289
+
290
+ For a **post-hoc hotfix** (Step 1.8), also run the branch-base check in
291
+ `references/modify-existing-post-hoc-hotfix.md` item 2 here, before step 3
292
+ creates anything: step 4 cuts from the base branch it settles.
293
+ 3. **Create the minimal `_index.md`** from `templates/_index.md` at
294
+ `dflow/specs/features/active/{SPEC-ID}-{slug}/_index.md`, carrying all
295
+ **seven required sections** that template names — the Metadata front
296
+ matter, Goals & Scope, Phase Specs, Current BR Snapshot, Lightweight
297
+ Changes, Checkpoint Log, Resume Pointer. (`Follow-up Tracking` is the
298
+ template's **optional** eighth section; a standalone host gets one only if
299
+ it later grows follow-ups of its own.) "Minimal" means the sections are
300
+ thin, not missing:
301
+ - Metadata `status: in-progress`; `branch:` = the branch you cut in
302
+ step 4. This field is **authoritative** — the branch gate and any
303
+ lightweight-spec frontmatter read their branch from it.
304
+ - Goals & Scope: one or two sentences. A standalone change need not
305
+ touch a bounded context; if it does not, say so plainly in Goals &
306
+ Scope rather than inventing one.
307
+ - Phase Specs: **leave the table empty** — a minimal host has no
308
+ phase-spec.
309
+ - Current BR Snapshot: fill it only if the change carries a BR delta; a
310
+ no-BR / T3 host leaves it empty (finish-feature Step 1 reads an
311
+ intentionally empty snapshot as a no-BR feature, not a validation
312
+ failure).
313
+ - Lightweight Changes, Checkpoint Log, Resume Pointer: start them; the
314
+ record and the two checkpoints land here as you go.
315
+ 4. **Branch gate — by change class.** A **functional bug** cuts
316
+ `bugfix/BUG-{NUMBER}-{slug}`, using the BUG-NUMBER assigned and
317
+ collision-checked in step 2. **Otherwise** — a standalone non-bug **T2 / T3** — cut
318
+ `feature/{SPEC-ID}-{slug}`. The
319
+ `_index.md` `branch:` field must equal the branch cut here. (See
320
+ `references/git-integration.md` § Commit Checkpoints, Branch Gate & AI
321
+ Commits.)
322
+
323
+ **Record + commit — rejoin the normal flow.** Follow this flow's
324
+ tier-aware routing (Part A): a **T2** writes its lightweight-spec (classic
325
+ BR form or the matching no-BR family variant — shapes are defined in
326
+ `templates/lightweight-spec.md`) and runs the Step 2–5 record **to the depth
327
+ Part A set** — that range names the route, not an instruction to run every item
328
+ in it. In particular a **no-BC** T2 — one whose host Goals & Scope says it
329
+ touches no bounded context — does not acquire one by walking Step 2: it does no
330
+ Domain-file work there (Step 2 carries the same guard at its own site), so
331
+ closeout's no-BC branch has nothing fictitious to skip past. A **T3**
332
+ skips the Domain / DDD-impact work and records an inline row in
333
+ `_index.md` Lightweight Changes — **one row per atomic T3 change**, so a
334
+ compound request records each of them here (see "minimal means zero-phase,
335
+ not one-artifact" above). The **implementation commit is checkpoint
336
+ 1** — offered at the end of Step 5 (§ 5.5), after Step 5 has written its
337
+ record, and recorded in the Checkpoint Log. (For a **post-hoc** host, Step 4 is
338
+ skipped and checkpoint 1 is the **documentation** commit instead; see Step 1.8
339
+ and Step 4's guard.)
340
+
341
+ **Every artifact gets a Lightweight Changes row, and every row is written
342
+ *before* checkpoint 1.** A **T3**'s row *is* its whole record; a **T2**'s row is
343
+ the outbound link to its lightweight-spec — both are rows, and closeout requires
344
+ one per artifact. Write them now, carrying the tier, the description and the
345
+ implementation paths. The **only** part that may appear afterwards is the
346
+ `Commit` cell, which cannot exist until its commit does: closeout's allow-list
347
+ admits that cell and no other change **to the row**, so a row added after
348
+ checkpoint 1 **blocks**. (The allow-list separately admits the Checkpoint Log
349
+ rows, the Resume Pointer and the Current BR Snapshot; the first two are what
350
+ "Finalize + close" writes after checkpoint 1.)
351
+
352
+ **Name the implementation paths in the artifact.** Closeout's evidence checks
353
+ assert that a commit *touches the implementation paths this change describes* —
354
+ which is only mechanical if the artifact actually declares them. So a **T2**'s
355
+ lightweight-spec names the source paths it changes, and a **T3**'s row
356
+ Description names them alongside its one-line description and tag. Paths, not a
357
+ diff — enough to compare a commit against. An artifact that declares none
358
+ leaves that check nothing to compare, and finish-feature treats a missing
359
+ declaration as a **block**, not a pass.
360
+
361
+ **Before checkpoint 1 — Step 5 finalizes the record.** Step 5's completion
362
+ checklist runs before checkpoint 1, so everything it writes rides that commit.
363
+ For **every** T2, 5.3 sets the lightweight-spec `status: completed`. **Only when
364
+ that T2 is BC-bearing**, 5.3 also refreshes the host's Current BR Snapshot — a
365
+ no-BC T2 has no snapshot to refresh. A **T3** has no spec file and no snapshot
366
+ to refresh; Step 5 only re-verifies its row.
367
+
368
+ **Finalize + close — after checkpoint 1.** Before `/dflow:finish-feature`,
369
+ write what cannot exist until checkpoint 1 does, for every tier: each row's
370
+ commit evidence (the two surfaces below) and the Resume Pointer advanced to the
371
+ closeout-ready state.
372
+
373
+ **Commit evidence goes to two surfaces, always — every row, every tier.** They
374
+ answer different questions, so filling one is never filling the other, and
375
+ finish-feature Step 1 reads both:
376
+
377
+ - **Checkpoint Log Result** — what happened at the *lifecycle checkpoint*.
378
+ - **Lightweight Changes row `Commit`** — the commit carrying *that row's own
379
+ artifact*. Every row needs one; a blank cell fails closeout — **and so does a
380
+ placeholder**. `{hash}`, `{pending}`, `(待 commit)`, anything
381
+ `git cat-file -t` cannot resolve to a commit: it counts as **unfilled**, not
382
+ as filled. Leave the cell empty until the hash exists.
383
+
384
+ The **mode** changes only *which hash* each surface carries:
385
+
386
+ - **Normal** (T2 or T3) — Checkpoint Log Result `committed ({hash})` and the
387
+ row's `Commit` cell both name **checkpoint 1**, the single commit that
388
+ carried the artifact, the implementation and Step 5's record together. Two
389
+ cells, one hash; fill both.
390
+ - **Post-hoc hotfix** (Step 1.8; T2 or T3) — the Checkpoint Log Result stays
391
+ `reconciled ({merged-hotfix-hash})`, **never overwrite it** — only closeout
392
+ corrects it, through `references/modify-existing-post-hoc-hotfix.md` item 6 —
393
+ while the row's `Commit` cell carries the **documentation** commit's hash.
394
+ This is the one mode where the two values genuinely differ (Step 1.8 item 4).
395
+
396
+ **A declined checkpoint still owes its hash.** If the developer answered **N**
397
+ at the checkpoint-1 offer and made that commit themselves — the change together
398
+ with Step 5's record — the Checkpoint Log row was written `skipped` honestly —
399
+ the AI did not commit — but it is now
400
+ **incomplete, not final**: complete it here to `committed ({hash})` with the
401
+ developer's actual hash. **That completion is for a normal checkpoint 1.** On a
402
+ **post-hoc** host the Result stays
403
+ `reconciled ({merged-hotfix-hash})` — a declined documentation commit is
404
+ completed by filling each Lightweight Changes row's `Commit` cell once the
405
+ developer's commit lands, never by overwriting the reconciliation hash, which
406
+ records a different commit entirely. A row left reading `skipped` blocks closeout, and
407
+ finish-feature cannot tell "declined then committed" from "never committed" on
408
+ your behalf. The **closeout** row is the deliberate exception — it carries no
409
+ hash at all, because no later commit of this host carries it
410
+ (`references/git-integration.md` § Commit checkpoints). Its **Result is still
411
+ read** afterwards — finish-feature's post-commit gate rejects `failed` there. A
412
+ declined closeout stays `skipped` because that value records the declined offer
413
+ honestly, not because the row goes unread.
414
+
415
+ In every case leave the host `status: in-progress` until
416
+ closeout — do not flip the host to `completed` early and do not invent a spec
417
+ file for a T3. Then `/dflow:finish-feature` performs the zero-phase closeout,
418
+ and its **closeout commit is checkpoint 2** — it includes the `git mv`
419
+ archival. The two checkpoints each record their own Checkpoint Log row
420
+ (implementation, then closeout); they are asserted separately, never merged
421
+ into one.
422
+
423
+ ## Step 1.8: Hotfix T2 / T3 Post-Hoc (documenting an already-merged emergency change that Part A classified T2 or T3)
424
+
425
+ **Open `references/modify-existing-post-hoc-hotfix.md` and follow it there.**
426
+ This step's rules live in that file and are not repeated here.
427
+
428
+ ⚠ Do not record a post-hoc hotfix from this heading alone. That file carries the
429
+ host-linkage choice, the `reconciled ({merged-hotfix-hash})` checkpoint Result,
430
+ the identity citation an **uncited** hash blocks closeout for, and the per-tier
431
+ hotfix trace. Reconstructed from this heading, post-hoc mode collapses into
432
+ re-implementing a fix that is already on the mainline — which Step 4's guard
433
+ forbids and closeout inspects that checkpoint's changed paths for.
170
434
 
171
435
  ## Step 2: Check Documentation
172
436
 
@@ -177,7 +441,17 @@ phase's content).
177
441
 
178
442
  If no documentation exists, capture current behavior BEFORE changing — use the **Delta** format below.
179
443
 
180
- If baseline domain docs are missing, create them from templates before filling content:
444
+ > **No-BC guard — never manufacture a bounded context to satisfy this step.**
445
+ > The creations below apply only when the change actually touches one. A
446
+ > **no-BC** change — a standalone appearance sweep, say, whose host Goals &
447
+ > Scope states it touches no bounded context — records **N/A** here and moves
448
+ > on. Inventing a `{context}` it does not have plants fictitious Domain files
449
+ > that finish-feature's no-BC closeout branch **skips past rather than
450
+ > removes**, so they survive into the archive as permanent fiction. Same rule
451
+ > as Step 5.3's tier-conditional note: state the verdict, do not manufacture
452
+ > the artifact an item names.
453
+
454
+ If baseline domain docs are missing **for a change that does touch a bounded context**, create them from templates before filling content:
181
455
  - `dflow/specs/domain/glossary.md` → `templates/glossary.md`
182
456
  - `dflow/specs/domain/{context}/models.md` → `templates/models.md`
183
457
  - `dflow/specs/domain/{context}/rules.md` → `templates/rules.md`
@@ -273,6 +547,17 @@ If constraints change:
273
547
  - Update Value Object validation
274
548
  - Check all usages of the Value Object
275
549
 
550
+ ### What system-level knowledge did this change depend on?
551
+ Look for what this change depends on and no single context document holds:
552
+ - **Cross-context flows** — ordered steps owned by more than one context (always the domain-root copy)
553
+ - **Lifecycles** — a status field and the transitions it moves through
554
+ - **Read models and derived figures** — a number computed rather than stored
555
+ - **Mechanisms** — behavior no single rule explains
556
+ - **Function / role index** — which roles reach this function, and what data each one sees (always the domain-root copy)
557
+ - **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)
558
+
559
+ 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.
560
+
276
561
  ### Generate Implementation Tasks List
277
562
 
278
563
  For a phase-spec modification, AI generates a concrete task list and writes it into the spec's `Implementation Tasks` section using `[LAYER]-[NUMBER]:description` (DOMAIN / APP / INFRA / API / TEST).
@@ -286,12 +571,22 @@ If the lightweight checklist looks larger than a short-fix checklist, AI must pa
286
571
  Announce to developer:
287
572
  > "DDD impact analysis done — {Aggregate boundary OK / needs redesign}, {no new events / new events needed}. Ready to implement? `/dflow:next` to proceed, or adjust the design first."
288
573
 
289
- > 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.
574
+ > 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.
290
575
 
291
576
  Wait for confirmation before entering Step 4.
292
577
 
293
578
  ## Step 4: Implement
294
579
 
580
+ > **Post-hoc hotfix (Step 1.8) — skip this step.** The implementation already
581
+ > landed on the mainline before any ceremony ran; that is the whole premise of
582
+ > post-hoc mode, and Step 1.8 item 2 forbids redoing it. There is nothing to
583
+ > implement here. Go straight to the Step 4 → Step 5 gate and on through Step 5;
584
+ > checkpoint 1 (§ 5.5) then commits **documentation only** — the T2 spec or T3
585
+ > row, this host's `_index.md` and what Step 5 wrote, and no source.
586
+ > Re-implementing the fix on this branch would satisfy the letter
587
+ > of the checkpoint while breaking §8's reconciliation contract, which is why
588
+ > closeout inspects that commit's changed paths.
589
+
295
590
  Follow the layer order: Domain → Application → Infrastructure → Presentation.
296
591
 
297
592
  Even for bug fixes, verify:
@@ -306,19 +601,20 @@ Even for bug fixes, verify:
306
601
  Announce to developer:
307
602
  > "Implementation appears complete. Ready to update documentation (spec, models.md, rules.md, events.md, glossary, tech-debt)? `/dflow:next` to proceed."
308
603
 
309
- > 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.
310
-
311
- Wait for confirmation before entering Step 5. This step gate is where the completion checklist is triggered — do not skip.
604
+ Wait for confirmation before entering Step 5. 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 5 (§ 5.5).
312
605
 
313
606
  ## Step 5: Update Documentation
314
607
 
315
608
  Triggered by the Step 4 → Step 5 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).
316
609
 
610
+ > **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, 5.1's spec and Domain items and all of 5.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 **no-BR family T2** has a spec but no BR delta: its **BR-derived** items are N/A (5.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 adds an event field still updates `events.md`; a family (e) defect in an Aggregate 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.
611
+
317
612
  ### 5.1 Verification — AI runs independently
318
613
 
319
614
  Items marked *(post-5.3)* are re-verified after the documentation merge in 5.3 lands:
320
615
 
321
616
  - [ ] Every ADDED / MODIFIED / REMOVED / RENAMED entry in the Delta section is covered by implementation or tests
617
+ - [ ] **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) event-field addition still updates `events.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
322
618
  - [ ] The fix is in the correct layer (Domain / Application / Infrastructure / Presentation)
323
619
  - [ ] Domain layer/package has **no** external package-manager dependencies beyond the language/runtime baseline
324
620
  - [ ] Aggregate invariants still hold; state changes go through methods
@@ -326,7 +622,7 @@ Items marked *(post-5.3)* are re-verified after the documentation merge in 5.3 l
326
622
  - [ ] ORM / persistence mapping is kept outside Domain entities (no persistence attributes/annotations on Domain entities)
327
623
  - [ ] `Implementation Tasks` section (`phase-spec.md` or `lightweight-spec.md`): all tasks checked, or unchecked items explicitly labelled as follow-up
328
624
  - [ ] *(post-5.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`)
329
- - [ ] *(post-5.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)
625
+ - [ ] *(post-5.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.
330
626
 
331
627
  If any item fails, report the gap and pause — don't proceed to 5.2.
332
628
 
@@ -343,11 +639,17 @@ Ask these one-by-one.
343
639
 
344
640
  ### 5.3 Documentation updates
345
641
 
346
- - [ ] Update or create the feature / bug spec; set `status: completed`
642
+ > **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).
643
+
644
+ - [ ] Update or create the feature / bug spec; set `status: completed` — **T3: N/A** (no spec file exists; the `_index.md` inline row is the record, and the host's own status is not touched)
645
+ - [ ] **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 and a T3
646
+ - [ ] 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}/` plus `context-map.md`: 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 `architecture/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 architecture 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 (an added event field still lands in `events.md`)
347
647
  - [ ] `dflow/specs/domain/{context}/models.md` — Aggregate structure updates
648
+ - [ ] `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)
348
649
  - [ ] `dflow/specs/domain/{context}/rules.md` — business rule updates
349
650
  - [ ] `dflow/specs/domain/{context}/events.md` — Domain Event updates
350
651
  - [ ] `dflow/specs/domain/glossary.md` — new / renamed terms (mirror any RENAMED delta entries here)
652
+ - [ ] `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)
351
653
  - [ ] `dflow/specs/domain/{context}/behavior.md` — update scenarios to reflect Delta result (merge final state, not Delta markup). Sub-steps:
352
654
  - Promote any Activity 3 (Spec Writing) draft sections (from B3 mid-sync) to formal sections
353
655
  - Update the corresponding `rules.md` anchor's `last-updated` date (B4)
@@ -379,9 +681,15 @@ file move at this point. The whole feature directory moves to
379
681
  If this modification was a **T3 inline-only** change, no spec file
380
682
  exists — archival is just leaving the row in `_index.md` Lightweight Changes.
381
683
 
382
- If the modification was a **standalone follow-up feature** (created
383
- via Step 1.6), the same rule applies: this flow does not archive the
384
- new follow-up directory; that happens at `/dflow:finish-feature` time.
684
+ If the modification opened a **standalone minimal host** (Step 1.7) or a
685
+ **follow-up feature** (created via Step 1.6, including its minimal
686
+ variant), the same rule applies: this flow does not archive the host
687
+ directory — the closeout `git mv` happens at `/dflow:finish-feature` time
688
+ (checkpoint 2 of the two-checkpoint minimal-host lifecycle).
385
689
 
386
690
  Only announce "change complete" after the appropriate archival step
387
691
  above (or the Step 5.3 docs sweep) is done.
692
+
693
+ ### 5.5 Commit checkpoint (checkpoint 1)
694
+
695
+ > 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–5 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, then closeout), for T3 as well as T2. **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 5 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.