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,6 +17,8 @@ trunk-based, GitHub Flow), use `Git-principles-trunk.md` instead.
17
17
 
18
18
  ---
19
19
 
20
+ <!-- dflow-generated: git-principles-canonical START -->
21
+
20
22
  ## 1. Branch Structure
21
23
 
22
24
  | Branch | Naming | Cut from | Merges to |
@@ -24,6 +26,7 @@ trunk-based, GitHub Flow), use `Git-principles-trunk.md` instead.
24
26
  | `main` / `master` | `main` | — | release / hotfix only |
25
27
  | `develop` | `develop` | — | integration branch for features |
26
28
  | feature | `feature/{SPEC-ID}-{slug}` | `develop` | `develop` |
29
+ | bugfix | `bugfix/{BUG-ID}-{slug}` | `develop` | `develop` |
27
30
  | release | `release/{version}` | `develop` | `main` + `develop` |
28
31
  | hotfix | `hotfix/{version}-hotfix{n}` | `main` | `main` + `develop` |
29
32
 
@@ -31,6 +34,17 @@ The `feature/{SPEC-ID}-{slug}` pattern is a **Dflow requirement** (not
31
34
  a Git Flow requirement). It ties each feature branch to its
32
35
  corresponding `dflow/specs/features/active/{SPEC-ID}-{slug}/` directory.
33
36
 
37
+ A **`bugfix/{BUG-ID}-{slug}`** branch is the same shape as a feature branch and
38
+ follows the same topology — cut from the same base, pushed the same way,
39
+ integrated the same way, and **closed out the same way**. It is used when a
40
+ defect owns its own host rather than being picked up by a feature already in
41
+ flight. Its host is a **minimal (zero-phase) host**, so it carries no
42
+ phase-spec: the SPEC-ID lives in the directory name while the branch name
43
+ carries the BUG-NUMBER, and the host `_index.md` `branch:` field is
44
+ authoritative for both. Closeout is not optional because the branch prefix
45
+ differs — `/dflow:finish-feature` runs and the directory is archived to
46
+ `completed/` before the branch merges, exactly as for `feature/`.
47
+
34
48
  ### Feature Branch Workflow
35
49
 
36
50
  ```bash
@@ -108,10 +122,18 @@ git branch -d hotfix/{version}-hotfix{n}
108
122
  ```
109
123
 
110
124
  **Hotfix spec requirement (team convention)**: Hotfixes often skip the
111
- upfront SDD cycle for speed. This project commits to writing a
112
- lightweight spec within **24 hours** after the hotfix lands, documenting
113
- root cause + fix + (if applicable) a tech-debt entry in
114
- `dflow/specs/architecture/tech-debt.md` if the bug reveals a systemic issue.
125
+ upfront SDD cycle for speed. This project commits to documenting the fix
126
+ within **24 hours** after it lands. Run `/dflow:modify-existing` in
127
+ **post-hoc mode** (`references/modify-existing-flow.md` Step 1.8): it opens a
128
+ minimal host of its own for the fix, records the implementation checkpoint as
129
+ `reconciled ({merged-hotfix-hash})`, and reconciles rather than re-running work
130
+ that is already on the mainline.
131
+ What gets written is whatever the cascade's tier calls for — a **T2** lands a
132
+ lightweight spec (root cause + fix + a `dflow/specs/architecture/tech-debt.md` entry
133
+ if the bug reveals a systemic issue); a **T3** lands one `_index.md` Lightweight
134
+ Changes row and no spec file. Step 1.8 admits **T2 / T3 only**: a **T1**
135
+ post-hoc keeps the normal phase-bearing route and documents the merged work
136
+ there.
115
137
  This is a **human-to-human commitment** — Dflow / AI cannot track the
116
138
  24-hour clock; the team enforces it in retros.
117
139
 
@@ -156,7 +178,10 @@ Before making key Git operations:
156
178
  justification in the spec's notes section)
157
179
  - [ ] `_index.md` status reflects the current work (Phase Specs row
158
180
  updated, `Resume Pointer` refreshed if the commit reaches a meaningful
159
- checkpoint)
181
+ checkpoint). A **minimal (zero-phase) host** has no Phase Specs row to
182
+ update — its record is the Lightweight Changes row, and that row must
183
+ already be written **before** this commit, not after it. Refresh the
184
+ Resume Pointer as usual.
160
185
  - [ ] Clean Architecture layer rules hold (Domain has no external
161
186
  package deps, no business logic leaked into handlers /
162
187
  controllers)
@@ -176,6 +201,21 @@ Before making key Git operations:
176
201
  - [ ] No ORM / serialization attributes on Domain entities
177
202
  - [ ] Domain unit tests pass (invariants + value object equality)
178
203
 
204
+ > **Minimal (zero-phase) host.** The items about this host's own record —
205
+ > `/dflow:finish-feature` having run, `_index.md` status `completed`, and the
206
+ > archival move — apply **unchanged**: they are what stops a host merging with
207
+ > its record still open. Every item naming a **Domain or bounded-context
208
+ > artifact** applies only to what this change **actually touched**: a **no-BC**
209
+ > host has no context to sync or document, and a **T3** does no Domain work at
210
+ > all, so for those they read N/A. **Bounded-context-scoped only** —
211
+ > `glossary.md` and the tech-debt file belong to no bounded context, stay in a
212
+ > no-BC host's sweep, and are **not** N/A for it. **Code invariants are not
213
+ > artifacts** — the items here that state a rule about the **source** rather
214
+ > than name a document to update are **never N/A**: they hold for any change
215
+ > that touches code at all, and a host wrongly claiming to be no-BC is exactly
216
+ > what they catch. Record the N/A; do not create a context, a Domain document,
217
+ > or a BR row to tick a box.
218
+
179
219
  ---
180
220
 
181
221
  ## 4. Integration Commit Message Conventions
@@ -209,6 +249,32 @@ Domain Events introduced / modified: {Event names, or "(none)"}
209
249
  Related SPEC-IDs: {SPEC-ID}{, follow-up SPEC-IDs if any}
210
250
  ```
211
251
 
252
+ **Zero-phase (minimal host) form.** A minimal host has no phases and may have
253
+ no bounded context, so its Change Scope block carries the values that are
254
+ actually true rather than padded ones:
255
+
256
+ ```
257
+ Change Scope:
258
+ - BC: none # or the real context, when the change has one
259
+ - Aggregate(s) touched: none
260
+ - Phase Count: 0
261
+ - Lightweight Changes: 1 T2 + 0 T3 # at least one row, always
262
+
263
+ Related BR-IDs: {empty, or the per-family no-BR marker this change carries}
264
+
265
+ Domain Events introduced / modified: (none)
266
+ ```
267
+
268
+ `none` and `0` are the honest values here, not placeholders waiting to be
269
+ filled. **`Related BR-IDs` is the exception — never force it to `none`.**
270
+ It reports what this change's own record carries, not what was synced, so it
271
+ takes the same values a BC-bearing host would: empty, or the per-family no-BR
272
+ marker when the T2 carries one. Writing `none` there erases the marker the
273
+ zero-phase shape requires (`references/finish-feature-flow.md` Step 5 states
274
+ the rule). A minimal host that genuinely touches a bounded context
275
+ reports that context and its real BR delta exactly as a phase-bearing feature
276
+ would — the zero is the **phase count**, not the significance.
277
+
212
278
  ### Concrete example
213
279
 
214
280
  ```bash
@@ -262,7 +328,7 @@ release.
262
328
  Example entry:
263
329
 
264
330
  ```markdown
265
- ## [1.2.3] — {YYYY-MM-DD}
331
+ ## [1.2.3] — {2026-04-21}
266
332
 
267
333
  ### Added
268
334
  - {SPEC-20260421-001}: ExpenseReport submission flow with Domain Events
@@ -276,6 +342,8 @@ Example entry:
276
342
 
277
343
  ---
278
344
 
345
+ <!-- dflow-generated: git-principles-canonical END -->
346
+
279
347
  ## 6. AI Collaboration Rules (Project Policy)
280
348
 
281
349
  Three categories:
@@ -17,6 +17,8 @@ use `Git-principles-gitflow.md` instead.
17
17
 
18
18
  ---
19
19
 
20
+ <!-- dflow-generated: git-principles-canonical START -->
21
+
20
22
  ## 1. Branch Structure
21
23
 
22
24
  Single-trunk model:
@@ -25,6 +27,7 @@ Single-trunk model:
25
27
  |--------|--------|----------|-----------|
26
28
  | `main` | `main` | — | — (protected; feature branches merge in) |
27
29
  | feature | `feature/{SPEC-ID}-{slug}` | `main` | `main` |
30
+ | bugfix | `bugfix/{BUG-ID}-{slug}` | `main` | `main` |
28
31
 
29
32
  No `develop`, no `release/*`, no `hotfix/*` branches. Hotfixes are just
30
33
  small, fast feature branches cut from `main`.
@@ -33,6 +36,17 @@ The `feature/{SPEC-ID}-{slug}` pattern is a **Dflow requirement** (not
33
36
  a trunk-based requirement). It ties each feature branch to its
34
37
  corresponding `dflow/specs/features/active/{SPEC-ID}-{slug}/` directory.
35
38
 
39
+ A **`bugfix/{BUG-ID}-{slug}`** branch is the same shape as a feature branch and
40
+ follows the same topology — cut from the same base, pushed the same way,
41
+ integrated the same way, and **closed out the same way**. It is used when a
42
+ defect owns its own host rather than being picked up by a feature already in
43
+ flight. Its host is a **minimal (zero-phase) host**, so it carries no
44
+ phase-spec: the SPEC-ID lives in the directory name while the branch name
45
+ carries the BUG-NUMBER, and the host `_index.md` `branch:` field is
46
+ authoritative for both. Closeout is not optional because the branch prefix
47
+ differs — `/dflow:finish-feature` runs and the directory is archived to
48
+ `completed/` before the branch merges, exactly as for `feature/`.
49
+
36
50
  ### Feature Branch Workflow
37
51
 
38
52
  ```bash
@@ -111,7 +125,8 @@ ExpenseItem before submission.
111
125
  ## 3. Merge Strategy Options
112
126
 
113
127
  Trunk-based projects typically pick **one** of the three below as the
114
- default. Document which one your team uses:
128
+ default. The trade-offs are here; **record which one your team uses in
129
+ § 6, under "Merge strategy"** — that section is yours, this one is not.
115
130
 
116
131
  ### Option A — Squash merge (most common)
117
132
 
@@ -123,8 +138,6 @@ All commits on the feature branch are squashed into a single commit on
123
138
  - Con: Loses intermediate commit context (though it's still available
124
139
  via the PR)
125
140
 
126
- **This project uses**: {Yes / No / Default — fill in}
127
-
128
141
  ### Option B — Rebase merge
129
142
 
130
143
  Each commit on the feature branch is rebased onto `main` as-is. Linear
@@ -135,8 +148,6 @@ history, but more commits than squash.
135
148
  phase)
136
149
  - Con: Noisier history
137
150
 
138
- **This project uses**: {Yes / No / Default — fill in}
139
-
140
151
  ### Option C — Fast-forward only
141
152
 
142
153
  Only merges when the feature branch is a direct descendant of `main`.
@@ -145,8 +156,6 @@ Equivalent to rebase merge when used consistently.
145
156
  - Pro: Perfectly linear
146
157
  - Con: Requires strict rebase discipline; can be inconvenient
147
158
 
148
- **This project uses**: {Yes / No / Default — fill in}
149
-
150
159
  ---
151
160
 
152
161
  ## 4. Integration Commit Message Conventions
@@ -181,6 +190,32 @@ Domain Events introduced / modified: {Event names, or "(none)"}
181
190
  Related SPEC-IDs: {SPEC-ID}{, follow-up SPEC-IDs if any}
182
191
  ```
183
192
 
193
+ **Zero-phase (minimal host) form.** A minimal host has no phases and may have
194
+ no bounded context, so its Change Scope block carries the values that are
195
+ actually true rather than padded ones:
196
+
197
+ ```
198
+ Change Scope:
199
+ - BC: none # or the real context, when the change has one
200
+ - Aggregate(s) touched: none
201
+ - Phase Count: 0
202
+ - Lightweight Changes: 1 T2 + 0 T3 # at least one row, always
203
+
204
+ Related BR-IDs: {empty, or the per-family no-BR marker this change carries}
205
+
206
+ Domain Events introduced / modified: (none)
207
+ ```
208
+
209
+ `none` and `0` are the honest values here, not placeholders waiting to be
210
+ filled. **`Related BR-IDs` is the exception — never force it to `none`.**
211
+ It reports what this change's own record carries, not what was synced, so it
212
+ takes the same values a BC-bearing host would: empty, or the per-family no-BR
213
+ marker when the T2 carries one. Writing `none` there erases the marker the
214
+ zero-phase shape requires (`references/finish-feature-flow.md` Step 5 states
215
+ the rule). A minimal host that genuinely touches a bounded context
216
+ reports that context and its real BR delta exactly as a phase-bearing feature
217
+ would — the zero is the **phase count**, not the significance.
218
+
184
219
  GitHub PR editor can be pre-filled with this body; the merge button
185
220
  then produces the squash commit.
186
221
 
@@ -213,6 +248,12 @@ For trivial features consisting of a single commit (often a T3
213
248
  triaged later to one small refactor / fix), the commit body itself
214
249
  IS the integration message — use the §4.1 format.
215
250
 
251
+ **A minimal (zero-phase) host is never this case.** It records **exactly two**
252
+ commits — the implementation checkpoint, then the closeout commit that carries
253
+ the archival `git mv` — so it does not arrive here with one. A minimal host
254
+ showing a single commit has not closed out: run `/dflow:finish-feature` first
255
+ rather than fast-forwarding it as it stands.
256
+
216
257
  ---
217
258
 
218
259
  ## 5. Gate Checks
@@ -226,7 +267,10 @@ Before making key Git operations:
226
267
  justification in the spec's notes section)
227
268
  - [ ] `_index.md` status reflects the current work (Phase Specs row
228
269
  updated, `Resume Pointer` refreshed if the commit reaches a meaningful
229
- checkpoint)
270
+ checkpoint). A **minimal (zero-phase) host** has no Phase Specs row to
271
+ update — its record is the Lightweight Changes row, and that row must
272
+ already be written **before** this commit, not after it. Refresh the
273
+ Resume Pointer as usual.
230
274
  - [ ] Clean Architecture layer rules hold (Domain has no external
231
275
  package deps, no business logic leaked into handlers /
232
276
  controllers)
@@ -247,8 +291,25 @@ Before making key Git operations:
247
291
  - [ ] Domain unit tests pass (invariants + value object equality)
248
292
  - [ ] CI is green (all required checks passing)
249
293
 
294
+ > **Minimal (zero-phase) host.** The items about this host's own record —
295
+ > `/dflow:finish-feature` having run, `_index.md` status `completed`, and the
296
+ > archival move — apply **unchanged**: they are what stops a host merging with
297
+ > its record still open. Every item naming a **Domain or bounded-context
298
+ > artifact** applies only to what this change **actually touched**: a **no-BC**
299
+ > host has no context to sync or document, and a **T3** does no Domain work at
300
+ > all, so for those they read N/A. **Bounded-context-scoped only** —
301
+ > `glossary.md` and the tech-debt file belong to no bounded context, stay in a
302
+ > no-BC host's sweep, and are **not** N/A for it. **Code invariants are not
303
+ > artifacts** — the items here that state a rule about the **source** rather
304
+ > than name a document to update are **never N/A**: they hold for any change
305
+ > that touches code at all, and a host wrongly claiming to be no-BC is exactly
306
+ > what they catch. Record the N/A; do not create a context, a Domain document,
307
+ > or a BR row to tick a box.
308
+
250
309
  ---
251
310
 
311
+ <!-- dflow-generated: git-principles-canonical END -->
312
+
252
313
  ## 6. AI Collaboration Rules (Project Policy)
253
314
 
254
315
  Three categories:
@@ -298,6 +359,13 @@ can always decline. If your team also wants vendor attribution, appending the
298
359
  assistant's documented line (e.g. `Co-Authored-By: Claude
299
360
  <noreply@anthropic.com>`) is an independent, optional convention on top.
300
361
 
362
+ ### Merge strategy
363
+
364
+ Dflow does not choose this for you; § 3 lists the trade-offs. Record what this
365
+ project settled on:
366
+
367
+ **This project uses**: {Squash / Rebase / Fast-forward only — fill in}
368
+
301
369
  ---
302
370
 
303
371
  ## 7. Hotfixes under Trunk-based
@@ -313,10 +381,18 @@ There is no separate `hotfix/*` branch. A hotfix is:
313
381
  4. Deployed via the same pipeline as any other change
314
382
 
315
383
  **Hotfix spec requirement (team convention)**: Hotfixes often skip the
316
- upfront SDD cycle for speed. This project commits to writing a
317
- lightweight spec within **24 hours** after the hotfix lands, documenting
318
- root cause + fix + (if applicable) a tech-debt entry in
319
- `dflow/specs/architecture/tech-debt.md` if the bug reveals a systemic issue.
384
+ upfront SDD cycle for speed. This project commits to documenting the fix
385
+ within **24 hours** after it lands. Run `/dflow:modify-existing` in
386
+ **post-hoc mode** (`references/modify-existing-flow.md` Step 1.8): it opens a
387
+ minimal host of its own for the fix, records the implementation checkpoint as
388
+ `reconciled ({merged-hotfix-hash})`, and reconciles rather than re-running work
389
+ that is already on the mainline.
390
+ What gets written is whatever the cascade's tier calls for — a **T2** lands a
391
+ lightweight spec (root cause + fix + a `dflow/specs/architecture/tech-debt.md` entry
392
+ if the bug reveals a systemic issue); a **T3** lands one `_index.md` Lightweight
393
+ Changes row and no spec file. Step 1.8 admits **T2 / T3 only**: a **T1**
394
+ post-hoc keeps the normal phase-bearing route and documents the merged work
395
+ there.
320
396
  This is a **human-to-human commitment** — Dflow / AI cannot track the
321
397
  24-hour clock; the team enforces it in retros.
322
398
 
@@ -30,25 +30,6 @@ dflow/specs/features/active/{SPEC-ID}-{slug}/
30
30
  T3 Trivial changes do **not** produce a separate file — they are
31
31
  recorded as one row in `_index.md` Lightweight Changes.
32
32
 
33
- ## Prose Language
34
-
35
- Project prose language: `{prose-language}`
36
-
37
- Dflow templates keep canonical English structural language: headings,
38
- table headers, fixed labels, placeholders, IDs, anchors, and code-facing
39
- terms remain English.
40
-
41
- Free prose written inside those sections should follow the project prose
42
- language:
43
-
44
- - `en`: write free prose in English.
45
- - `zh-TW`: write free prose in Traditional Chinese.
46
- - `{xx-XX}`: write free prose in that explicit BCP-47 language.
47
-
48
- Do not translate code identifiers, DDD pattern names, BR IDs, SPEC IDs,
49
- file paths, branch names, anchors, or inline code only to satisfy the
50
- prose-language setting.
51
-
52
33
  ### SPEC-ID Format
53
34
 
54
35
  - Pattern: `SPEC-YYYYMMDD-NNN` (e.g. `SPEC-20260421-001`)
@@ -56,6 +37,14 @@ prose-language setting.
56
37
  - Once assigned, the SPEC-ID is immutable — it appears in the feature
57
38
  directory name, the first phase-spec filename, and the git branch
58
39
  name (see `Git-principles-*.md`)
40
+ - **Minimal (zero-phase) host exception.** A host that records a small
41
+ standalone or follow-up change carries **no phase-spec**, so there is no
42
+ phase-spec filename for the SPEC-ID to appear in — the directory name and
43
+ the branch carry it. A **functional bug** host goes one step further: its
44
+ branch is `bugfix/BUG-{NUMBER}-{slug}`, so it carries the BUG-NUMBER and
45
+ not the SPEC-ID at all. In every case the host `_index.md` `branch:` field
46
+ is authoritative, and the SPEC-ID itself stays immutable. Do not create a
47
+ phase-spec, or rename a branch, to make the three-name rule above hold.
59
48
 
60
49
  ### Slug Conventions (Project-Specific Fill-In)
61
50
 
@@ -68,6 +57,25 @@ prose-language setting.
68
57
  - **Length target**: 2–4 English words or 2–6 Chinese characters
69
58
  (Dflow skill guidance)
70
59
 
60
+ ## Prose Language
61
+
62
+ Project prose language: `{prose-language}`
63
+
64
+ Dflow templates keep canonical English structural language: headings,
65
+ table headers, fixed labels, placeholders, IDs, anchors, and code-facing
66
+ terms remain English.
67
+
68
+ Free prose written inside those sections should follow the project prose
69
+ language:
70
+
71
+ - `en`: write free prose in English.
72
+ - `zh-TW`: write free prose in Traditional Chinese.
73
+ - `{xx-XX}`: write free prose in that explicit BCP-47 language.
74
+
75
+ Do not translate code identifiers, DDD pattern names, BR IDs, SPEC IDs,
76
+ file paths, branch names, anchors, or inline code only to satisfy the
77
+ prose-language setting.
78
+
71
79
  ---
72
80
 
73
81
  ## Filling the Templates
@@ -78,12 +86,15 @@ Dflow ships these templates (do **not** re-inline their content here
78
86
  | Template | Used when |
79
87
  |----------|-----------|
80
88
  | `templates/_index.md` | Creating a feature directory (every feature) |
81
- | `templates/phase-spec.md` | T1 Heavy — new feature / new phase / architectural change |
82
- | `templates/lightweight-spec.md` | T2 Light — bug fix / small tweak with BR Delta |
89
+ | `templates/phase-spec.md` | T1 Heavy |
90
+ | `templates/lightweight-spec.md` | T2 Light — classic BR-delta form, or one of the no-BR family variants (presentation, non-breaking contract, operational / security, performance, implementation defect, intentional change) |
83
91
  | `templates/context-definition.md` | When a new Bounded Context is introduced |
84
92
  | `templates/aggregate-design.md` | When a new Aggregate is introduced |
85
93
  | `templates/behavior.md` | BC-level consolidated behavior spec |
86
94
 
95
+ Which tier applies is decided by the cascade in `AI-AGENT-GUIDE.md` § Ceremony
96
+ Scaling, never by this table — these rows only say which template a tier uses.
97
+
87
98
  Project-specific guidance when filling these templates:
88
99
 
89
100
  ### DDD-specific spec conventions
@@ -120,18 +131,29 @@ Project-specific guidance when filling these templates:
120
131
 
121
132
  ## Ceremony Scaling (Project Application)
122
133
 
123
- Dflow defines three tiers — **T1 Heavy / T2 Light / T3
124
- Trivial**. See `AI-AGENT-GUIDE.md` § Ceremony Scaling for the full
125
- criteria table. We do not re-define the tier criteria here; this
134
+ Dflow defines three tiers — **T1 Heavy / T2 Light / T3 Trivial** — plus a
135
+ below-workflow level. See `AI-AGENT-GUIDE.md` § Ceremony Scaling for the
136
+ full ordered cascade. We do not re-define the tier criteria here; this
126
137
  section records how *this* project applies them in borderline
127
138
  situations.
128
139
 
140
+ **The cascade result is a floor: rows in this section may only escalate a
141
+ tier, never lower it.** A row may take a change Dflow would call T2 and
142
+ make it T1 for this project; no row may lower a T1, and no row may move a
143
+ tracked change below workflow.
144
+
145
+ Write `T<n> (project convention)` in the Tier column when this project raises the
146
+ tier, and `cascade result` when it adds an obligation but no tier change. Do not
147
+ write a bare tier — that restates the cascade instead of recording a decision,
148
+ and it is how the two drift apart.
149
+
129
150
  | Situation (project-specific) | Tier we default to | Why |
130
151
  |------------------------------|--------------------|-----|
131
- | {e.g. New Aggregate} | T1 + `aggregate-design.md` | Crosses Aggregate boundary and needs invariant documentation |
132
- | {e.g. Adding a Query only (no write)} | T2 | No Aggregate state change, but goes through Application layer; trace via lightweight-spec |
133
- | {e.g. EF configuration tweak in Infrastructure} | T3 if no Domain change | Infra-only; inline row in `_index.md` |
134
- | {e.g. Domain Event payload extension} | T1 | Event contract change affects cross-context consumers |
152
+ | {e.g. New Aggregate} | cascade result + `aggregate-design.md` | No tier change — we add the design worksheet on top of whatever the cascade returns, because our invariants need somewhere to live |
153
+ | {e.g. A supporting query added for an existing screen or behaviour change} | T2 (project convention) | We want a lightweight-spec trace even when the cascade would not require a spec file |
154
+ | {e.g. A newly exposed read capability — new endpoint, new data source, or an independently callable read} | T1 (project convention) | We escalate any newly exposed read above whatever the cascade returns — our consumers treat it as a contract the moment it exists |
155
+ | {e.g. EF configuration tweak in Infrastructure} | T1 (project convention) | We escalate Infrastructure mapping tweaks above whatever the cascade returns — this layer has silently changed persisted behaviour before |
156
+ | {e.g. Domain Event payload extension} | T1 (project convention) | We escalate above whatever the cascade returns for an additive optional field, because our cross-context consumers deserialize strictly |
135
157
 
136
158
  ### DDD Modeling Depth (`AI-AGENT-GUIDE.md` § Ceremony Scaling)
137
159
 
@@ -1,3 +1,4 @@
1
+ <!-- dflow-shape: greenfield/_overview.md 1 — keep this line: dflow doctor reads it -->
1
2
  <!-- Seeded by Dflow. -->
2
3
 
3
4
  # System Overview — {System Name}
@@ -140,8 +141,11 @@ to the following design habits. Expand / adapt each to this project:
140
141
  - **Domain at the Center** — Business rules live in `*.Domain`. If you
141
142
  find business logic in `*.Application` handlers or (worse) in
142
143
  controllers, raise a tech-debt entry.
143
- - **Aggregate Boundaries** — Each transaction modifies exactly one
144
- Aggregate. Cross-aggregate workflows go through Domain Events.
144
+ - **Aggregate Boundaries** — By default, each transaction modifies one
145
+ Aggregate and cross-Aggregate workflows use Domain Events. Any justified
146
+ local multi-Aggregate exception must follow and record the contract in
147
+ `dflow/specs/shared/dflow-workflows/references/ddd-modeling-guide.md`
148
+ "Aggregate Design Rules"; external facts cannot join the local transaction.
145
149
  - **Dependency Inversion** — The Domain declares interfaces; the
146
150
  Infrastructure layer implements them. No Domain code imports
147
151
  `Microsoft.EntityFrameworkCore`.