dflow-sdd-ddd 0.10.0 → 0.12.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 (42) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/README.en.md +57 -43
  3. package/README.md +36 -33
  4. package/TEMPLATE-LANGUAGE-GLOSSARY.md +1 -0
  5. package/bin/dflow.js +4 -8
  6. package/docs/why-dflow.en.md +72 -0
  7. package/docs/why-dflow.md +72 -0
  8. package/lib/init.js +114 -77
  9. package/package.json +2 -2
  10. package/templates/brownfield/references/drift-verification.md +40 -6
  11. package/templates/brownfield/references/finish-feature-flow.md +85 -29
  12. package/templates/brownfield/references/git-integration.md +29 -9
  13. package/templates/brownfield/references/modify-existing-flow.md +61 -0
  14. package/templates/brownfield/references/new-feature-flow.md +62 -1
  15. package/templates/brownfield/references/new-phase-flow.md +19 -1
  16. package/templates/brownfield/references/pr-review-checklist.md +7 -1
  17. package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +46 -33
  18. package/templates/brownfield/scaffolding/Git-principles-gitflow.md +1 -1
  19. package/templates/brownfield/scaffolding/Git-principles-trunk.md +2 -2
  20. package/templates/brownfield/templates/_index.md +23 -4
  21. package/templates/brownfield/templates/context-map.md +12 -4
  22. package/templates/brownfield/templates/lightweight-spec.md +3 -3
  23. package/templates/brownfield/templates/phase-spec.md +3 -3
  24. package/templates/common/references/ddd-modeling-guide.md +837 -0
  25. package/templates/greenfield/references/drift-verification.md +60 -12
  26. package/templates/greenfield/references/finish-feature-flow.md +86 -29
  27. package/templates/greenfield/references/git-integration.md +29 -9
  28. package/templates/greenfield/references/modify-existing-flow.md +23 -0
  29. package/templates/greenfield/references/new-feature-flow.md +70 -8
  30. package/templates/greenfield/references/new-phase-flow.md +15 -1
  31. package/templates/greenfield/references/pr-review-checklist.md +9 -1
  32. package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +40 -33
  33. package/templates/greenfield/scaffolding/Git-principles-gitflow.md +1 -1
  34. package/templates/greenfield/scaffolding/Git-principles-trunk.md +4 -2
  35. package/templates/greenfield/templates/_index.md +23 -4
  36. package/templates/greenfield/templates/aggregate-design.md +8 -1
  37. package/templates/greenfield/templates/context-map.md +13 -4
  38. package/templates/greenfield/templates/events.md +5 -1
  39. package/templates/greenfield/templates/lightweight-spec.md +3 -3
  40. package/templates/greenfield/templates/phase-spec.md +3 -3
  41. package/docs/migrating-to-dflow-v1.md +0 -234
  42. package/templates/greenfield/references/ddd-modeling-guide.md +0 -351
@@ -4,18 +4,24 @@ Triggered by `/dflow:verify` or `/dflow:verify <bounded-context>`.
4
4
 
5
5
  ## Purpose
6
6
 
7
- The A+C structure (`rules.md` as index + `behavior.md` as scenario content) introduces a drift risk — the two files can fall out of sync. This command provides a mechanical verification safety net that developers can run at key moments: before a PR, after a refactor, or when onboarding to an unfamiliar Bounded Context.
7
+ The A+C structure (`rules.md` as index + `behavior.md` as scenario content) introduces a drift risk — the two files can fall out of sync. This command's **core** is a mechanical safety net for that `rules.md` ↔ `behavior.md` correspondence, run at key moments: before a PR, after a refactor, or when onboarding to an unfamiliar Bounded Context. On top of the core it also runs **optional, non-blocking domain-doc hygiene checks** on the BC's other docs (`events.md`, `models.md`) — see Scope.
8
8
 
9
9
  ## Scope
10
10
 
11
- ### This command does (mechanical layer)
11
+ ### This command does (core + optional hygiene)
12
12
 
13
- Three string-matching checks that AI can perform deterministically:
13
+ A small **core** of three deterministic string-matching checks on the
14
+ `rules.md` ↔ `behavior.md` correspondence:
14
15
 
15
16
  1. **BR-ID forward check**: Every `BR-*` declared in `rules.md` has a corresponding section in `behavior.md`
16
17
  2. **Anchor validity**: If `rules.md` links to `behavior.md#section`, that anchor exists
17
18
  3. **BR-ID reverse check**: Every `BR-*` referenced in `behavior.md` is declared in `rules.md`
18
19
 
20
+ Plus **optional domain-doc hygiene** warnings (non-blocking — they never fail the
21
+ command, only surface "confirm this is intentional" signals): the `events.md`
22
+ cross-check (forward + reverse, see Core-Specific Notes) and the `models.md`
23
+ Code-Mapping hygiene check (see Model Catalog Notes).
24
+
19
25
  ### This command does NOT do (semantic layer — explicitly excluded)
20
26
 
21
27
  Semantic verification (LLM reads the one-line summary in `rules.md` vs the Given/When/Then in `behavior.md` and judges whether they contradict) is **out of scope**. Reasons:
@@ -40,9 +46,9 @@ Reasons:
40
46
  - BC-level current state is already maintained by `rules.md` /
41
47
  `behavior.md` / `events.md`, written by the same
42
48
  `/dflow:finish-feature` Step 3
43
- - `/dflow:verify` keeps a small, mechanical scope: just the
44
- `rules.md` ↔ `behavior.md` correspondence inside one BC, plus the
45
- events.md bonus check below
49
+ - `/dflow:verify` keeps a small core: the `rules.md` ↔ `behavior.md`
50
+ correspondence inside one BC, plus the optional domain-doc hygiene
51
+ checks below (events.md, models.md)
46
52
  - Cross-feature / cross-phase aggregation would mix `/dflow:verify`'s
47
53
  job with `/dflow:finish-feature`'s job and produce false positives
48
54
  during in-progress features
@@ -86,6 +92,10 @@ For each Bounded Context:
86
92
  - behavior.md → templates/behavior.md
87
93
  Or run the completion flow to populate it from existing completed specs
88
94
  ```
95
+ - Also locate the **optional** hygiene inputs for this BC — `events.md` and
96
+ `models.md`. They feed the non-blocking hygiene checks (Core-Specific Notes /
97
+ Model Catalog Notes). If either is absent, **skip its hygiene check silently** —
98
+ do not report or stop; they are bonus, not part of the core.
89
99
 
90
100
  ### Step 2: Extract BR-IDs from rules.md
91
101
 
@@ -155,15 +165,52 @@ Issues:
155
165
  remove the stale scenario reference from behavior.md
156
166
  ```
157
167
 
168
+ The optional domain-doc hygiene checks (below) append their non-blocking signals
169
+ to this same report — the `events.md` cross-check as `⚠`, the `models.md`
170
+ Code-Mapping check as `ℹ` — and never change the core pass / fail count.
171
+
158
172
  ## Core-Specific Notes
159
173
 
160
- When verifying a Core context, also check:
161
- - `events.md` references in `behavior.md`: if a scenario says "And {DomainEvent} is raised", confirm the event is listed in `events.md`
162
- - This is a **bonus check**, not a blocking failure — report as a warning:
174
+ When verifying a Core context, also run the `events.md` cross-check — **both
175
+ directions, bonus only** (warnings, never a blocking failure):
176
+
177
+ - **Forward** — `events.md` referenced from `behavior.md`: if a scenario says
178
+ "And {DomainEvent} is raised", confirm the event is listed in `events.md`:
163
179
  ```
164
180
  ⚠ BR-001 scenario references ExpenseReportSubmitted event,
165
181
  but events.md does not list it
166
182
  ```
183
+ - **Reverse** — an `events.md` event with no scenario: for each Event Catalog row
184
+ that is **locally produced** (Producer is this BC's Aggregate / Application
185
+ Service) **and business-significant**, confirm at least one `behavior.md`
186
+ scenario references it; warn if none:
187
+ ```
188
+ ⚠ events.md lists OrderCancelled (produced by Order) but no behavior.md
189
+ scenario references it — confirm intentional (orphan / not yet specced)
190
+ ```
191
+ Exclude (else noisy): the `{EventName}` seed row, and best-effort side-effect
192
+ events (notification / logging) that the modeling guide lets live in
193
+ `events.md` / tech-debt without a BR. The reverse check is deterministic name
194
+ matching **plus** this applicability judgment — not a pure string match.
195
+
196
+ ## Model Catalog Notes
197
+
198
+ A non-blocking **informational** hygiene check on `models.md`:
199
+
200
+ - For each row whose **primary name cell** holds a real value, if the
201
+ `Code Mapping` column is empty or still a `{Namespace.Class}` placeholder,
202
+ surface it:
203
+ ```
204
+ ℹ models.md: Entity "ExpenseReport" has no Code Mapping yet — link it if the
205
+ code exists; if it is deliberately deferred, this is expected
206
+ ```
207
+ - **Skip untouched seed rows by the name cell only**: a row whose name is still a
208
+ `{...}` placeholder is seed scaffolding. But a row with a **real name** and a
209
+ placeholder / empty Code Mapping is exactly the one to surface — do not skip it
210
+ just because that one cell still holds `{...}`.
211
+ - This is **informational, not drift** — a recorded model with no Code Mapping is a
212
+ normal state before the code is written. An explicit "planned / deferred" note on
213
+ the row counts as accounted for; do not surface it.
167
214
 
168
215
  ## When to Run
169
216
 
@@ -178,9 +225,10 @@ Recommended trigger points (not enforced — developer's judgment):
178
225
  ## Path Assumptions
179
226
 
180
227
  This command operates entirely within `dflow/specs/domain/{context}/` files
181
- (`rules.md`, `behavior.md`, and the `events.md` bonus check). It does
182
- **not** read from `dflow/specs/features/active/{SPEC-ID}-{slug}/` directories
183
- — the feature directory layout is not part of verify's input.
228
+ (`rules.md` and `behavior.md` for the core check; `events.md` and `models.md`
229
+ for the optional hygiene warnings). It does **not** read from
230
+ `dflow/specs/features/active/{SPEC-ID}-{slug}/` directories — the feature
231
+ directory layout is not part of verify's input.
184
232
 
185
233
  ## Interaction with Other Commands
186
234
 
@@ -56,6 +56,10 @@ proceeding (do not flip status, do not archive, do not emit summary).
56
56
  - [ ] Every phase-spec file referenced in the Phase Specs table exists at
57
57
  the path the table claims
58
58
  - [ ] Every phase-spec file's frontmatter has `status: completed`
59
+ - [ ] Every Tier = T2 row in `_index.md` Lightweight Changes references an
60
+ existing `lightweight-*.md` / `BUG-*.md` file in the feature directory
61
+ - [ ] Every such lightweight / BUG spec file's frontmatter has
62
+ `status: completed`
59
63
  - [ ] `_index.md` has no obvious open items in Resume Pointer (e.g. "phase-N
60
64
  drafting" / "implementation pending" / "TODO" markers)
61
65
  - [ ] Current BR Snapshot table is non-empty (or feature is intentionally
@@ -66,6 +70,7 @@ If any check fails:
66
70
  > found:
67
71
  > ✗ phase-spec-2026-04-15-foo.md status is still `in-progress`
68
72
  > ✗ Phase Specs table row 3 references missing file phase-spec-...
73
+ > ✗ lightweight-2026-06-20-rounding.md frontmatter status is still `in-progress`
69
74
  >
70
75
  > Address these (run `/dflow:new-phase` to add missing work, or fix the
71
76
  > stale status manually), then re-run `/dflow:finish-feature`."
@@ -93,11 +98,17 @@ branch: feature/{SPEC-ID}-{slug}
93
98
  ---
94
99
  ```
95
100
 
96
- Also update the **Resume Pointer** to reflect closeout:
101
+ Also update the **Resume Pointer** to reflect closeout — this writes the
102
+ cursor's terminal state (after closeout no workflow is active on this
103
+ feature; do not edit the cursor again after the Step 4 closeout commit):
97
104
 
98
105
  ```
99
106
  **Current Progress**: feature completed ({date}); all phase-specs status = completed.
100
107
  **Next Action**: integration — push / merge / PR per the selected Git policy.
108
+ **Active Workflow**: none
109
+ **Current Step**: n/a
110
+ **Gates Passed**: n/a
111
+ **Awaiting**: none
101
112
  ```
102
113
 
103
114
  **→ Transition (step-internal)**: Step 2 complete. Announce "Step 2 complete (status flipped). Entering Step 3: Sync BR Snapshot to BC layer." and continue.
@@ -184,7 +195,8 @@ AI runs:
184
195
  ```bash
185
196
  git mv dflow/specs/features/active/{SPEC-ID}-{slug} \
186
197
  dflow/specs/features/completed/{SPEC-ID}-{slug}
187
- git status # confirm rename detection
198
+ git status # confirm rename detection AND check for `RM` — an `M` next to
199
+ # a rename means unstaged edits you must re-add before committing
188
200
  ```
189
201
 
190
202
  `git mv` is mandatory — never use plain `mv` + `git add`. This preserves
@@ -193,37 +205,75 @@ PR diff quality stays intact across the move. See
193
205
  `references/git-integration.md` § "Directory Moves Must Use git mv" for
194
206
  the full rule set.
195
207
 
196
- After the move, also `git add` any modified files from Step 3 (the
197
- updated `rules.md`, `behavior.md`, `events.md`, `context-map.md`,
198
- `glossary.md`, `architecture/tech-debt.md`, etc.) into the same stage.
199
-
200
208
  **Closeout commit checkpoint** (completes the offline Local-closeout gate):
201
209
 
202
210
  ```
203
- ✓ Feature archived to completed/ and closeout files staged
211
+ ✓ Feature archived to completed/ and closeout ready to stage
204
212
  Commit this closeout now?
205
213
  [Y] Yes — the AI commits with your Git identity (marker per _conventions.md § AI Commit Policy)
206
214
  [N] No — skip; you commit yourself
207
215
  ```
208
216
 
209
- Whether you choose Y or N, record one row in the feature `_index.md`
210
- Checkpoint Log (`closeout | committed ({hash})` or `closeout | skipped`). Only
211
- write a hash after the commit actually succeeds; if a pre-commit hook rejects it
212
- or the commit fails, record `failed` and surface the error — never write a fake
213
- hash.
214
-
215
- The Local-closeout gate is satisfied **only when the closeout is committed**:
216
- closeout complete, Checkpoint Log updated, and the working tree clean (no
217
- uncommitted changes). If you declined the commit (chose N) or it failed,
218
- Local-closeout is **not** satisfied yet — commit the staged closeout yourself
219
- before continuing; do not enter the Integration / PR gate with uncommitted
220
- changes. Once committed, the gate stands on its own offline; integration happens
221
- in Step 5 when you have network.
222
-
223
- **→ Transition (step-internal)**: Step 4 complete. Branch on whether the closeout commit landed:
224
-
225
- - **Closeout commit landed (working tree clean)** → announce "Step 4 complete (feature archived; Local-closeout gate satisfied). Entering Step 5: Integration / PR gate." and continue.
226
- - **Closeout commit was declined (N) or failed** → **stop here.** Announce "Step 4 complete (feature archived), but the Local-closeout gate is not satisfied yet — the closeout is staged but uncommitted. Commit those changes (or address the failure), then resume to Step 5." Do **not** enter Step 5 with uncommitted closeout changes.
217
+ Then, in this order:
218
+
219
+ 1. **Record the checkpoint row first.** Write one row in the moved
220
+ `_index.md` Checkpoint Log — `closeout | committed` for Y, `closeout |
221
+ skipped` for N. The closeout row carries **no commit hash**: the closeout
222
+ commit cannot contain its own hash. Trace it later via
223
+ `git log -1 -- dflow/specs/features/completed/{SPEC-ID}-{slug}` (or the
224
+ optional `Dflow-Checkpoint` trailer). The "hash only after success" rule
225
+ still applies to spec / implementation rows — closeout is the documented
226
+ exception (see `references/git-integration.md` § Commit Checkpoints,
227
+ Branch Gate & AI Commits).
228
+ 2. **Stage the whole archived feature directory:**
229
+
230
+ ```bash
231
+ git add dflow/specs/features/completed/{SPEC-ID}-{slug}
232
+ ```
233
+
234
+ This is required, not optional: `git mv` stages the rename with the
235
+ **last-committed** content, so working-tree edits made earlier in this
236
+ flow to the moved files — the Step 2 status flip and Resume Pointer
237
+ update, plus the checkpoint row you just wrote — stay **unstaged** until
238
+ this `git add`. In `git status`, the moved `_index.md` showing `RM`
239
+ instead of plain `R` is exactly this signal. Then also `git add` the
240
+ files updated in Step 3 (the updated `rules.md`, `behavior.md`,
241
+ `events.md`, `context-map.md`, `glossary.md`,
242
+ `architecture/tech-debt.md`, etc.) into the same stage.
243
+ 3. **Commit (Y) or stop (N).** For Y the AI commits. If a pre-commit hook
244
+ rejects it or the commit fails, flip the checkpoint row to `failed` (the
245
+ row is not committed yet — edit it directly), surface the error, and
246
+ treat the gate as unsatisfied.
247
+
248
+ **Post-commit closeout verification** — after a successful commit, and before
249
+ declaring the Local-closeout gate satisfied, AI runs and reports `✓` / `✗` for
250
+ every item:
251
+
252
+ - [ ] `git show HEAD:dflow/specs/features/completed/{SPEC-ID}-{slug}/_index.md`
253
+ — one blob read verifying **two** things: frontmatter `status: completed`
254
+ **and** the Checkpoint Log contains the closeout row. This reads the
255
+ **committed** content, not the working tree — the former catches "rename
256
+ carried stale content", the latter catches "row never made it into the
257
+ commit".
258
+ - [ ] `dflow/specs/features/active/{SPEC-ID}-{slug}/` no longer exists (the
259
+ directory was moved, not copied)
260
+ - [ ] `git status --short` shows no leftovers related to this feature
261
+ (working tree clean; identify any unrelated dirty files explicitly)
262
+
263
+ If any item fails, do **not** declare closeout complete — fix it (re-add and
264
+ amend, or a follow-up commit; the developer chooses) and re-verify.
265
+
266
+ The Local-closeout gate is satisfied **only when the closeout is committed and
267
+ the verification above passes**. If you declined the commit (chose N) or it
268
+ failed, Local-closeout is **not** satisfied yet — commit the staged closeout
269
+ yourself before continuing; do not enter the Integration / PR gate with
270
+ uncommitted changes. Once committed and verified, the gate stands on its own
271
+ offline; integration happens in Step 5 when you have network.
272
+
273
+ **→ Transition (step-internal)**: Step 4 complete. Branch on the verification result:
274
+
275
+ - **Closeout commit landed and post-commit verification passed** → announce "Step 4 complete (feature archived; Local-closeout gate satisfied). Entering Step 5: Integration / PR gate." and continue.
276
+ - **Closeout commit was declined (N), failed, or verification reported `✗`** → **stop here.** Announce "Step 4 complete (feature archived), but the Local-closeout gate is not satisfied yet — the closeout is staged but uncommitted, or the committed content failed verification. Commit the staged changes (or fix the failure), then resume to Step 5." Do **not** enter Step 5 with uncommitted or unverified closeout changes.
227
277
 
228
278
  ## Step 5: Emit Integration Summary (Git-strategy-neutral)
229
279
 
@@ -286,10 +336,17 @@ the developer:
286
336
 
287
337
  If no `follow-up-of` field, skip Step 6 and announce closeout complete:
288
338
  > "`/dflow:finish-feature` complete for `{SPEC-ID}-{slug}`. Feature
289
- > directory is now at `dflow/specs/features/completed/{SPEC-ID}-{slug}/`.
290
- > If you skipped the closeout commit, commit the staged changes first to
291
- > finish the Local-closeout gate. Then integration — merge / push / PR —
292
- > follows the selected Git policy, at your discretion."
339
+ > directory is now at `dflow/specs/features/completed/{SPEC-ID}-{slug}/`,
340
+ > with the Local-closeout gate satisfied (closeout committed and verified).
341
+ > Integration — merge / push / PR — follows the selected Git policy, at
342
+ > your discretion."
343
+
344
+ **In-flight reminder** — after the closeout announcement (with or without
345
+ Step 6), run the in-flight overview scan (see `AI-AGENT-GUIDE.md` § Status /
346
+ Control Commands) and list any other unfinished features in `active/` and any
347
+ in-flight feature / bugfix branches. Surfacing them at closeout is deliberate:
348
+ attention is about to move elsewhere, and this is exactly where half-done work
349
+ sinks.
293
350
 
294
351
  ## Step 6: Reverse-Update Follow-up Tracking (only if follow-up)
295
352
 
@@ -43,8 +43,8 @@ bugfix/{BUG-ID}-{slug}
43
43
  Examples:
44
44
 
45
45
  ```
46
- feature/EXP-001-expense-submission-aggregate
47
- feature/HR-003-leave-approval-workflow
46
+ feature/SPEC-20260424-002-submit-expense-report
47
+ feature/SPEC-20260430-001-leave-approval-workflow
48
48
  bugfix/BUG-042-money-rounding
49
49
  ```
50
50
 
@@ -149,10 +149,30 @@ existing Step Gate prompt (it does not add a separate question):
149
149
  Tier sets how many checkpoints a change has: T1 three (spec / implementation /
150
150
  closeout), T2 two (spec+implementation merged / closeout), T3 a single commit.
151
151
  Whether you choose Y or N, the AI records one row in the feature `_index.md`
152
- Checkpoint Log. A commit hash is written only after the commit succeeds; a hook
153
- rejection or failed commit is recorded as `failed` (never a fake hash). After
154
- several consecutive skips in a project the AI mentions you can turn checkpoints
155
- off in config — it does not turn them off for you.
152
+ Checkpoint Log — every checkpoint is accounted for (`committed` / `skipped` /
153
+ `failed`), even when no commit happens. A commit hash is written only after the
154
+ commit succeeds; a hook rejection or failed commit is recorded as `failed`
155
+ (never a fake hash). **Exception — the closeout row**: the closeout commit
156
+ cannot contain its own hash, so the closeout row is written before the commit
157
+ as `closeout | committed` with **no hash** (see
158
+ `references/finish-feature-flow.md` Step 4); trace that commit via
159
+ `git log -1 -- dflow/specs/features/completed/{SPEC-ID}-{slug}` or the optional
160
+ `Dflow-Checkpoint` trailer below. After several consecutive skips in a project
161
+ the AI mentions you can turn checkpoints off in config — it does not turn them
162
+ off for you.
163
+
164
+ **Optional machine-greppable trailer.** Teams that want cross-flow checkpoint
165
+ accounting can append a commit trailer at checkpoint commits:
166
+
167
+ ```
168
+ Dflow-Checkpoint: {SPEC-ID} {spec|impl|closeout}
169
+ ```
170
+
171
+ The `_index.md` Checkpoint Log **remains the source of truth**; the trailer is
172
+ a cheap derived mirror (`git log --grep 'Dflow-Checkpoint: {SPEC-ID}'`). Use
173
+ role names, not (k/N) counts — the checkpoint total can change mid-feature
174
+ (tier escalation, follow-ups), and a role gap ("impl exists but no closeout for
175
+ this SPEC-ID") is detectable without predicting N, even across flows.
156
176
 
157
177
  ### AI commits
158
178
 
@@ -312,9 +332,9 @@ with the rule.
312
332
  ```
313
333
  [SPEC-ID] Short description
314
334
 
315
- [EXP-001] Define ExpenseReport Aggregate with submission invariants
316
- [EXP-001] Add CreateExpenseReport command and handler
317
- [EXP-001] Implement persistence configuration for ExpenseReport
335
+ [SPEC-20260424-002] Define ExpenseReport Aggregate with submission invariants
336
+ [SPEC-20260424-002] Add CreateExpenseReport command and handler
337
+ [SPEC-20260424-002] Implement persistence configuration for ExpenseReport
318
338
  [BUG-042] Fix rounding in Money value object
319
339
  ```
320
340
 
@@ -9,6 +9,8 @@ Triggered by `/dflow:modify-existing` or `/dflow:bug-fix` (or natural language i
9
9
  - Step 3 → Step 4 (DDD impact decision → implement)
10
10
  - Step 4 → Step 5 (implementation done → update documentation)
11
11
 
12
+ Crossing any step gate above also updates the host feature's `_index.md` Resume Pointer cursor (Active Workflow / Current Step / Gates Passed / Awaiting) once the host feature directory exists — fold it into that gate's existing `_index.md` / Resume Pointer edit, no separate ceremony (see the `_index.md` template's Resume Pointer notes).
13
+
12
14
  All other step transitions are **step-internal**: announce "Step N complete, entering Step N+1" and proceed without waiting. See AI-AGENT-GUIDE.md § Workflow Transparency for the full transparency protocol and confirmation signals.
13
15
 
14
16
  **Note on step count**: Greenfield edition has 5 steps (Brownfield has
@@ -61,6 +63,16 @@ Walk through these in order:
61
63
  this is a new concern. For T1, use `/dflow:new-feature`. For T2 / T3
62
64
  on a standalone bug, see Step 1.5 — `/dflow:bug-fix` will create a
63
65
  minimal feature directory to host the lightweight-spec.
66
+ 4. **In-flight overlap scan (cross-branch)**: this branch's `active/` is not
67
+ everything in flight. Run the in-flight scan (classification and dedup
68
+ rules in `AI-AGENT-GUIDE.md` § Status / Control Commands) — `git fetch`
69
+ when the network allows, then
70
+ `git branch --all --list '*feature/*' --list '*bugfix/*'` — and also list
71
+ other unfinished features in this branch's `active/` (one cursor line
72
+ each). If a scanned branch classified as in flight elsewhere, closed out
73
+ awaiting integration, or unknown — or an unfinished feature — semantically
74
+ overlaps this change, surface it and wait for the developer to decide
75
+ before creating anything new (stale branches are non-blocking).
64
76
 
65
77
  > **Why scan completed too?** Completed features are frozen history
66
78
  > and **cannot accept** any T2 / T3 directly
@@ -237,6 +249,17 @@ Changes that require Aggregate redesign:
237
249
  boundary still make sense, or do we need to split/merge?"
238
250
  ```
239
251
 
252
+ **Established-model re-read.** When the change extends an existing
253
+ Aggregate, re-read that Aggregate's recorded Design Decisions — its
254
+ `aggregate-design.md` worksheet in the feature directory that introduced it
255
+ (usually under `features/completed/`). If this change matches a recorded
256
+ re-evaluation condition ("revisit when …") or trips a model-resistance
257
+ signal, follow `references/ddd-modeling-guide.md` § "Revising an
258
+ Established Model": record one short passage in the spec's Design
259
+ Decisions / Open Questions — proceed as-is, split, or rename, with the
260
+ reason. Deciding to keep the current model, recorded, is a valid outcome;
261
+ extending silently is not.
262
+
240
263
  ### Do we need new Domain Events?
241
264
 
242
265
  If the behavior change means other parts of the system need to react differently:
@@ -10,6 +10,8 @@ Triggered by `/dflow:new-feature` (or natural language implying a new-feature ta
10
10
  - Step 6 → Step 7 (branch ready → start implementation)
11
11
  - Step 7 → Step 8 (implementation done → completion)
12
12
 
13
+ Crossing any step gate above also updates the host feature's `_index.md` Resume Pointer cursor (Active Workflow / Current Step / Gates Passed / Awaiting) once the feature directory exists — fold it into that gate's existing `_index.md` / Resume Pointer edit, no separate ceremony (see the `_index.md` template's Resume Pointer notes).
14
+
13
15
  All other step transitions are **step-internal**: announce "Step N complete, entering Step N+1" and proceed without waiting. See AI-AGENT-GUIDE.md § Workflow Transparency for the full transparency protocol and confirmation signals.
14
16
 
15
17
  **Ceremony**: this flow always defaults to **T1 Heavy** — the first phase of a brand-new feature is by definition a full SDD cycle. Tier judgement (T1 / T2 / T3) only applies to `/dflow:modify-existing` (see `references/modify-existing-flow.md` and AI-AGENT-GUIDE.md § Ceremony Scaling).
@@ -31,6 +33,27 @@ Check existing assets:
31
33
  - Search `dflow/specs/features/` for related features
32
34
  - Check `dflow/specs/domain/glossary.md` and `context-map.md`
33
35
 
36
+ **In-flight overlap scan (cross-branch + other unfinished features)** — this
37
+ branch's `dflow/specs/` does not show everything in flight. Run the in-flight
38
+ scan (classification and dedup rules in `AI-AGENT-GUIDE.md` § Status / Control
39
+ Commands):
40
+
41
+ ```bash
42
+ git fetch # when the network allows; skip gracefully offline
43
+ git branch --all --list '*feature/*' --list '*bugfix/*'
44
+ ```
45
+
46
+ - List other unfinished features already in this branch's `active/` (one
47
+ cursor line each, from their `_index.md` Resume Pointer).
48
+ - Classify every listed branch by the guide's rules — in flight elsewhere /
49
+ closed out awaiting integration / stale (completed here) / unknown — do
50
+ not shortcut the classification. If a branch classified as **in flight
51
+ elsewhere, closed out awaiting integration, or unknown** has an ID / slug
52
+ that semantically overlaps this request, surface it and wait for the
53
+ developer to decide — continue there / integrate it first / treat as
54
+ related / unrelated — **before creating any new directory, spec, or
55
+ branch**. Only stale (completed here) branches are non-blocking.
56
+
34
57
  **→ Transition (step-internal)**: Step 1 complete. Announce "Step 1 complete (intake). Entering Step 2: Identify the Bounded Context." and continue.
35
58
 
36
59
  ## Step 2: Identify the Bounded Context
@@ -52,13 +75,36 @@ If it crosses contexts:
52
75
  - Do we need an Anti-Corruption Layer?"
53
76
  ```
54
77
 
78
+ Once the BC is confirmed, classify and record its **Subdomain Type** as part
79
+ of the same confirmation (not a separate gate):
80
+
81
+ ```
82
+ "Is this capability core (差異化來源), supporting (必要但非差異化),
83
+ or generic (可買 / 可套件 / 簡單 CRUD)? I'll record it in context-map.md."
84
+ ```
85
+
86
+ If the BC already has a Subdomain Type in `context-map.md`, reuse it — don't
87
+ re-ask unless the developer wants to reclassify. Record it in
88
+ `dflow/specs/domain/context-map.md`:
89
+
90
+ - If the **Subdomain Type column is missing** (an older context-map), add the
91
+ column **preserving every existing row** — do not rewrite their content.
92
+ - The greenfield context-map is created at init, so the file normally exists;
93
+ if for any reason it is absent, create it from `templates/context-map.md`.
94
+
95
+ The classification sets the modeling depth used in Step 3 (see
96
+ `references/ddd-modeling-guide.md` § Subdomain-Aware Modeling Depth).
97
+
55
98
  **→ Transition (step-internal)**: Step 2 complete. Announce "Step 2 complete (BC identified). Entering Step 3: Domain Modeling." and continue.
56
99
 
57
100
  ## Step 3: Domain Modeling
58
101
 
59
102
  This is where the Greenfield Clean Architecture workflow diverges
60
103
  significantly from the Brownfield edition.
61
- Read `references/ddd-modeling-guide.md` for detailed patterns.
104
+ Read `references/ddd-modeling-guide.md` for detailed patterns. Apply the
105
+ modeling depth set by this BC's Subdomain Type from Step 2 (see that guide's
106
+ § Subdomain-Aware Modeling Depth): a `generic` context gets a thin model, not
107
+ the full tactical treatment below.
62
108
 
63
109
  Walk through:
64
110
 
@@ -73,6 +119,17 @@ Those things form an Aggregate. Everything else is eventually consistent."
73
119
  - What entities belong inside this Aggregate?
74
120
  - What Value Objects can we extract?
75
121
 
122
+ **Established-model re-read (when the feature reuses an existing
123
+ Aggregate).** Re-read that Aggregate's recorded Design Decisions — its
124
+ `aggregate-design.md` worksheet in the feature directory that introduced it
125
+ (usually under `features/completed/`) — before extending it. If this change
126
+ matches a recorded re-evaluation condition ("revisit when …") or trips a
127
+ model-resistance signal, follow `references/ddd-modeling-guide.md`
128
+ § "Revising an Established Model": record one short passage in the
129
+ phase-spec's Design Decisions / Open Questions — proceed as-is, split, or
130
+ rename, with the reason. Deciding to keep the current model, recorded, is a
131
+ valid outcome; extending silently is not.
132
+
76
133
  ### Domain Events
77
134
  ```
78
135
  "After this happens, what else in the system needs to know?"
@@ -169,17 +226,22 @@ dflow/specs/features/active/{SPEC-ID}-{slug}/
169
226
  - Current BR Snapshot: initialise from the first phase's planned BRs
170
227
  (will be refreshed when the phase-spec finalises)
171
228
  - Lightweight Changes: empty table at start
172
- - Resume Pointer: "phase-1 in progress: drafting phase-spec." / "Next Action: finish phase-spec, then implement Domain layer."
229
+ - Resume Pointer: "phase-1 in progress: drafting phase-spec." / "Next Action: finish phase-spec, then implement Domain layer." / cursor fields: Active Workflow `new-feature`, Current Step `Step 4 — write the spec`, Gates Passed `3→3.5`, Awaiting `none (mid-step)`
173
230
  3. **Create the first phase-spec** at `phase-spec-{YYYY-MM-DD}-{slug}.md`
174
231
  using `templates/phase-spec.md`. The "Delta from prior phases" section
175
232
  is filled with "首 phase,無前置 Delta" (first phase has nothing to
176
233
  delta against).
177
- 4. **If this feature introduces a new Aggregate**, also create an
178
- `aggregate-design.md` from `templates/aggregate-design.md` **inside this
179
- feature directory** as the per-Aggregate design worksheet. It is a working
180
- artifact scoped to the feature; the Aggregate's durable, long-lived catalog
181
- entry still lives in `dflow/specs/domain/{context}/models.md`.
182
- `aggregate-design.md` complements `models.md`, it does not replace it.
234
+ 4. **If this feature introduces a new Aggregate**, whether to create an
235
+ `aggregate-design.md` worksheet from `templates/aggregate-design.md`
236
+ **inside this feature directory** follows the BC's Subdomain Type (Step 2;
237
+ see `references/ddd-modeling-guide.md` § Subdomain-Aware Modeling Depth):
238
+ **core** → create it; **supporting** → create it but keep it lean;
239
+ **generic** → skip by default (a thin wrapper needs no design worksheet)
240
+ unless the developer explicitly opts into deeper modeling and records why.
241
+ When created, it is a working artifact scoped to the feature; the
242
+ Aggregate's durable, long-lived catalog entry still lives in
243
+ `dflow/specs/domain/{context}/models.md` — `aggregate-design.md`
244
+ complements `models.md`, it does not replace it.
183
245
 
184
246
  Key additions compared to Brownfield edition:
185
247
  - **Aggregate State Transitions**: Document how Aggregate state changes
@@ -19,6 +19,8 @@ adds a new phase to an in-progress feature only.
19
19
  - Step 5 → Step 6 (`_index.md` refreshed → start implementation)
20
20
  - Step 6 → Step 7 (implementation done → complete the phase)
21
21
 
22
+ Crossing any step gate above also updates the feature's `_index.md` Resume Pointer cursor (Active Workflow / Current Step / Gates Passed / Awaiting) — fold it into that gate's existing `_index.md` / Resume Pointer edit, no separate ceremony (see the `_index.md` template's Resume Pointer notes).
23
+
22
24
  All other step transitions are **step-internal**: announce "Step N complete,
23
25
  entering Step N+1" and proceed without waiting. See AI-AGENT-GUIDE.md § Workflow
24
26
  Transparency for the full transparency protocol and confirmation signals.
@@ -66,6 +68,11 @@ AI must locate the target feature and load its current state:
66
68
  - Cross-reference the bounded context's `dflow/specs/domain/{context}/rules.md`
67
69
  and `behavior.md` if the new phase is likely to touch system-level
68
70
  state (BC-level current state lives there, not in `_index.md`)
71
+ - Run the in-flight overlap scan (classification and dedup rules in
72
+ `AI-AGENT-GUIDE.md` § Status / Control Commands): list other unfinished
73
+ features in `active/` and any feature / bugfix branches whose work is
74
+ not visible on this branch — if the incoming phase scope overlaps one
75
+ of them, surface it before writing the phase-spec.
69
76
 
70
77
  4. **Branch gate — ensure you are on this feature's branch (before any commit)**
71
78
 
@@ -95,7 +102,14 @@ Walk the developer through what the new phase covers:
95
102
  BRs (ADDED), changed BRs (MODIFIED), removed BRs (REMOVED), renamed
96
103
  (RENAMED). Items not mentioned stay UNCHANGED implicitly.
97
104
  3. **Any Aggregate / Domain concepts introduced or changed?** New
98
- Aggregates, Value Objects, Domain Events, or invariants?
105
+ Aggregates, Value Objects, Domain Events, or invariants? Model new concepts
106
+ at the depth set by the BC's Subdomain Type (see
107
+ `references/ddd-modeling-guide.md` § Subdomain-Aware Modeling Depth) — don't
108
+ bypass the classification just because this is a phase, not a new feature.
109
+ If the phase **extends an existing Aggregate**, apply the established-model
110
+ re-read from `references/ddd-modeling-guide.md` § "Revising an Established
111
+ Model" (match recorded re-evaluation conditions; record proceed / split /
112
+ rename in the phase-spec).
99
113
  4. **Cross-context impact?** Does this phase introduce / change Domain
100
114
  Events that other contexts consume? (If yes, plan for `context-map.md`
101
115
  updates at finish-feature time.)
@@ -116,7 +116,15 @@ If the closeout commit is in this PR (`/dflow:finish-feature` was run):
116
116
 
117
117
  ## Cross-Cutting
118
118
 
119
- - [ ] **Glossary consistency** — new terms documented?
119
+ - [ ] **Glossary consistency** — any new business concept added to `glossary.md`?
120
+ - [ ] **Naming matches the Ubiquitous Language** — for each **domain-facing** type
121
+ or member the diff introduces (skip DTO / test / framework names), is there a
122
+ matching term in `glossary.md`? The `Code Mapping` column maps each term to
123
+ its `{Namespace/Class/Member}` — a domain name in the diff with no glossary
124
+ term, or a term whose Code Mapping is now stale, is the signal.
125
+ - [ ] **No synonym drift** — is the code naming a concept with a different word than
126
+ the glossary (e.g. "reimbursement" in code vs "報銷 / Expense Claim" in the
127
+ glossary)? Align it. (Judgment call, not a string match.)
120
128
  - [ ] **Context boundaries respected** — no reaching into another context's internals
121
129
  - [ ] **Domain Events documented** — events.md updated?
122
130
  - [ ] **Tests cover invariants** — not just happy path