dflow-sdd-ddd 0.9.0 → 0.11.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 (57) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/README.en.md +73 -48
  3. package/README.md +46 -36
  4. package/TEMPLATE-COVERAGE.md +0 -1
  5. package/TEMPLATE-LANGUAGE-GLOSSARY.md +1 -0
  6. package/bin/dflow.js +7 -11
  7. package/docs/evaluating-dflow.en.md +11 -7
  8. package/docs/evaluating-dflow.md +9 -4
  9. package/docs/using-with-claude-code.en.md +40 -23
  10. package/docs/using-with-claude-code.md +34 -23
  11. package/docs/using-with-codex.en.md +125 -42
  12. package/docs/using-with-codex.md +93 -34
  13. package/docs/using-with-github-copilot.en.md +135 -34
  14. package/docs/using-with-github-copilot.md +120 -43
  15. package/docs/why-dflow.en.md +72 -0
  16. package/docs/why-dflow.md +72 -0
  17. package/lib/init.js +867 -214
  18. package/package.json +2 -2
  19. package/templates/brownfield/references/drift-verification.md +41 -10
  20. package/templates/brownfield/references/finish-feature-flow.md +3 -2
  21. package/templates/brownfield/references/git-integration.md +0 -1
  22. package/templates/brownfield/references/init-project-flow.md +31 -17
  23. package/templates/brownfield/references/modify-existing-flow.md +44 -38
  24. package/templates/brownfield/references/new-feature-flow.md +41 -11
  25. package/templates/brownfield/references/new-phase-flow.md +9 -2
  26. package/templates/brownfield/references/pr-review-checklist.md +7 -1
  27. package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +258 -29
  28. package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +5 -8
  29. package/templates/brownfield/scaffolding/_conventions.md +10 -9
  30. package/templates/brownfield/templates/_index.md +1 -1
  31. package/templates/brownfield/templates/context-map.md +12 -4
  32. package/templates/brownfield/templates/lightweight-spec.md +1 -1
  33. package/templates/brownfield/templates/phase-spec.md +1 -1
  34. package/templates/common/references/ddd-modeling-guide.md +643 -0
  35. package/templates/common/skill/SKILL.md +9 -6
  36. package/templates/greenfield/references/drift-verification.md +60 -15
  37. package/templates/greenfield/references/finish-feature-flow.md +3 -2
  38. package/templates/greenfield/references/git-integration.md +0 -1
  39. package/templates/greenfield/references/init-project-flow.md +31 -17
  40. package/templates/greenfield/references/modify-existing-flow.md +5 -7
  41. package/templates/greenfield/references/new-feature-flow.md +49 -19
  42. package/templates/greenfield/references/new-phase-flow.md +5 -2
  43. package/templates/greenfield/references/pr-review-checklist.md +9 -1
  44. package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +221 -29
  45. package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +10 -15
  46. package/templates/greenfield/scaffolding/Git-principles-trunk.md +1 -1
  47. package/templates/greenfield/scaffolding/_conventions.md +9 -8
  48. package/templates/greenfield/templates/_index.md +1 -1
  49. package/templates/greenfield/templates/aggregate-design.md +6 -0
  50. package/templates/greenfield/templates/context-map.md +13 -4
  51. package/templates/greenfield/templates/events.md +4 -1
  52. package/templates/greenfield/templates/lightweight-spec.md +1 -1
  53. package/templates/greenfield/templates/phase-spec.md +1 -1
  54. package/docs/migrating-to-dflow-v1.md +0 -230
  55. package/templates/brownfield/templates/CLAUDE.md +0 -165
  56. package/templates/greenfield/references/ddd-modeling-guide.md +0 -351
  57. package/templates/greenfield/templates/CLAUDE.md +0 -172
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dflow-sdd-ddd",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Spec-first SDD/DDD workflow kit for AI-assisted development",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "homepage": "https://github.com/weilung/dflow-sdd-ddd#readme",
41
41
  "scripts": {
42
- "test": "node test/smoke.mjs"
42
+ "test": "node test/smoke.mjs && node test/registry-parity.mjs && node test/agent-inject.mjs && node test/bundle-guards.mjs"
43
43
  },
44
44
  "license": "AGPL-3.0-or-later",
45
45
  "publishConfig": {
@@ -4,18 +4,23 @@ 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 an **optional, non-blocking domain-doc hygiene check** on the model catalog (`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 an **optional domain-doc hygiene** warning (non-blocking — it never fails the
21
+ command, only surfaces a "confirm this is intentional" signal): the `models.md`
22
+ Code-Mapping hygiene check (see Model Catalog Notes).
23
+
19
24
  ### This command does NOT do (semantic layer — explicitly excluded)
20
25
 
21
26
  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:
@@ -39,8 +44,8 @@ Reasons:
39
44
  Step 3
40
45
  - BC-level current state is already maintained by `rules.md` /
41
46
  `behavior.md`, written by the same `/dflow:finish-feature` Step 3
42
- - `/dflow:verify` keeps a small, mechanical scope: just the
43
- `rules.md` ↔ `behavior.md` correspondence inside one BC
47
+ - `/dflow:verify` keeps a small core: the `rules.md` ↔ `behavior.md`
48
+ correspondence inside one BC, plus the optional models.md hygiene check below
44
49
  - Cross-feature / cross-phase aggregation would mix `/dflow:verify`'s
45
50
  job with `/dflow:finish-feature`'s job and produce false positives
46
51
  during in-progress features
@@ -84,6 +89,9 @@ For each Bounded Context:
84
89
  - behavior.md → templates/behavior.md
85
90
  Or run the completion flow to populate it from existing completed specs
86
91
  ```
92
+ - Also locate the **optional** hygiene input for this BC — `models.md`. It feeds
93
+ the non-blocking Model Catalog Notes hygiene check. If it is absent, **skip the
94
+ check silently** — do not report or stop; it is bonus, not part of the core.
87
95
 
88
96
  ### Step 2: Extract BR-IDs from rules.md
89
97
 
@@ -153,6 +161,31 @@ Issues:
153
161
  remove the stale scenario reference from behavior.md
154
162
  ```
155
163
 
164
+ The optional `models.md` Code-Mapping hygiene check (below) appends its
165
+ non-blocking `ℹ` signals to this same report and never changes the core
166
+ pass / fail count.
167
+
168
+ ## Model Catalog Notes
169
+
170
+ A non-blocking **informational** hygiene check on `models.md`:
171
+
172
+ - For each row whose **primary name cell** holds a real value, if the
173
+ `Code Mapping` column is empty or still a `{Namespace.Class}` placeholder,
174
+ surface it:
175
+ ```
176
+ ℹ models.md: Entity "ExpenseReport" has no Code Mapping yet — link it if the
177
+ code is extracted; if extraction is deferred, this is expected
178
+ ```
179
+ - **Skip untouched seed rows by the name cell only**: a row whose name is still a
180
+ `{...}` placeholder is seed scaffolding. But a row with a **real name** and a
181
+ placeholder / empty Code Mapping is exactly the one to surface — do not skip it
182
+ just because that one cell still holds `{...}`.
183
+ - This is **informational, not drift** — Brownfield records a concept in `models.md`
184
+ during discovery, often *before* the code is extracted, so an empty Code Mapping
185
+ is a normal state, not drift. An explicit "planned / deferred" note on the row, or
186
+ a matching `## Code Mapping Notes` entry, counts as accounted for; do not surface
187
+ it.
188
+
156
189
  ## When to Run
157
190
 
158
191
  Recommended trigger points (not enforced — developer's judgment):
@@ -166,12 +199,10 @@ Recommended trigger points (not enforced — developer's judgment):
166
199
  ## Path Assumptions
167
200
 
168
201
  This command operates entirely within `dflow/specs/domain/{context}/` files
169
- (`rules.md` and `behavior.md`). It does **not** read from
202
+ (`rules.md` and `behavior.md` for the core check; `models.md` for the optional
203
+ hygiene warning). It does **not** read from
170
204
  `dflow/specs/features/active/{SPEC-ID}-{slug}/` directories — the feature
171
- directory layout is not part of verify's input. The only effect of feature directory layout on this command is
172
- ensuring `last-updated` dates in `behavior.md` are bumped at
173
- `/dflow:finish-feature` time (so verify's mechanical drift guard stays
174
- useful).
205
+ directory layout is not part of verify's input.
175
206
 
176
207
  ## Interaction with Other Commands
177
208
 
@@ -34,7 +34,7 @@ state, archives the feature directory, and emits a Git-strategy-neutral
34
34
  - Step 5 → Step 6 (Integration Summary emitted → optional follow-up reverse-link)
35
35
 
36
36
  All other step transitions are **step-internal**: announce "Step N complete,
37
- entering Step N+1" and proceed without waiting. See SKILL.md § Workflow
37
+ entering Step N+1" and proceed without waiting. See AI-AGENT-GUIDE.md § Workflow
38
38
  Transparency for the full transparency protocol and confirmation signals.
39
39
 
40
40
  ## Step 1: Validate Phase Specs and `_index.md`
@@ -124,6 +124,8 @@ For each row in Current BR Snapshot where Status = `active`:
124
124
  `rules.md` (REMOVED rule)
125
125
  - For any RENAMED BR-ID → rename the BR-ID in `rules.md` and update
126
126
  `glossary.md` if the term itself changed
127
+ - For every BR-ID added, modified, or renamed above, set its `Last updated`
128
+ date in `rules.md`'s Rule Index to today
127
129
 
128
130
  For `behavior.md`:
129
131
 
@@ -132,7 +134,6 @@ For `behavior.md`:
132
134
  matching the BR-ID
133
135
  - For REMOVED BR-IDs, delete the corresponding scenario section from
134
136
  `behavior.md`
135
- - Update the BR-ID anchor's `last-updated` date in `behavior.md` to today
136
137
 
137
138
  This is the **mechanical input that `/dflow:verify` later uses** for the
138
139
  rules.md ↔ behavior.md drift check (see `references/drift-verification.md`).
@@ -181,7 +181,6 @@ diff. That breaks:
181
181
  - `git blame` on lines that crossed the rename boundary
182
182
  - PR diff quality (reviewers see two unrelated big-blob changes
183
183
  instead of one rename + small content diff)
184
- - `/dflow:verify` and other tools that walk feature history
185
184
 
186
185
  This is a known weakness of OpenSpec's directory-rename pattern; Dflow
187
186
  deliberately avoids it by mandating `git mv`.
@@ -49,8 +49,8 @@ Report findings plainly:
49
49
  > - `dflow/specs/`: not yet present → greenfield Dflow setup
50
50
  > - `specs/`: present → legacy / other-tool directory; Dflow V1 will not
51
51
  > migrate or modify it
52
- > - `CLAUDE.md`: present → will not overwrite; I'll offer a snippet
53
- > to merge into it"
52
+ > - `CLAUDE.md`: present → I'll append a marked Dflow block (shown in
53
+ > the preview); a merge snippet only if there's a marker conflict"
54
54
 
55
55
  Or:
56
56
 
@@ -162,9 +162,10 @@ Wait for answers.
162
162
  >
163
163
  > If you select any agent, Dflow will create
164
164
  > `dflow/specs/shared/AI-AGENT-GUIDE.md` as the canonical guide. Root-level
165
- > tool files stay thin and point back to that guide. Existing tool files are
166
- > never overwritten; Dflow writes merge snippets under `dflow/specs/shared/`
167
- > instead."
165
+ > tool files stay thin and point back to that guide. Existing user content is
166
+ > never overwritten; Dflow appends a marked Dflow block (shown in the preview)
167
+ > and refreshes it in place on re-run. Merge snippets under
168
+ > `dflow/specs/shared/` are used only if Dflow markers conflict."
168
169
 
169
170
  **→ Transition (step-internal)**: Step 2 complete. Announce
170
171
  > "Step 2 complete (project information captured). Entering Step 3:
@@ -228,16 +229,17 @@ vendored workflow bundle). Compute the destination path:
228
229
  | `scaffolding/Git-principles-trunk.md` | `dflow/specs/shared/Git-principles-trunk.md` |
229
230
  | `scaffolding/AI-AGENT-GUIDE.md` | `dflow/specs/shared/AI-AGENT-GUIDE.md` when at least one AI agent is selected |
230
231
  | generated tool shim | `AGENTS.md`, `CLAUDE.md`, or `.github/copilot-instructions.md` when selected and missing |
231
- | generated merge snippet | `dflow/specs/shared/*-snippet.md` when the selected tool file already exists |
232
+ | marked Dflow block | appended to a selected existing tool file unless it already points to `AI-AGENT-GUIDE.md`; refreshed in place on re-run |
233
+ | fallback merge snippet | `dflow/specs/shared/*-snippet.md` only when the selected tool file has conflicting or malformed Dflow markers |
232
234
 
233
235
  ### 3.3 Present the preview
234
236
 
235
- Present the complete file list as two tables, separating create vs
237
+ Present the complete file list as two tables, separating create / update vs
236
238
  skip, and wait for developer confirmation:
237
239
 
238
240
  > "Based on Step 1 inventory + Step 2 answers, here is what I'll do:
239
241
  >
240
- > **Will create ({N} files):**
242
+ > **Will create / update ({N} files):**
241
243
  >
242
244
  > | Path | Source |
243
245
  > |---|---|
@@ -250,7 +252,7 @@ skip, and wait for developer confirmation:
250
252
  > | `dflow/specs/shared/_overview.md` | optional (you picked it) |
251
253
  > | `dflow/specs/shared/Git-principles-trunk.md` | mandatory (selected Git policy) |
252
254
  > | `dflow/specs/shared/AI-AGENT-GUIDE.md` | selected AI agent guide |
253
- > | `CLAUDE.md` | selected tool shim because repo has no CLAUDE.md |
255
+ > | `CLAUDE.md` | marked Dflow block appended to existing CLAUDE.md (shown in preview) |
254
256
  >
255
257
  > **Will skip ({M} files — already present):**
256
258
  >
@@ -325,11 +327,24 @@ guide.
325
327
  For each selected tool-specific file (`AGENTS.md`, `CLAUDE.md`,
326
328
  `.github/copilot-instructions.md`):
327
329
 
330
+ (checked in this order — the first matching rule wins):
331
+
328
332
  - if the target file does not exist, create a small shim at the target
329
333
  path that points to `dflow/specs/shared/AI-AGENT-GUIDE.md`
330
- - if the target file already exists, do not overwrite it; write a merge
331
- snippet under `dflow/specs/shared/` and report that the developer
332
- should merge it manually
334
+ - if the target file contains conflicting or malformed Dflow markers, do not
335
+ edit it; write a fallback merge snippet under `dflow/specs/shared/` and
336
+ report that the developer should merge it manually
337
+ - if the target file already contains a single well-formed Dflow marked block,
338
+ replace that block in place (idempotent refresh) and keep the rest of the
339
+ file unchanged
340
+ - if the target file is an existing whole-file Dflow-generated shim, refresh it
341
+ in place
342
+ - if the target file already points to the guide through the developer's own
343
+ pointer (and has no Dflow marked block), leave it untouched
344
+ - otherwise preserve the existing content and append a marked Dflow block at
345
+ the end of the file, keeping the file's dominant line ending; show that block
346
+ in the preview, and refresh that same block on re-run. If the developer later
347
+ deletes the block, a later `init` / `configure-agents` run appends it again
333
348
 
334
349
  ### 4.4 Directory-only entries
335
350
 
@@ -354,7 +369,7 @@ Summarise what actually happened and point at the next command.
354
369
  ```
355
370
  Init complete. Summary:
356
371
 
357
- Created ({N} files):
372
+ Created / Updated ({N} files):
358
373
  ✓ dflow/specs/features/active/.gitkeep
359
374
  ✓ dflow/specs/features/completed/.gitkeep
360
375
  ✓ dflow/specs/features/backlog/.gitkeep
@@ -363,7 +378,7 @@ Init complete. Summary:
363
378
  ✓ dflow/specs/migration/tech-debt.md
364
379
  ✓ dflow/specs/shared/_overview.md
365
380
  ✓ dflow/specs/shared/Git-principles-trunk.md
366
- ✓ CLAUDE.md (seeded from scaffolding snippet)
381
+ ✓ CLAUDE.md (marked Dflow block appended)
367
382
 
368
383
  Skipped ({M} files already present):
369
384
  - (none this run)
@@ -412,9 +427,8 @@ Remind the developer to review files that have `{placeholder}` tokens
412
427
  still in them:
413
428
 
414
429
  > "A few files still have `{placeholder}` tokens that need your input:
415
- > - `dflow/specs/shared/_overview.md`: `{業務領域}`, `{團隊}`,
416
- > `{使用者規模}`
417
- > - `CLAUDE.md`: `{業務領域}`
430
+ > - `dflow/specs/shared/_overview.md`: the Business Domain and Technical
431
+ > Architecture fields (e.g. primary domain, stakeholders, user scale, stack)
418
432
  >
419
433
  > These are fine to leave for now; fill them in during your next
420
434
  > review pass."
@@ -1,15 +1,15 @@
1
1
  # Modify Existing Feature Workflow
2
2
 
3
- Step-by-step guide for when a developer triggers `/dflow:modify-existing` or `/dflow:bug-fix` (or natural language implying a modification task — see SKILL.md § Workflow Transparency for the auto-trigger safety net).
3
+ Step-by-step guide for when a developer triggers `/dflow:modify-existing` or `/dflow:bug-fix` (or natural language implying a modification task — see AI-AGENT-GUIDE.md § Workflow Transparency for the auto-trigger safety net).
4
4
 
5
5
  **Step Gates** in this flow (stop-and-confirm before proceeding):
6
6
  - Step 2 → Step 3 (baseline captured → analyze business logic embedded in delivery/entrypoint code: presentation/UI layer, controllers, handlers, jobs, message consumers, data pipelines, or stored procedures)
7
7
  - Step 4 → Step 5 (extraction decision → start implementation)
8
8
  - Step 5 → Step 6 (implementation done → update artifacts)
9
9
 
10
- All other step transitions are **step-internal**: announce "Step N complete, entering Step N+1" and proceed without waiting. See SKILL.md § Workflow Transparency for the full transparency protocol and confirmation signals.
10
+ 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.
11
11
 
12
- **Ceremony adjustment when triggered by `/dflow:bug-fix`**: treat as lightweight — use the Lightweight Spec Template at the end of this file instead of the full spec, and Step 4 (extraction) may default to "defer and record in tech-debt.md" unless the bug itself is in extractable logic. T2 still generates a concise `Implementation Tasks` checklist (see Step 4).
12
+ **Ceremony adjustment when triggered by `/dflow:bug-fix`**: treat as lightweight — use the Lightweight Spec Template (see `templates/lightweight-spec.md`) instead of the full spec, and Step 4 (extraction) may default to "defer and record in tech-debt.md" unless the bug itself is in extractable logic. T2 still generates a concise `Implementation Tasks` checklist (see Step 4).
13
13
 
14
14
  ## Mindset
15
15
 
@@ -31,7 +31,7 @@ This step has two parallel concerns:
31
31
 
32
32
  **Part A — Determine the Ceremony Tier (T1 / T2 / T3)**
33
33
 
34
- Dflow runs three ceremony tiers (full table in SKILL.md § Ceremony Scaling).
34
+ Dflow runs three ceremony tiers (full table in AI-AGENT-GUIDE.md § Ceremony Scaling).
35
35
  For a modification, AI judges which tier fits before deciding what to
36
36
  produce:
37
37
 
@@ -141,7 +141,7 @@ add a row:
141
141
  | {新 SPEC-ID} | {新 slug} | {today} | in-progress |
142
142
  ```
143
143
 
144
- This update is **part of the same change set** (the developer commits
144
+ This update is **part of the same change set** (offer to commit
145
145
  both at once; commit message should mention "Add follow-up reference to
146
146
  `{新 SPEC-ID}`"). The reverse link is a derived index — the new
147
147
  feature's `follow-up-of` field is the authoritative source.
@@ -152,8 +152,6 @@ phase's content).
152
152
 
153
153
  ## Step 2: Document Current Behavior (if no spec exists)
154
154
 
155
- ## Step 2: Document Current Behavior (if no spec exists)
156
-
157
155
  This is critical. Before changing anything, capture what currently exists:
158
156
 
159
157
  ```
@@ -284,8 +282,46 @@ Decision framework:
284
282
  - **Extract now** if: the logic is being significantly modified anyway
285
283
  - **Extract now** if: the logic is duplicated elsewhere and we need the single source of truth
286
284
  - **Defer extraction** if: the change is a one-line fix and the surrounding code is too tangled
285
+ - **Consider not extracting at all** if: the context is `generic` (per the
286
+ context-map Subdomain Type) — a commodity capability's endgame is wholesale
287
+ replacement with an off-the-shelf package / service, so extracting its rules
288
+ one by one is wasted effort; record the replacement intent as the tech-debt
289
+ entry instead
287
290
  - **Always record** the extraction opportunity in tech-debt.md even if deferring
288
291
 
292
+ If the target context has **no Subdomain Type** (not in `context-map.md`, or
293
+ the column is absent), ask the developer once to classify it. If they'd rather
294
+ not decide now, record it as an Open Question in the spec and run the
295
+ extraction decision on the framework above — do **not** assume `generic`.
296
+
297
+ **Aggregate emergence check.** Before extracting yet another rule onto an
298
+ existing concept, look at what has already accumulated on it (in `models.md` /
299
+ `rules.md`). The signal that it has stopped being a loose entity and is
300
+ becoming an **Aggregate Root with a consistency boundary**: **2+ non-trivial
301
+ state-transition rules on the same lifecycle identity, or any invariant that
302
+ must check / update multiple fields or child records atomically.** (A
303
+ *consistency boundary* means state that must hold or change **together,
304
+ atomically** — not mere relatedness: same screen, related nouns, or local
305
+ single-field input validation do **not** count.) When you see it, continuing
306
+ to extract rules one by one as T2 will leave the boundary undrawn — surface it
307
+ and **suggest escalating to T1** (`/dflow:new-phase` inside an active feature,
308
+ else `/dflow:new-feature`) to model the Aggregate deliberately: its invariants,
309
+ what must change atomically, what it protects. For *how* to model it —
310
+ invariant classification, set-based / uniqueness rules, aggregate sizing — read
311
+ `references/ddd-modeling-guide.md` (its **Edition note** maps each recording
312
+ surface to brownfield's `models.md` / `rules.md`). In `models.md`, **mark the
313
+ existing Entity row as the Aggregate Root and note the protected invariants /
314
+ atomic-change scope in its Responsibility / Notes** — brownfield `models.md`
315
+ has no separate Aggregates section, do not invent one; update the Repository
316
+ row if one exists. If the developer defers, **record the emergence observation
317
+ in `tech-debt.md`** so the boundary decision is not silently lost.
318
+
319
+ If the context is **`generic`** (Subdomain Type), emergence is usually a
320
+ *replacement / adapter-boundary* debt signal, not a cue for deep T1 modeling —
321
+ record the replacement intent (consistent with the generic extraction fallback
322
+ above) rather than escalating, unless the developer explicitly chooses to
323
+ model it.
324
+
289
325
  ### Generate Implementation Tasks List
290
326
 
291
327
  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 / DELIVERY / DATA / TEST).
@@ -360,7 +396,7 @@ Items marked *(post-6.3)* are re-verified after the documentation merge in 6.3 l
360
396
  - [ ] Extracted logic (if Step 4 decided "extract now") lives under `src/Domain/` as framework-pure code
361
397
  - [ ] `Implementation Tasks` section (`phase-spec.md` or `lightweight-spec.md`): all tasks checked, or unchecked items explicitly labelled as follow-up
362
398
  - [ ] *(post-6.3)* `dflow/specs/domain/{context}/behavior.md` has a section anchor for every `BR-*` in ADDED / MODIFIED entries; REMOVED entries' anchors have been deleted (mechanical input for `/dflow:verify`)
363
- - [ ] *(post-6.3)* `dflow/specs/domain/{context}/behavior.md` `last-updated` is later than this spec's `created` date (mechanical drift guard)
399
+ - [ ] *(post-6.3)* every ADDED / MODIFIED / RENAMED BR's `Last updated` in `dflow/specs/domain/{context}/rules.md` is later than this spec's `created` date (mechanical drift guard)
364
400
 
365
401
  If any item fails, report the gap and pause — don't proceed to 6.2.
366
402
 
@@ -416,33 +452,3 @@ new follow-up directory; that happens at `/dflow:finish-feature` time.
416
452
 
417
453
  Only announce "change complete" after the appropriate archival step
418
454
  above (or the Step 6.3 docs sweep) is done.
419
-
420
- ## Lightweight Spec Template (for bug fixes)
421
-
422
- For small bug fixes, a lightweight spec is enough:
423
-
424
- ```markdown
425
- ---
426
- id: BUG-042
427
- title: Fix rounding inconsistency in expense calculation
428
- status: in-progress
429
- bounded-context: Expense
430
- created: 2025-02-12
431
- ---
432
-
433
- ## Problem
434
- Entrypoint A uses Math.Round(amount, 0, MidpointRounding.AwayFromZero) (四捨五入)
435
- Entrypoint B uses Math.Floor(amount) (無條件捨去)
436
- They should both use the same rounding rule.
437
-
438
- ## Expected Behavior
439
- Given an expense amount of 123.5 TWD
440
- When displayed or returned by any entrypoint
441
- Then it should show 124 (四捨五入 per accounting standard)
442
-
443
- ## Root Cause
444
- Duplicated calculation logic — recorded in tech-debt.md
445
-
446
- ## Fix
447
- Extract rounding to Money.Round() in Domain layer, both pages call it.
448
- ```
@@ -1,6 +1,6 @@
1
1
  # New Feature Workflow
2
2
 
3
- Step-by-step guide for when a developer triggers `/dflow:new-feature` (or natural language implying a new-feature task — see SKILL.md § Workflow Transparency for the auto-trigger safety net behavior).
3
+ Step-by-step guide for when a developer triggers `/dflow:new-feature` (or natural language implying a new-feature task — see AI-AGENT-GUIDE.md § Workflow Transparency for the auto-trigger safety net behavior).
4
4
 
5
5
  **Step Gates** in this flow (stop-and-confirm before proceeding):
6
6
  - Step 3 → Step 3.5 (domain concepts captured → confirm slug + directory + branch names)
@@ -8,9 +8,9 @@ Step-by-step guide for when a developer triggers `/dflow:new-feature` (or natura
8
8
  - Step 6 → Step 7 (branch ready → start implementation)
9
9
  - Step 7 → Step 8 (implementation done → completion)
10
10
 
11
- All other step transitions are **step-internal**: announce "Step N complete, entering Step N+1" and proceed without waiting. See SKILL.md § Workflow Transparency for the full transparency protocol and confirmation signals.
11
+ 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.
12
12
 
13
- **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 SKILL.md § Ceremony Scaling).
13
+ **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).
14
14
 
15
15
  ## Step 1: Intake — Understand the Request
16
16
 
@@ -50,6 +50,23 @@ If no matching context exists:
50
50
  2. Create `dflow/specs/domain/{new-context}/context.md` using the context-definition template
51
51
  3. Get developer confirmation before proceeding
52
52
 
53
+ Once the BC is confirmed, classify and record its **Subdomain Type** as part
54
+ of the same confirmation (not a separate gate):
55
+
56
+ ```
57
+ "Is this capability core (差異化來源), supporting (必要但非差異化),
58
+ or generic (可買 / 可套件 / 簡單 CRUD)? I'll record it in context-map.md."
59
+ ```
60
+
61
+ If the BC already has a Subdomain Type, reuse it — don't re-ask unless the
62
+ developer wants to reclassify. Record it in
63
+ `dflow/specs/domain/context-map.md`:
64
+
65
+ - If the file **does not exist** (the Brownfield track does not mandate it —
66
+ contexts emerge organically), create it from `templates/context-map.md`.
67
+ - If it exists but the **Subdomain Type column is missing**, add the column
68
+ **preserving every existing row** — do not rewrite their content.
69
+
53
70
  **→ Transition (step-internal)**: Step 2 complete. Announce "Step 2 complete (BC identified). Entering Step 3: Domain Concept Discovery." and continue.
54
71
 
55
72
  ## Step 3: Domain Concept Discovery
@@ -62,6 +79,17 @@ Walk through these questions:
62
79
  - **What are the states/statuses?** → State machines to model
63
80
  - **What external data is needed?** → Interfaces to define
64
81
 
82
+ If one concept gathers rules / invariants that must hold together — **a state
83
+ machine over its lifecycle, or invariants spanning several of its fields /
84
+ child records** — treat it as a candidate **Aggregate Root** (a consistency
85
+ boundary = atomic, not mere relatedness), not just an Entity. Note its
86
+ invariants and what must change atomically against its `models.md` Entity row,
87
+ and confirm the boundary with the developer. (A state machine is one common
88
+ signal, not a prerequisite.) For the tactical patterns — invariant
89
+ classification, set-based / uniqueness rules, value objects, aggregate sizing —
90
+ read `references/ddd-modeling-guide.md` (its **Edition note** maps recording
91
+ surfaces to brownfield's `models.md` / `rules.md`).
92
+
65
93
  For each new concept:
66
94
  1. Check glossary — add if missing
67
95
  2. Check if it already exists in models.md — extend if needed
@@ -188,7 +216,7 @@ Specifically ask about:
188
216
  Announce to developer:
189
217
  > "Spec is drafted — behavior scenarios, business rules, and edge cases are captured. Ready to plan the implementation (Domain layer design, interfaces, thin delivery/entrypoint code — presentation/UI layer, controllers, handlers, jobs, message consumers, data pipelines, or stored procedures)? `/dflow:next` or reply 'OK' to continue, or tell me if the spec needs another iteration first."
190
218
 
191
- Wait for confirmation (`/dflow:next`, verbal OK, or implicit — see SKILL.md § Confirmation Signals) before entering Step 5.
219
+ Wait for confirmation (`/dflow:next`, verbal OK, or implicit — see AI-AGENT-GUIDE.md § Confirmation Signals) before entering Step 5.
192
220
 
193
221
  ## Step 5: Plan the Implementation
194
222
 
@@ -325,7 +353,7 @@ AI reports `✓` / `✗` for every item before touching docs. Items marked *(pos
325
353
  - [ ] Every `EC-*` edge case is handled
326
354
  - [ ] Domain layer has **no** delivery-framework references (grep `src/Domain/`)
327
355
  - [ ] *(post-8.3)* `dflow/specs/domain/{context}/behavior.md` contains a section anchor for every `BR-*` introduced by this spec (mechanical input for `/dflow:verify`)
328
- - [ ] *(post-8.3)* `dflow/specs/domain/{context}/behavior.md` `last-updated` is later than this spec's `created` date (mechanical drift guard)
356
+ - [ ] *(post-8.3)* `dflow/specs/domain/{context}/rules.md` `last-updated` is later than this spec's `created` date (mechanical drift guard)
329
357
 
330
358
  If any item fails, report the gap and pause — don't proceed to 8.2.
331
359
 
@@ -354,12 +382,14 @@ Ask these one-by-one; do not dump all five at once.
354
382
 
355
383
  ### 8.4 Archival
356
384
 
357
- For a single-phase feature, this is the closeout point. For a multi-phase
358
- feature, the developer typically reaches this point at the end of the
359
- final phase — at which time `/dflow:finish-feature` is the recommended
360
- trigger (it bundles steps 8.1 / 8.2 verification, BC sync, and archival
361
- into one explicit ceremony). Either path is acceptable; pick the one
362
- that matches the developer's habit.
385
+ For a single-phase feature, this is the closeout point. If the feature has
386
+ later phases still ahead, this phase is complete but the feature is not —
387
+ don't archive yet; run `/dflow:new-phase` to start the next phase, not
388
+ `/dflow:finish-feature` yet. For a multi-phase feature, the developer
389
+ typically reaches this point at the end of the final phase — at which time
390
+ `/dflow:finish-feature` is the recommended trigger (it bundles steps 8.1 /
391
+ 8.2 verification, BC sync, and archival into one explicit ceremony). Either
392
+ path is acceptable; pick the one that matches the developer's habit.
363
393
 
364
394
  - [ ] `_index.md` `status` field changed to `completed`
365
395
  - [ ] All `phase-spec-*.md` files in the feature directory have `status:
@@ -20,7 +20,7 @@ adds a new phase to an in-progress feature only.
20
20
  - Step 6 → Step 7 (implementation done → complete the phase)
21
21
 
22
22
  All other step transitions are **step-internal**: announce "Step N complete,
23
- entering Step N+1" and proceed without waiting. See SKILL.md § Workflow
23
+ entering Step N+1" and proceed without waiting. See AI-AGENT-GUIDE.md § Workflow
24
24
  Transparency for the full transparency protocol and confirmation signals.
25
25
 
26
26
  ## Step 1: Read Active Feature Context
@@ -92,7 +92,14 @@ Walk the developer through what the new phase covers:
92
92
  BRs (ADDED), changed BRs (MODIFIED), removed BRs (REMOVED), renamed
93
93
  (RENAMED). Items not mentioned stay UNCHANGED implicitly.
94
94
  3. **Any Domain concepts introduced or changed?** New Entities / Value
95
- Objects / Services touching `src/Domain/{context}/`?
95
+ Objects / Services touching `src/Domain/{context}/`? If this phase is an
96
+ **Aggregate-emergence escalation** (handed off from `/dflow:modify-existing`),
97
+ record the candidate Aggregate Root, the invariants it protects, and what
98
+ must change atomically — marking the Aggregate Root on its `models.md`
99
+ Entity row (no separate Aggregates section). For how to model it (invariant
100
+ classification, set-based / uniqueness rules, aggregate sizing), read
101
+ `references/ddd-modeling-guide.md` (its **Edition note** maps recording
102
+ surfaces to brownfield's `models.md` / `rules.md`).
96
103
  4. **Data structure impact?** New tables, columns, indices?
97
104
  5. **Why now?** Priority — informs sequencing relative to other phases.
98
105
 
@@ -139,7 +139,13 @@ for later?"
139
139
  ## Glossary Consistency
140
140
 
141
141
  - [ ] **New terms documented** — Any new business concept added to glossary.md?
142
- - [ ] **Consistent naming** — Do class/method/variable names match glossary terms?
142
+ - [ ] **Naming matches the Ubiquitous Language** — for each **domain-facing**
143
+ class / method / variable the diff introduces (skip DTO / test / framework
144
+ names), is there a matching term in `glossary.md`? The `Code Mapping` column
145
+ maps each term to its `{Namespace/Class/Member}` — a domain name with no
146
+ glossary term, or a term whose Code Mapping is now stale, is the signal.
147
+ - [ ] **No synonym drift** — is the code naming a concept with a different word
148
+ than the glossary? Align it. (Judgment call, not a string match.)
143
149
  - [ ] **No ambiguous terms** — Are domain-specific terms used precisely?
144
150
 
145
151
  Example check: