dflow-sdd-ddd 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +824 -1
  2. package/CONTRIBUTING.md +16 -10
  3. package/README.en.md +156 -200
  4. package/README.md +89 -144
  5. package/TEMPLATE-COVERAGE.md +15 -8
  6. package/TEMPLATE-LANGUAGE-GLOSSARY.md +15 -1
  7. package/bin/dflow.js +36 -4
  8. package/docs/commands.en.md +110 -0
  9. package/docs/commands.md +101 -0
  10. package/docs/doctor-uncertainty.en.md +212 -0
  11. package/docs/doctor-uncertainty.md +212 -0
  12. package/docs/evaluating-dflow.en.md +29 -11
  13. package/docs/evaluating-dflow.md +8 -6
  14. package/docs/npm-publish-checklist.md +3 -1
  15. package/docs/release-versioning-policy.md +8 -2
  16. package/docs/upgrading.en.md +196 -0
  17. package/docs/upgrading.md +197 -0
  18. package/docs/using-with-claude-code.en.md +25 -10
  19. package/docs/using-with-claude-code.md +20 -7
  20. package/docs/using-with-codex.en.md +18 -6
  21. package/docs/using-with-codex.md +16 -5
  22. package/docs/using-with-github-copilot.en.md +25 -10
  23. package/docs/using-with-github-copilot.md +21 -8
  24. package/lib/doc-shapes.json +997 -0
  25. package/lib/doctor-checks.js +2654 -0
  26. package/lib/init.js +3583 -107
  27. package/lib/render-diagrams.js +1474 -0
  28. package/lib/render.js +865 -49
  29. package/package.json +2 -2
  30. package/templates/brownfield/references/drift-verification.md +4 -0
  31. package/templates/brownfield/references/finish-feature-flow.md +635 -88
  32. package/templates/brownfield/references/finish-feature-follow-up.md +60 -0
  33. package/templates/brownfield/references/finish-feature-minimal-host.md +406 -0
  34. package/templates/brownfield/references/finish-feature-post-hoc-hotfix.md +95 -0
  35. package/templates/brownfield/references/git-integration.md +160 -15
  36. package/templates/brownfield/references/init-project-flow.md +26 -4
  37. package/templates/brownfield/references/modify-existing-flow.md +412 -87
  38. package/templates/brownfield/references/modify-existing-follow-up.md +121 -0
  39. package/templates/brownfield/references/modify-existing-post-hoc-hotfix.md +82 -0
  40. package/templates/brownfield/references/new-feature-flow.md +61 -6
  41. package/templates/brownfield/references/new-phase-flow.md +57 -7
  42. package/templates/brownfield/references/pr-review-checklist.md +303 -10
  43. package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +158 -34
  44. package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +1 -1
  45. package/templates/brownfield/scaffolding/Git-principles-gitflow.md +75 -6
  46. package/templates/brownfield/scaffolding/Git-principles-trunk.md +82 -8
  47. package/templates/brownfield/scaffolding/_conventions.md +50 -28
  48. package/templates/brownfield/scaffolding/_overview.md +1 -0
  49. package/templates/brownfield/templates/_index.md +151 -7
  50. package/templates/brownfield/templates/analysis.md +79 -0
  51. package/templates/brownfield/templates/behavior.md +1 -0
  52. package/templates/brownfield/templates/context-definition.md +1 -0
  53. package/templates/brownfield/templates/context-map.md +2 -1
  54. package/templates/brownfield/templates/glossary.md +1 -0
  55. package/templates/brownfield/templates/lightweight-spec.md +154 -11
  56. package/templates/brownfield/templates/models.md +1 -0
  57. package/templates/brownfield/templates/phase-spec.md +9 -1
  58. package/templates/brownfield/templates/rules.md +1 -0
  59. package/templates/brownfield/templates/tech-debt.md +1 -0
  60. package/templates/common/references/ddd-modeling-guide.md +33 -16
  61. package/templates/{greenfield → common}/references/dflow-feedback-flow.md +2 -1
  62. package/templates/common/references/flow-rationale-registry.md +130 -0
  63. package/templates/common/skill/SKILL.md +13 -11
  64. package/templates/greenfield/references/drift-verification.md +4 -0
  65. package/templates/greenfield/references/finish-feature-flow.md +625 -89
  66. package/templates/greenfield/references/finish-feature-follow-up.md +60 -0
  67. package/templates/greenfield/references/finish-feature-minimal-host.md +363 -0
  68. package/templates/greenfield/references/finish-feature-post-hoc-hotfix.md +95 -0
  69. package/templates/greenfield/references/git-integration.md +148 -15
  70. package/templates/greenfield/references/init-project-flow.md +28 -8
  71. package/templates/greenfield/references/modify-existing-flow.md +378 -85
  72. package/templates/greenfield/references/modify-existing-follow-up.md +103 -0
  73. package/templates/greenfield/references/modify-existing-post-hoc-hotfix.md +82 -0
  74. package/templates/greenfield/references/new-feature-flow.md +67 -4
  75. package/templates/greenfield/references/new-phase-flow.md +56 -7
  76. package/templates/greenfield/references/pr-review-checklist.md +287 -8
  77. package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +153 -32
  78. package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +5 -2
  79. package/templates/greenfield/scaffolding/Git-principles-gitflow.md +74 -6
  80. package/templates/greenfield/scaffolding/Git-principles-trunk.md +88 -12
  81. package/templates/greenfield/scaffolding/_conventions.md +50 -28
  82. package/templates/greenfield/scaffolding/_overview.md +6 -2
  83. package/templates/greenfield/templates/_index.md +137 -7
  84. package/templates/greenfield/templates/aggregate-design.md +1 -0
  85. package/templates/greenfield/templates/analysis.md +79 -0
  86. package/templates/greenfield/templates/behavior.md +1 -0
  87. package/templates/greenfield/templates/context-definition.md +1 -0
  88. package/templates/greenfield/templates/context-map.md +2 -1
  89. package/templates/greenfield/templates/events.md +4 -1
  90. package/templates/greenfield/templates/glossary.md +1 -0
  91. package/templates/greenfield/templates/lightweight-spec.md +154 -11
  92. package/templates/greenfield/templates/models.md +1 -0
  93. package/templates/greenfield/templates/phase-spec.md +9 -1
  94. package/templates/greenfield/templates/rules.md +1 -0
  95. package/templates/greenfield/templates/tech-debt.md +1 -0
  96. package/templates/brownfield/references/dflow-feedback-flow.md +0 -251
@@ -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,212 @@ 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
+ 3. **Create the minimal `_index.md`** from `templates/_index.md` at
290
+ `dflow/specs/features/active/{SPEC-ID}-{slug}/_index.md`, carrying all
291
+ **seven required sections** that template names — the Metadata front
292
+ matter, Goals & Scope, Phase Specs, Current BR Snapshot, Lightweight
293
+ Changes, Checkpoint Log, Resume Pointer. (`Follow-up Tracking` is the
294
+ template's **optional** eighth section; a standalone host gets one only if
295
+ it later grows follow-ups of its own.) "Minimal" means the sections are
296
+ thin, not missing:
297
+ - Metadata `status: in-progress`; `branch:` = the branch you cut in
298
+ step 4. This field is **authoritative** — the branch gate and any
299
+ lightweight-spec frontmatter read their branch from it.
300
+ - Goals & Scope: one or two sentences. A standalone change need not
301
+ touch a bounded context; if it does not, say so plainly in Goals &
302
+ Scope rather than inventing one.
303
+ - Phase Specs: **leave the table empty** — a minimal host has no
304
+ phase-spec.
305
+ - Current BR Snapshot: fill it only if the change carries a BR delta; a
306
+ no-BR / T3 host leaves it empty (finish-feature Step 1 reads an
307
+ intentionally empty snapshot as a no-BR feature, not a validation
308
+ failure).
309
+ - Lightweight Changes, Checkpoint Log, Resume Pointer: start them; the
310
+ record and the two checkpoints land here as you go.
311
+ 4. **Branch gate — by change class.** A **functional bug** cuts
312
+ `bugfix/BUG-{NUMBER}-{slug}`, using the BUG-NUMBER assigned and
313
+ collision-checked in step 2. **Otherwise** — a standalone non-bug **T2 / T3** — cut
314
+ `feature/{SPEC-ID}-{slug}`. The
315
+ `_index.md` `branch:` field must equal the branch cut here. (See
316
+ `references/git-integration.md` § Commit Checkpoints, Branch Gate & AI
317
+ Commits.)
318
+
319
+ **Record + commit — rejoin the normal flow.** Follow this flow's
320
+ tier-aware routing (Part A): a **T2** writes its lightweight-spec (classic
321
+ BR form or the matching no-BR family variant — shapes are defined in
322
+ `templates/lightweight-spec.md`) and runs the Step 2–5 record **to the depth
323
+ Part A set** — that range names the route, not an instruction to run every item
324
+ in it. In particular a **no-BC** T2 — one whose host Goals & Scope says it
325
+ touches no bounded context — does not acquire one by walking Step 2: it does no
326
+ Domain-file work there (Step 2 carries the same guard at its own site), so
327
+ closeout's no-BC branch has nothing fictitious to skip past. A **T3**
328
+ skips the Domain / DDD-impact work and records an inline row in
329
+ `_index.md` Lightweight Changes — **one row per atomic T3 change**, so a
330
+ compound request records each of them here (see "minimal means zero-phase,
331
+ not one-artifact" above). The **implementation commit is checkpoint
332
+ 1** — the Step 4 → Step 5 commit checkpoint records it in the Checkpoint
333
+ Log. (For a **post-hoc** host, Step 4 is skipped and checkpoint 1 is the
334
+ **documentation** commit instead; see Step 1.8 and Step 4's guard.)
335
+
336
+ **Every artifact gets a Lightweight Changes row, and every row is written
337
+ *before* checkpoint 1.** A **T3**'s row *is* its whole record; a **T2**'s row is
338
+ the outbound link to its lightweight-spec — both are rows, and closeout requires
339
+ one per artifact. Write them now, carrying the tier, the description and the
340
+ implementation paths. The **only** part that may appear afterwards is the
341
+ `Commit` cell, which cannot exist until its commit does: closeout's allow-list
342
+ admits that cell and no other change **to the row**, so a row added after
343
+ checkpoint 1 **blocks**. (The allow-list separately admits the Checkpoint Log
344
+ rows, the Resume Pointer and the Current BR Snapshot — the finalization edits
345
+ this step makes next.)
346
+
347
+ **Name the implementation paths in the artifact.** Closeout's evidence checks
348
+ assert that a commit *touches the implementation paths this change describes* —
349
+ which is only mechanical if the artifact actually declares them. So a **T2**'s
350
+ lightweight-spec names the source paths it changes, and a **T3**'s row
351
+ Description names them alongside its one-line description and tag. Paths, not a
352
+ diff — enough to compare a commit against. An artifact that declares none
353
+ leaves that check nothing to compare, and finish-feature treats a missing
354
+ declaration as a **block**, not a pass.
355
+
356
+ **Finalize + close.** Before `/dflow:finish-feature`, run the Step 5
357
+ completion checklist's minimal-host finalization. For **every** T2: set the
358
+ lightweight-spec `status: completed`, record its commit evidence, and advance
359
+ the Resume Pointer to the closeout-ready state. **Only when that T2 is
360
+ BC-bearing**, additionally refresh the host's Current BR Snapshot — a no-BC T2
361
+ has no snapshot to refresh, but still owes the commit evidence and the Resume
362
+ Pointer. A **T3** has no spec file — record its inline row's commit evidence
363
+ and advance the Resume Pointer.
364
+
365
+ **Commit evidence goes to two surfaces, always — every row, every tier.** They
366
+ answer different questions, so filling one is never filling the other, and
367
+ finish-feature Step 1 reads both:
368
+
369
+ - **Checkpoint Log Result** — what happened at the *lifecycle checkpoint*.
370
+ - **Lightweight Changes row `Commit`** — the commit carrying *that row's own
371
+ artifact*. Every row needs one; a blank cell fails closeout — **and so does a
372
+ placeholder**. `{hash}`, `{pending}`, `(待 commit)`, anything
373
+ `git cat-file -t` cannot resolve to a commit: it counts as **unfilled**, not
374
+ as filled. Leave the cell empty until the hash exists.
375
+
376
+ The **mode** changes only *which hash* each surface carries:
377
+
378
+ - **Normal** (T2 or T3) — Checkpoint Log Result `committed ({hash})` and the
379
+ row's `Commit` cell both name **checkpoint 1**, the single commit that
380
+ carried the artifact and the implementation together. Two cells, one hash;
381
+ fill both.
382
+ - **Post-hoc hotfix** (Step 1.8; T2 or T3) — the Checkpoint Log Result stays
383
+ `reconciled ({merged-hotfix-hash})`, **never overwrite it**, while the row's
384
+ `Commit` cell carries the **documentation** commit's hash. This is the one
385
+ mode where the two values genuinely differ (Step 1.8 item 4).
386
+
387
+ **A declined checkpoint still owes its hash.** If the developer answered **N**
388
+ at the checkpoint-1 offer and made that commit themselves, the Checkpoint Log
389
+ row was written `skipped` honestly — the AI did not commit — but it is now
390
+ **incomplete, not final**: complete it here to `committed ({hash})` with the
391
+ developer's actual hash. **That completion is for a normal checkpoint 1.** On a
392
+ **post-hoc** host the Result stays
393
+ `reconciled ({merged-hotfix-hash})` — a declined documentation commit is
394
+ completed by filling each Lightweight Changes row's `Commit` cell once the
395
+ developer's commit lands, never by overwriting the reconciliation hash, which
396
+ records a different commit entirely. A row left reading `skipped` blocks closeout, and
397
+ finish-feature cannot tell "declined then committed" from "never committed" on
398
+ your behalf. The **closeout** row is the deliberate exception — it carries no
399
+ hash at all, because a commit cannot contain its own. Its **Result is still
400
+ read** afterwards — finish-feature's post-commit gate rejects `failed` there. A
401
+ declined closeout stays `skipped` because that value records the declined offer
402
+ honestly, not because the row goes unread.
403
+
404
+ In every case leave the host `status: in-progress` until
405
+ closeout — do not flip the host to `completed` early and do not invent a spec
406
+ file for a T3. Then `/dflow:finish-feature` performs the zero-phase closeout,
407
+ and its **closeout commit is checkpoint 2** — it includes the `git mv`
408
+ archival. The two checkpoints each record their own Checkpoint Log row
409
+ (implementation, then closeout); they are asserted separately, never merged
410
+ into one.
411
+
412
+ ## Step 1.8: Hotfix T2 / T3 Post-Hoc (documenting an already-merged emergency change that Part A classified T2 or T3)
413
+
414
+ **Open `references/modify-existing-post-hoc-hotfix.md` and follow it there.**
415
+ This step's rules live in that file and are not repeated here.
416
+
417
+ ⚠ Do not record a post-hoc hotfix from this heading alone. That file carries the
418
+ host-linkage choice, the `reconciled ({merged-hotfix-hash})` checkpoint Result,
419
+ the identity citation an **uncited** hash blocks closeout for, and the per-tier
420
+ hotfix trace. Reconstructed from this heading, post-hoc mode collapses into
421
+ re-implementing a fix that is already on the mainline — which Step 4's guard
422
+ forbids and closeout inspects that checkpoint's changed paths for.
170
423
 
171
424
  ## Step 2: Check Documentation
172
425
 
@@ -177,7 +430,17 @@ phase's content).
177
430
 
178
431
  If no documentation exists, capture current behavior BEFORE changing — use the **Delta** format below.
179
432
 
180
- If baseline domain docs are missing, create them from templates before filling content:
433
+ > **No-BC guard — never manufacture a bounded context to satisfy this step.**
434
+ > The creations below apply only when the change actually touches one. A
435
+ > **no-BC** change — a standalone appearance sweep, say, whose host Goals &
436
+ > Scope states it touches no bounded context — records **N/A** here and moves
437
+ > on. Inventing a `{context}` it does not have plants fictitious Domain files
438
+ > that finish-feature's no-BC closeout branch **skips past rather than
439
+ > removes**, so they survive into the archive as permanent fiction. Same rule
440
+ > as Step 5.3's tier-conditional note: state the verdict, do not manufacture
441
+ > the artifact an item names.
442
+
443
+ If baseline domain docs are missing **for a change that does touch a bounded context**, create them from templates before filling content:
181
444
  - `dflow/specs/domain/glossary.md` → `templates/glossary.md`
182
445
  - `dflow/specs/domain/{context}/models.md` → `templates/models.md`
183
446
  - `dflow/specs/domain/{context}/rules.md` → `templates/rules.md`
@@ -273,6 +536,17 @@ If constraints change:
273
536
  - Update Value Object validation
274
537
  - Check all usages of the Value Object
275
538
 
539
+ ### What system-level knowledge did this change depend on?
540
+ Look for what this change depends on and no single context document holds:
541
+ - **Cross-context flows** — ordered steps owned by more than one context (always the domain-root copy)
542
+ - **Lifecycles** — a status field and the transitions it moves through
543
+ - **Read models and derived figures** — a number computed rather than stored
544
+ - **Mechanisms** — behavior no single rule explains
545
+ - **Function / role index** — which roles reach this function, and what data each one sees (always the domain-root copy)
546
+ - **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)
547
+
548
+ 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.
549
+
276
550
  ### Generate Implementation Tasks List
277
551
 
278
552
  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 +560,21 @@ If the lightweight checklist looks larger than a short-fix checklist, AI must pa
286
560
  Announce to developer:
287
561
  > "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
562
 
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.
563
+ > 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
564
 
291
565
  Wait for confirmation before entering Step 4.
292
566
 
293
567
  ## Step 4: Implement
294
568
 
569
+ > **Post-hoc hotfix (Step 1.8) — skip this step.** The implementation already
570
+ > landed on the mainline before any ceremony ran; that is the whole premise of
571
+ > post-hoc mode, and Step 1.8 item 2 forbids redoing it. There is nothing to
572
+ > implement here. Go straight to the Step 4 → Step 5 gate and commit
573
+ > **documentation only** — the T2 spec or T3 row plus this host's `_index.md`,
574
+ > and no source. Re-implementing the fix on this branch would satisfy the letter
575
+ > of the checkpoint while breaking §8's reconciliation contract, which is why
576
+ > closeout inspects that commit's changed paths.
577
+
295
578
  Follow the layer order: Domain → Application → Infrastructure → Presentation.
296
579
 
297
580
  Even for bug fixes, verify:
@@ -306,7 +589,7 @@ Even for bug fixes, verify:
306
589
  Announce to developer:
307
590
  > "Implementation appears complete. Ready to update documentation (spec, models.md, rules.md, events.md, glossary, tech-debt)? `/dflow:next` to proceed."
308
591
 
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.
592
+ > 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 implementation commit, and its `_index.md` rows ride along on the host's next commit (see `references/git-integration.md` § Commit checkpoints). **Minimal host exception (Step 1.7 standalone *and* the Step 1.6 follow-up variant)**: a minimal host has no later host commit for a T3 row to ride along on, so **the row rides checkpoint 1 itself** — write it into `_index.md` *before* this commit, alongside the implementation, because finish-feature Step 1 reads **checkpoint 1's committed `_index.md`** for it. Only what cannot exist until the commit does — the row's `Commit` cell and the Checkpoint Log Result — is backfilled later and rides 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`, 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.
310
593
 
311
594
  Wait for confirmation before entering Step 5. This step gate is where the completion checklist is triggered — do not skip.
312
595
 
@@ -314,11 +597,14 @@ Wait for confirmation before entering Step 5. This step gate is where the comple
314
597
 
315
598
  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
599
 
600
+ > **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.
601
+
317
602
  ### 5.1 Verification — AI runs independently
318
603
 
319
604
  Items marked *(post-5.3)* are re-verified after the documentation merge in 5.3 lands:
320
605
 
321
606
  - [ ] Every ADDED / MODIFIED / REMOVED / RENAMED entry in the Delta section is covered by implementation or tests
607
+ - [ ] **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
608
  - [ ] The fix is in the correct layer (Domain / Application / Infrastructure / Presentation)
323
609
  - [ ] Domain layer/package has **no** external package-manager dependencies beyond the language/runtime baseline
324
610
  - [ ] Aggregate invariants still hold; state changes go through methods
@@ -326,7 +612,7 @@ Items marked *(post-5.3)* are re-verified after the documentation merge in 5.3 l
326
612
  - [ ] ORM / persistence mapping is kept outside Domain entities (no persistence attributes/annotations on Domain entities)
327
613
  - [ ] `Implementation Tasks` section (`phase-spec.md` or `lightweight-spec.md`): all tasks checked, or unchecked items explicitly labelled as follow-up
328
614
  - [ ] *(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)
615
+ - [ ] *(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
616
 
331
617
  If any item fails, report the gap and pause — don't proceed to 5.2.
332
618
 
@@ -343,11 +629,16 @@ Ask these one-by-one.
343
629
 
344
630
  ### 5.3 Documentation updates
345
631
 
346
- - [ ] Update or create the feature / bug spec; set `status: completed`
632
+ > **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).
633
+
634
+ - [ ] 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)
635
+ - [ ] 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
636
  - [ ] `dflow/specs/domain/{context}/models.md` — Aggregate structure updates
637
+ - [ ] `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
638
  - [ ] `dflow/specs/domain/{context}/rules.md` — business rule updates
349
639
  - [ ] `dflow/specs/domain/{context}/events.md` — Domain Event updates
350
640
  - [ ] `dflow/specs/domain/glossary.md` — new / renamed terms (mirror any RENAMED delta entries here)
641
+ - [ ] `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
642
  - [ ] `dflow/specs/domain/{context}/behavior.md` — update scenarios to reflect Delta result (merge final state, not Delta markup). Sub-steps:
352
643
  - Promote any Activity 3 (Spec Writing) draft sections (from B3 mid-sync) to formal sections
353
644
  - Update the corresponding `rules.md` anchor's `last-updated` date (B4)
@@ -379,9 +670,11 @@ file move at this point. The whole feature directory moves to
379
670
  If this modification was a **T3 inline-only** change, no spec file
380
671
  exists — archival is just leaving the row in `_index.md` Lightweight Changes.
381
672
 
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.
673
+ If the modification opened a **standalone minimal host** (Step 1.7) or a
674
+ **follow-up feature** (created via Step 1.6, including its minimal
675
+ variant), the same rule applies: this flow does not archive the host
676
+ directory — the closeout `git mv` happens at `/dflow:finish-feature` time
677
+ (checkpoint 2 of the two-checkpoint minimal-host lifecycle).
385
678
 
386
679
  Only announce "change complete" after the appropriate archival step
387
680
  above (or the Step 5.3 docs sweep) is done.