dflow-sdd-ddd 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.md +915 -0
  2. package/CONTRIBUTING.md +11 -1
  3. package/README.en.md +160 -212
  4. package/README.md +93 -147
  5. package/TEMPLATE-COVERAGE.md +13 -6
  6. package/TEMPLATE-LANGUAGE-GLOSSARY.md +15 -1
  7. package/bin/dflow.js +90 -4
  8. package/docs/closeout-check.en.md +204 -0
  9. package/docs/closeout-check.md +204 -0
  10. package/docs/commands.en.md +112 -0
  11. package/docs/commands.md +103 -0
  12. package/docs/doctor-uncertainty.en.md +212 -0
  13. package/docs/doctor-uncertainty.md +212 -0
  14. package/docs/evaluating-dflow.en.md +29 -11
  15. package/docs/evaluating-dflow.md +8 -6
  16. package/docs/release-versioning-policy.md +6 -0
  17. package/docs/upgrading.en.md +196 -0
  18. package/docs/upgrading.md +197 -0
  19. package/docs/using-with-claude-code.en.md +13 -4
  20. package/docs/using-with-claude-code.md +13 -4
  21. package/docs/using-with-codex.en.md +13 -4
  22. package/docs/using-with-codex.md +13 -4
  23. package/docs/using-with-github-copilot.en.md +13 -4
  24. package/docs/using-with-github-copilot.md +13 -4
  25. package/lib/closeout-check.js +690 -0
  26. package/lib/doc-shapes.json +1195 -0
  27. package/lib/doctor-checks.js +2500 -24
  28. package/lib/init.js +2861 -143
  29. package/lib/render-diagrams.js +1474 -0
  30. package/lib/render.js +865 -49
  31. package/package.json +2 -2
  32. package/templates/brownfield/references/drift-verification.md +4 -0
  33. package/templates/brownfield/references/finish-feature-flow.md +648 -98
  34. package/templates/brownfield/references/finish-feature-follow-up.md +60 -0
  35. package/templates/brownfield/references/finish-feature-minimal-host.md +427 -0
  36. package/templates/brownfield/references/finish-feature-post-hoc-hotfix.md +95 -0
  37. package/templates/brownfield/references/finish-feature-record-correction.md +45 -0
  38. package/templates/brownfield/references/git-integration.md +205 -26
  39. package/templates/brownfield/references/init-project-flow.md +23 -3
  40. package/templates/brownfield/references/modify-existing-flow.md +439 -88
  41. package/templates/brownfield/references/modify-existing-follow-up.md +122 -0
  42. package/templates/brownfield/references/modify-existing-post-hoc-hotfix.md +200 -0
  43. package/templates/brownfield/references/new-feature-flow.md +110 -37
  44. package/templates/brownfield/references/new-phase-flow.md +59 -9
  45. package/templates/brownfield/references/pr-review-checklist.md +328 -10
  46. package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +151 -34
  47. package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +1 -1
  48. package/templates/brownfield/scaffolding/Git-principles-gitflow.md +85 -8
  49. package/templates/brownfield/scaffolding/Git-principles-trunk.md +88 -10
  50. package/templates/brownfield/scaffolding/_conventions.md +50 -28
  51. package/templates/brownfield/scaffolding/_overview.md +1 -0
  52. package/templates/brownfield/templates/_index.md +158 -10
  53. package/templates/brownfield/templates/analysis.md +79 -0
  54. package/templates/brownfield/templates/behavior.md +1 -0
  55. package/templates/brownfield/templates/context-definition.md +1 -0
  56. package/templates/brownfield/templates/context-map.md +2 -1
  57. package/templates/brownfield/templates/glossary.md +1 -0
  58. package/templates/brownfield/templates/lightweight-spec.md +154 -11
  59. package/templates/brownfield/templates/models.md +1 -0
  60. package/templates/brownfield/templates/phase-spec.md +9 -1
  61. package/templates/brownfield/templates/rules.md +1 -0
  62. package/templates/brownfield/templates/tech-debt.md +1 -0
  63. package/templates/common/references/ddd-modeling-guide.md +33 -16
  64. package/templates/{greenfield → common}/references/dflow-feedback-flow.md +2 -1
  65. package/templates/common/references/flow-rationale-registry.md +146 -0
  66. package/templates/common/skill/SKILL.md +13 -11
  67. package/templates/greenfield/references/drift-verification.md +4 -0
  68. package/templates/greenfield/references/finish-feature-flow.md +639 -100
  69. package/templates/greenfield/references/finish-feature-follow-up.md +60 -0
  70. package/templates/greenfield/references/finish-feature-minimal-host.md +383 -0
  71. package/templates/greenfield/references/finish-feature-post-hoc-hotfix.md +95 -0
  72. package/templates/greenfield/references/finish-feature-record-correction.md +45 -0
  73. package/templates/greenfield/references/git-integration.md +193 -26
  74. package/templates/greenfield/references/init-project-flow.md +23 -3
  75. package/templates/greenfield/references/modify-existing-flow.md +395 -87
  76. package/templates/greenfield/references/modify-existing-follow-up.md +104 -0
  77. package/templates/greenfield/references/modify-existing-post-hoc-hotfix.md +200 -0
  78. package/templates/greenfield/references/new-feature-flow.md +116 -35
  79. package/templates/greenfield/references/new-phase-flow.md +58 -9
  80. package/templates/greenfield/references/pr-review-checklist.md +311 -8
  81. package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +146 -32
  82. package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +5 -2
  83. package/templates/greenfield/scaffolding/Git-principles-gitflow.md +84 -8
  84. package/templates/greenfield/scaffolding/Git-principles-trunk.md +94 -14
  85. package/templates/greenfield/scaffolding/_conventions.md +50 -28
  86. package/templates/greenfield/scaffolding/_overview.md +6 -2
  87. package/templates/greenfield/templates/_index.md +145 -10
  88. package/templates/greenfield/templates/aggregate-design.md +1 -0
  89. package/templates/greenfield/templates/analysis.md +79 -0
  90. package/templates/greenfield/templates/behavior.md +1 -0
  91. package/templates/greenfield/templates/context-definition.md +1 -0
  92. package/templates/greenfield/templates/context-map.md +2 -1
  93. package/templates/greenfield/templates/events.md +4 -1
  94. package/templates/greenfield/templates/glossary.md +1 -0
  95. package/templates/greenfield/templates/lightweight-spec.md +154 -11
  96. package/templates/greenfield/templates/models.md +1 -0
  97. package/templates/greenfield/templates/phase-spec.md +9 -1
  98. package/templates/greenfield/templates/rules.md +1 -0
  99. package/templates/greenfield/templates/tech-debt.md +1 -0
  100. package/templates/brownfield/references/dflow-feedback-flow.md +0 -251
@@ -28,8 +28,8 @@ are not available in the current AI tool:
28
28
 
29
29
  | Workflow | Use when |
30
30
  |---|---|
31
- | `/dflow:new-feature` | A new user-visible capability or business behavior is requested. |
32
- | `/dflow:modify-existing` | Existing behavior needs to change. |
31
+ | `/dflow:new-feature` | A genuinely new feature, page, or capability — a **newly created** navigable surface (its own route and its own content tree), a new user-executable domain operation, or a new independently-consumable output. Adding a control to an existing surface — or a menu entry pointing at a route that already exists — is modify-existing. |
32
+ | `/dflow:modify-existing` | Existing behavior or an existing surface changes — including adding a presentation / interaction control (copy button, filter, sort, quick-view) to an existing screen. |
33
33
  | `/dflow:bug-fix` | A defect can be described with expected vs actual behavior. |
34
34
  | `/dflow:new-phase` | An active feature needs another implementation slice. |
35
35
  | `/dflow:finish-feature` | Implementation is complete and needs drift closure. |
@@ -45,8 +45,8 @@ Machine-readable source for rendering tool-specific thin wrappers:
45
45
  <!-- dflow-command-registry:start -->
46
46
  | id | label | description | arg-hint | scope |
47
47
  |---|---|---|---|---|
48
- | new-feature | /dflow:new-feature | Start a new user-visible feature or business behavior. | feature request | workflow |
49
- | modify-existing | /dflow:modify-existing | Change existing behavior. | change request | workflow |
48
+ | new-feature | /dflow:new-feature | Start a genuinely new feature, page, or capability (new navigable surface, domain operation, or consumable output). | feature request | workflow |
49
+ | modify-existing | /dflow:modify-existing | Change existing behavior, or add a control to an existing surface. | change request | workflow |
50
50
  | bug-fix | /dflow:bug-fix | Investigate a defect described by expected vs actual behavior. | expected vs actual | workflow |
51
51
  | new-phase | /dflow:new-phase | Add another implementation slice to an active feature. | feature id or phase goal | workflow |
52
52
  | finish-feature | /dflow:finish-feature | Close implementation with drift checks and archived feature state. | feature id | workflow |
@@ -68,7 +68,26 @@ input like this (supporting files live in the workflow bundle at
68
68
  `references/ddd-modeling-guide.md`.
69
69
  - **"Quick question about..." / "How does X work?"** → check
70
70
  `dflow/specs/domain/` first and answer from the documented domain knowledge.
71
+ - **Knowledge that no single context document holds** — an ordered flow that
72
+ crosses contexts (always the domain-root copy), the lifecycle a status field
73
+ moves through, a figure computed rather than stored, the mechanism behind a
74
+ behavior no single rule explains, which roles reach which function (always
75
+ the domain-root copy), or a spot in one of these that this project keeps
76
+ working around until a domain decision settles it (in the copy that holds
77
+ the knowledge it is stuck on) → **record it in
78
+ `analysis.md`**: `dflow/specs/domain/{context}/analysis.md` when one context
79
+ owns what it describes, otherwise `dflow/specs/domain/analysis.md`. Create
80
+ the file from `templates/analysis.md` the first time there is something to
81
+ record. With no workflow running, offer to commit that record on its own.
71
82
  - **"I'm creating a branch"** → read `references/git-integration.md`.
83
+ - **"Why does this rule exist?" / "This rule seems wrong"** → look the rule up in
84
+ `references/flow-rationale-registry.md`. Grep the rule id when you have one
85
+ (`grep -E '^R-FF-BRANCH-02:'`), otherwise a **short** fragment of the rule —
86
+ four to eight words, because the flow files are hard-wrapped and a longer
87
+ phrase spans a line break. A lookup may return two lines tagged `gf ·` / `bf ·`;
88
+ take this project's edition, which the workflow bundle's
89
+ `.dflow-bundle-manifest.json` records in its `edition` field. **Do not read
90
+ that file whole** — it is a lookup table, not a document.
72
91
  - **"Turn the specs into HTML" / "make the specs easier to read"** → run the
73
92
  CLI command `dflow render` (a human-readability tool, not a `/dflow:*`
74
93
  workflow). It mirrors `dflow/specs/` into a browsable static HTML tree
@@ -77,10 +96,18 @@ input like this (supporting files live in the workflow bundle at
77
96
  - **"Dflow seems wrong" / "this template is confusing"** (or you notice Dflow
78
97
  guidance drift) → suggest `/dflow:report-dflow-feedback`; never submit
79
98
  anything upstream automatically.
80
- - **Anything else code-related** → assess whether it touches business logic. If
81
- it does, use the auto-trigger safety net (suggest the matching `/dflow:*`
82
- command and wait for confirmation — see § Workflow Transparency); if not, help
83
- directly with no ceremony.
99
+ - **Anything else code-related** → run it through § Ceremony Scaling's ordered
100
+ cascade rather than a business-logic yes/no. Only the cascade's step 2 sends
101
+ work outside Dflow, and it is narrower than "not business logic": a display
102
+ typo, an appearance change, a machine-consumed contract edit, security / CVE
103
+ work and a deliberate runtime performance change are all tracked. If the
104
+ cascade lands the request anywhere at or above T3, suggest the matching
105
+ `/dflow:*` command and wait for confirmation (see § Workflow Transparency);
106
+ only if it lands below workflow, help directly with no ceremony. If step 0
107
+ takes it out of the cascade instead — observation-only work — it is neither:
108
+ say so and record it, do not treat "no tier" as "no ceremony". This applies
109
+ once you are already reading this guide — what makes a tool load it in the
110
+ first place is that tool's own trigger configuration, which is narrower.
84
111
 
85
112
  ## Status / Control Commands
86
113
 
@@ -206,6 +233,8 @@ Dflow-owned project documents live under `dflow/specs/`.
206
233
  | System overview | `dflow/specs/shared/_overview.md` |
207
234
  | Domain glossary | `dflow/specs/domain/glossary.md` |
208
235
  | Context map | `dflow/specs/domain/context-map.md` |
236
+ | Domain analysis (cross-context) | `dflow/specs/domain/analysis.md` |
237
+ | Domain analysis (per context) | `dflow/specs/domain/{context}/analysis.md` |
209
238
  | Active feature specs | `dflow/specs/features/active/` |
210
239
  | Completed feature snapshots | `dflow/specs/features/completed/` |
211
240
  | Technical debt | `dflow/specs/architecture/tech-debt.md` or `dflow/specs/migration/tech-debt.md` |
@@ -222,10 +251,12 @@ dflow/specs/
222
251
  ├── domain/
223
252
  │ ├── glossary.md
224
253
  │ ├── context-map.md # Bounded Context relationships
254
+ │ ├── analysis.md # Cross-context flows and role reach
225
255
  │ └── {bounded-context}/
226
256
  │ ├── context.md
227
257
  │ ├── models.md # Aggregates, Entities, VOs
228
258
  │ ├── rules.md # Business rules index (BR-ID + one-line)
259
+ │ ├── analysis.md # Lifecycles, derived figures, mechanisms
229
260
  │ ├── behavior.md # Consolidated behavior (Given/When/Then)
230
261
  │ └── events.md # Domain Events catalog
231
262
  ├── features/
@@ -255,29 +286,112 @@ dflow/specs/
255
286
 
256
287
  ## Ceremony Scaling
257
288
 
258
- Dflow uses three tiers — **T1 Heavy / T2 Light / T3 Trivial** — chosen by the AI
259
- per change. `/dflow:new-feature` and `/dflow:new-phase` always default to T1 (no
260
- judgement needed). The criteria below apply when `/dflow:modify-existing` or
261
- `/dflow:bug-fix` decides which tier fits a modification.
262
-
263
- | Tier | Scenario | Output | Command / Trigger |
264
- |---|---|---|---|
265
- | **T1 Heavy** | New feature, new phase, new Aggregate / BC, architectural change, new BR | Independent `phase-spec-YYYY-MM-DD-{slug}.md` placed in the feature directory + `_index.md` Phase Specs row + refresh BR Snapshot. For a new Aggregate / BC also create an `aggregate-design.md` from `templates/aggregate-design.md` **in the feature directory** (working worksheet; the durable summary stays in `models.md`) + update `context-map.md` + `events.md`. | `/dflow:new-feature` / `/dflow:new-phase` |
266
- | **T2 Light** | Bug fix (logic error), UI input validation tweak, flow branch change — has BR Delta | Independent `lightweight-YYYY-MM-DD-{slug}.md` (or `BUG-{NUMBER}-{slug}.md`) inside the feature directory + `_index.md` Lightweight Changes row (outbound link) + refresh BR Snapshot. Confirm the fix lands in the correct architectural layer. | `/dflow:bug-fix` or `/dflow:modify-existing` (lightweight branch) |
267
- | **T3 Trivial** | Button colour, copy/text fix, typo, formatting, pure comments — **no BR change, no Domain concept change, no data structure change** | **Inline row in `_index.md` Lightweight Changes only** (no independent spec file) | `/dflow:modify-existing` (`_index-only` branch) |
268
-
269
- **T3 criteria** (the AI must satisfy **all four** before classifying T3):
270
-
271
- 1. No BR-ID change (no ADDED / MODIFIED / REMOVED / RENAMED business rule)
272
- 2. No Domain concept added or changed (Aggregate / Entity / VO / Event)
273
- 3. No data structure change (table, column, relation, index)
274
- 4. Only changes UI surface (colour, text, layout), pure comments, or pure formatting
275
-
276
- If any criterion fails → drop to T2; if Domain / BR / data structure is touched → escalate to T1.
277
-
278
- **Below T3 — Dflow doesn't track at all**: pure typo fixes, commit-message
279
- typos, pure formatting commits (e.g. `prettier` / `dotnet format` auto-runs).
280
- You can `git commit` directly without writing even a T3 inline row.
289
+ Dflow uses three tiers — **T1 Heavy / T2 Light / T3 Trivial** — plus a
290
+ **below-workflow** level Dflow doesn't track at all. `/dflow:new-feature` and
291
+ `/dflow:new-phase` are always T1 (no judgement). For `/dflow:modify-existing`
292
+ and `/dflow:bug-fix`, classify the change with the **ordered cascade — the first
293
+ step that matches wins** (order matters: a later catch-all would otherwise
294
+ swallow the trivial and below-workflow cases):
295
+
296
+ 0. **Scope.** The cascade classifies a *modification*. Genuinely new work — a
297
+ new feature, page, or capability — is `/dflow:new-feature` (T1), even with no
298
+ new BR / Domain / schema. Adding a presentation or interaction control to an
299
+ **existing** surface (copy button, date-range filter, sort control, quick-view
300
+ drawer / tab, or filling a missing `aria-label`) is a *modification* (stays in
301
+ the cascade). A new user-executable domain operation (e.g. one-click return), a
302
+ new independently-consumable output or delivery channel (Download-PDF / export /
303
+ emailed report), or a **newly created** navigable surface (its own route and its
304
+ own content tree) **is** new-feature. Adding a menu entry or link that points at
305
+ a route that already exists is an access control on an existing surface —
306
+ a modification, not a new surface. **Unit of classification**: classify one
307
+ coherent requested change. Split a compound request into its atomic changes,
308
+ run each through the cascade, and let the highest tier govern the whole — each
309
+ lower-tier part still records its own artifact under the same host. Mechanical
310
+ fallout you did not ask for (formatter noise, lint churn) neither raises nor
311
+ lowers the result.
312
+ **Observation-only work is also outside the
313
+ cascade**: capturing existing behaviour as a baseline (Brownfield) changes no
314
+ output, so it carries no tier at all — record it and do not read step 2's
315
+ "below workflow" as permission to skip the record.
316
+ 1. **T1 — Heavy.** A **new** business rule or normative constraint (permission /
317
+ eligibility / threshold / approval / required outcome — regardless of whether a
318
+ BR-ID already exists). *New* means a rule that can be stated and broken on its
319
+ own: take the change away and the original rule still works exactly as before.
320
+ Changing an existing rule's parameters is **T2** — a different threshold value,
321
+ or adding to a set the rule already checks (one more allowed country, one more
322
+ approver role). Adding an independent condition the rule never had (an approver
323
+ predicate for a specific payment channel) is a new rule, and T1. A Domain concept (Aggregate / Entity / VO / Event)
324
+ **added or structurally changed** (identity, VO equality components, aggregate
325
+ boundary, or removing / renaming / redefining a spec-tracked member — a Domain
326
+ concept **rename** is T1); a persistent **data-structure** change (table /
327
+ column / relation / index added, removed, renamed, or its type / nullability /
328
+ constraint / logical definition changed); an **architectural** change
329
+ (inter-layer dependency direction, deployment / module boundary, runtime /
330
+ platform ownership, or overturning an architecture decision — behavior-
331
+ preserving still counts); or a **breaking** cross-consumer contract (API /
332
+ event). Contracts run **inbound** too — a required env var / deployment config
333
+ key, a CLI flag, an exit code, a scheduled-automation calling convention. What
334
+ breaks a caller is T1: removing or renaming one, changing what one means, or
335
+ adding a **required** key with no backward-compatible default (deployments must
336
+ act) — making an existing operation's parameter **required** breaks callers the
337
+ same way. Adding an *optional* key or parameter with a backward-compatible
338
+ default is non-breaking — T2 via step 4.
339
+ 2. **Below workflow — not tracked.** No audience-perceivable output delta **and**
340
+ no machine-consumed-contract or operational-semantics touch: auto-formatter
341
+ runs, whitespace, internal comments, internal-doc typos, commit messages, and
342
+ behavior-preserving **routine** refactors / dependency bumps. **Routine** =
343
+ touches no operational-semantics axis (security / safety / resilience /
344
+ compliance / payment) and is not architectural — **breadth is not the test** (a
345
+ behavior-preserving refactor across hundreds of call sites is still below
346
+ workflow; a single-file change that touches an operational axis is not). Never
347
+ below workflow, even when invisible: any BR-ID delta, any machine-consumed
348
+ structured-log / export / contract change, any deliberate runtime performance /
349
+ resource / SLA change, or any security / CVE / compliance work — those reach
350
+ step 1 or 4 by audience. `git commit` directly.
351
+ 3. **T3 — Trivial.** A **local, low-risk, meaning-preserving pure copy or
352
+ appearance change a product audience perceives** — display-text typo / wording
353
+ polish, colour, spacing, layout polish, or polishing existing alt / ARIA
354
+ wording — on a **single screen / component or single independently-consumed
355
+ page / file**, at the **element level**. **Excluded from T3**: high-consequence
356
+ content (security warnings, password hints, consent, payment / legal notices);
357
+ meaning-changing appearance (danger / status-colour semantics); anything
358
+ affecting operability, default state, interaction order, or task completion
359
+ ("just CSS" is no exemption); adding a **missing** accessible name (compliance
360
+ remediation); and text a machine consumes — an API error string or code a client
361
+ parses is contract, not display copy, so it is never T3: route it by the contract
362
+ axis instead (breaks the consumer → step 1, T1; otherwise → step 4, T2). **Locality is
363
+ the rendered audience footprint, not the number of source files**: one shared
364
+ component or localization key whose output appears on several screens is beyond
365
+ the local unit (T2), while edits to several files that surface in one place stay
366
+ T3. Anything beyond that unit is T2 — a typo swept across many screens, a
367
+ whole-screen visual rewrite, a cross-page sweep. The limit follows the whole
368
+ intent, so splitting one cross-screen typo sweep into per-screen requests does
369
+ not turn it into several T3s.
370
+ 4. **T2 — Light (catch-all — everything else).** Functional / semantic behavior
371
+ delta (logic, validation, interaction flow, display calculation, an
372
+ **existing** BR's delta, non-breaking contract semantics); performance-only
373
+ changes (perceivable or not); and copy / appearance sweeps escalated from step
374
+ 3. Functional bug fixes are T2 (root-cause + regression notes).
375
+
376
+ | Tier | Output | Command / Trigger |
377
+ |---|---|---|
378
+ | **T1 Heavy** | Independent `phase-spec-YYYY-MM-DD-{slug}.md` in the feature directory + `_index.md` Phase Specs row + refresh BR Snapshot. For a new Aggregate / BC also create an `aggregate-design.md` from `templates/aggregate-design.md` **in the feature directory** (working worksheet; durable summary stays in `models.md`) + update `context-map.md` + `events.md`. | `/dflow:new-feature` / `/dflow:new-phase` — also where a `/dflow:modify-existing` or `/dflow:bug-fix` request goes when the cascade lands it at T1 |
379
+ | **T2 Light** | Independent `lightweight-YYYY-MM-DD-{slug}.md` (or `BUG-{NUMBER}-{slug}.md`) inside the feature directory + `_index.md` Lightweight Changes row (outbound link) + refresh BR Snapshot. Confirm the fix lands in the correct architectural layer. | `/dflow:modify-existing` or `/dflow:bug-fix` — the usual landing for a functional defect |
380
+ | **T3 Trivial** | **Inline row in the host `_index.md` Lightweight Changes only** (no independent spec file) | `/dflow:modify-existing` or `/dflow:bug-fix` (`_index`-only branch — e.g. a defect that is only a display-text typo) |
381
+
382
+ **Audience** = any human audience of the product perceives the output: UI
383
+ (including alt / ARIA read by assistive tech), email, exports. Public / adopter-
384
+ facing docs (product README, public API reference) and operator surfaces
385
+ (dashboard labels, alerts) are product-audience: pure wording = T3 (single page;
386
+ a cross-page sweep escalates to T2 at step 3), meaning change = T2. Raw internal
387
+ diagnostic logs / traces are internal (copy-only fixes are below workflow).
388
+ Structured logs / machine-readable exports a downstream consumer depends on are
389
+ contract: breaking cross-consumer = step 1 T1, non-breaking = step 4 T2.
390
+
391
+ **Project conventions can only escalate.** `_conventions.md` Ceremony (Project
392
+ Application) rows are a floor-raising overlay applied *after* the cascade: a
393
+ project may push a T2 up to T1, but may not lower a cascade T1, nor drop a
394
+ tracked class below workflow.
281
395
 
282
396
  **DDD Modeling Depth (still informs T1 scope)**:
283
397
 
@@ -374,7 +488,7 @@ directory first. For example:
374
488
  |---|---|
375
489
  | `/dflow:new-feature` | `dflow/specs/shared/dflow-workflows/references/new-feature-flow.md` |
376
490
  | `/dflow:modify-existing` | `dflow/specs/shared/dflow-workflows/references/modify-existing-flow.md` |
377
- | `/dflow:bug-fix` | `dflow/specs/shared/dflow-workflows/references/modify-existing-flow.md` (lightweight-ceremony branch) |
491
+ | `/dflow:bug-fix` | `dflow/specs/shared/dflow-workflows/references/modify-existing-flow.md` (same flow; tier comes from the cascade, not from the command) |
378
492
  | `/dflow:new-phase` | `dflow/specs/shared/dflow-workflows/references/new-phase-flow.md` |
379
493
  | `/dflow:finish-feature` | `dflow/specs/shared/dflow-workflows/references/finish-feature-flow.md` |
380
494
  | `/dflow:verify` | `dflow/specs/shared/dflow-workflows/references/drift-verification.md` |
@@ -115,7 +115,10 @@ AI 的完整決策樹、Workflow Transparency、Ceremony Scaling 三層判準
115
115
  1. **Spec Before Code** — 沒有規格就不寫實作
116
116
  2. **Domain at the Center** — 業務邏輯只存在於 Domain 層
117
117
  3. **Ubiquitous Language** — 使用 `dflow/specs/domain/glossary.md` 中定義的術語
118
- 4. **One Aggregate per Transaction** — 單一操作只修改一個 Aggregate
118
+ 4. **One Aggregate per Transaction(default)** — 單一操作預設只修改一個
119
+ Aggregate;有充分理由的 multi-root local transaction 例外,依
120
+ `dflow/specs/shared/dflow-workflows/references/ddd-modeling-guide.md`
121
+ 「Aggregate Design Rules」記錄 domain rationale 與 re-evaluation condition
119
122
  5. **Dependency Inversion** — Domain 定義介面,Infrastructure 實作
120
123
 
121
124
  ### Domain Layer Rules (Hard Invariants)
@@ -147,7 +150,7 @@ AI 的完整決策樹、Workflow Transparency、Ceremony Scaling 三層判準
147
150
 
148
151
  ### AI Collaboration Notes
149
152
 
150
- - 開發者提出任何需求時,先引導建立 spec 和 Aggregate 設計
153
+ - 開發者提出需求時,先用 guide 的 § Ceremony Scaling ordered cascade 判 tier,再依 tier 決定產出:T1 才引導建立 spec 和 Aggregate 設計,T2 用 lightweight spec,T3 在所屬 feature 的 `_index.md` 記一行(沒有 active host 時,`/dflow:modify-existing` 會先開一個 minimal zero-phase host),below workflow 直接做
151
154
  - 確認實作順序:Domain → Application → Infrastructure → Presentation
152
155
  - 發現業務邏輯在錯誤的層時,指出並建議搬移
153
156
  - 每次開發循環結束時,提醒更新術語表、models.md、events.md
@@ -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,22 @@ 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. The hash it records is the hotfix's own
131
+ commit, **not** the tagged merge commit on `main` (step 3): the record is
132
+ never a merge commit, and step 4 merges the hotfix **branch**, so the tagged
133
+ commit does not come into `develop` with it.
134
+ `references/modify-existing-post-hoc-hotfix.md` item 3 has the rule.
135
+ What gets written is whatever the cascade's tier calls for — a **T2** lands a
136
+ lightweight spec (root cause + fix + a `dflow/specs/architecture/tech-debt.md` entry
137
+ if the bug reveals a systemic issue); a **T3** lands one `_index.md` Lightweight
138
+ Changes row and no spec file. Step 1.8 admits **T2 / T3 only**: a **T1**
139
+ post-hoc keeps the normal phase-bearing route and documents the merged work
140
+ there.
115
141
  This is a **human-to-human commitment** — Dflow / AI cannot track the
116
142
  24-hour clock; the team enforces it in retros.
117
143
 
@@ -156,15 +182,22 @@ Before making key Git operations:
156
182
  justification in the spec's notes section)
157
183
  - [ ] `_index.md` status reflects the current work (Phase Specs row
158
184
  updated, `Resume Pointer` refreshed if the commit reaches a meaningful
159
- checkpoint)
185
+ checkpoint). A **minimal (zero-phase) host** has no Phase Specs row to
186
+ update — its record is the Lightweight Changes row, and that row must
187
+ already be written **before** this commit, not after it. Refresh the
188
+ Resume Pointer as usual.
160
189
  - [ ] Clean Architecture layer rules hold (Domain has no external
161
190
  package deps, no business logic leaked into handlers /
162
191
  controllers)
163
192
 
164
193
  ### Before merging a feature branch to `develop`
165
194
 
166
- - [ ] `/dflow:finish-feature` has run (or the equivalent Step 8.4
167
- manual archival is complete)
195
+ - [ ] **Closeout complete**: `/dflow:finish-feature` has announced closeout
196
+ complete for this host — its Local-closeout gate is satisfied (the
197
+ closeout commit landed and passed post-commit verification) and, if
198
+ the host carries `follow-up-of`, the Step 6 tracking commit has also
199
+ landed and been verified. `status: completed` or a directory already
200
+ under `completed/` does not show this on its own.
168
201
  - [ ] `_index.md` status = `completed`, feature directory moved to
169
202
  `dflow/specs/features/completed/` via `git mv`
170
203
  - [ ] BC layer synced: `dflow/specs/domain/{context}/rules.md`,
@@ -176,6 +209,21 @@ Before making key Git operations:
176
209
  - [ ] No ORM / serialization attributes on Domain entities
177
210
  - [ ] Domain unit tests pass (invariants + value object equality)
178
211
 
212
+ > **Minimal (zero-phase) host.** The items about this host's own record —
213
+ > **Closeout complete**, `_index.md` status `completed`, and the archival
214
+ > move — apply **unchanged**: they are what stops a host merging with
215
+ > its record still open. Every item naming a **Domain or bounded-context
216
+ > artifact** applies only to what this change **actually touched**: a **no-BC**
217
+ > host has no context to sync or document, and a **T3** does no Domain work at
218
+ > all, so for those they read N/A. **Bounded-context-scoped only** —
219
+ > `glossary.md` and the tech-debt file belong to no bounded context, stay in a
220
+ > no-BC host's sweep, and are **not** N/A for it. **Code invariants are not
221
+ > artifacts** — the items here that state a rule about the **source** rather
222
+ > than name a document to update are **never N/A**: they hold for any change
223
+ > that touches code at all, and a host wrongly claiming to be no-BC is exactly
224
+ > what they catch. Record the N/A; do not create a context, a Domain document,
225
+ > or a BR row to tick a box.
226
+
179
227
  ---
180
228
 
181
229
  ## 4. Integration Commit Message Conventions
@@ -209,6 +257,32 @@ Domain Events introduced / modified: {Event names, or "(none)"}
209
257
  Related SPEC-IDs: {SPEC-ID}{, follow-up SPEC-IDs if any}
210
258
  ```
211
259
 
260
+ **Zero-phase (minimal host) form.** A minimal host has no phases and may have
261
+ no bounded context, so its Change Scope block carries the values that are
262
+ actually true rather than padded ones:
263
+
264
+ ```
265
+ Change Scope:
266
+ - BC: none # or the real context, when the change has one
267
+ - Aggregate(s) touched: none
268
+ - Phase Count: 0
269
+ - Lightweight Changes: 1 T2 + 0 T3 # at least one row, always
270
+
271
+ Related BR-IDs: {empty, or the per-family no-BR marker this change carries}
272
+
273
+ Domain Events introduced / modified: (none)
274
+ ```
275
+
276
+ `none` and `0` are the honest values here, not placeholders waiting to be
277
+ filled. **`Related BR-IDs` is the exception — never force it to `none`.**
278
+ It reports what this change's own record carries, not what was synced, so it
279
+ takes the same values a BC-bearing host would: empty, or the per-family no-BR
280
+ marker when the T2 carries one. Writing `none` there erases the marker the
281
+ zero-phase shape requires (`references/finish-feature-flow.md` Step 5 states
282
+ the rule). A minimal host that genuinely touches a bounded context
283
+ reports that context and its real BR delta exactly as a phase-bearing feature
284
+ would — the zero is the **phase count**, not the significance.
285
+
212
286
  ### Concrete example
213
287
 
214
288
  ```bash
@@ -262,7 +336,7 @@ release.
262
336
  Example entry:
263
337
 
264
338
  ```markdown
265
- ## [1.2.3] — {YYYY-MM-DD}
339
+ ## [1.2.3] — {2026-04-21}
266
340
 
267
341
  ### Added
268
342
  - {SPEC-20260421-001}: ExpenseReport submission flow with Domain Events
@@ -276,6 +350,8 @@ Example entry:
276
350
 
277
351
  ---
278
352
 
353
+ <!-- dflow-generated: git-principles-canonical END -->
354
+
279
355
  ## 6. AI Collaboration Rules (Project Policy)
280
356
 
281
357
  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,15 +267,22 @@ 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)
233
277
 
234
278
  ### Before merging a feature branch to `main` (opening / merging the PR)
235
279
 
236
- - [ ] `/dflow:finish-feature` has run (or the equivalent Step 8.4
237
- manual archival is complete)
280
+ - [ ] **Closeout complete**: `/dflow:finish-feature` has announced closeout
281
+ complete for this host — its Local-closeout gate is satisfied (the
282
+ closeout commit landed and passed post-commit verification) and, if
283
+ the host carries `follow-up-of`, the Step 6 tracking commit has also
284
+ landed and been verified. `status: completed` or a directory already
285
+ under `completed/` does not show this on its own.
238
286
  - [ ] `_index.md` status = `completed`, feature directory moved to
239
287
  `dflow/specs/features/completed/` via `git mv`
240
288
  - [ ] BC layer synced: `dflow/specs/domain/{context}/rules.md`,
@@ -247,8 +295,25 @@ Before making key Git operations:
247
295
  - [ ] Domain unit tests pass (invariants + value object equality)
248
296
  - [ ] CI is green (all required checks passing)
249
297
 
298
+ > **Minimal (zero-phase) host.** The items about this host's own record —
299
+ > **Closeout complete**, `_index.md` status `completed`, and the archival
300
+ > move — apply **unchanged**: they are what stops a host merging with
301
+ > its record still open. Every item naming a **Domain or bounded-context
302
+ > artifact** applies only to what this change **actually touched**: a **no-BC**
303
+ > host has no context to sync or document, and a **T3** does no Domain work at
304
+ > all, so for those they read N/A. **Bounded-context-scoped only** —
305
+ > `glossary.md` and the tech-debt file belong to no bounded context, stay in a
306
+ > no-BC host's sweep, and are **not** N/A for it. **Code invariants are not
307
+ > artifacts** — the items here that state a rule about the **source** rather
308
+ > than name a document to update are **never N/A**: they hold for any change
309
+ > that touches code at all, and a host wrongly claiming to be no-BC is exactly
310
+ > what they catch. Record the N/A; do not create a context, a Domain document,
311
+ > or a BR row to tick a box.
312
+
250
313
  ---
251
314
 
315
+ <!-- dflow-generated: git-principles-canonical END -->
316
+
252
317
  ## 6. AI Collaboration Rules (Project Policy)
253
318
 
254
319
  Three categories:
@@ -298,6 +363,13 @@ can always decline. If your team also wants vendor attribution, appending the
298
363
  assistant's documented line (e.g. `Co-Authored-By: Claude
299
364
  <noreply@anthropic.com>`) is an independent, optional convention on top.
300
365
 
366
+ ### Merge strategy
367
+
368
+ Dflow does not choose this for you; § 3 lists the trade-offs. Record what this
369
+ project settled on:
370
+
371
+ **This project uses**: {Squash / Rebase / Fast-forward only — fill in}
372
+
301
373
  ---
302
374
 
303
375
  ## 7. Hotfixes under Trunk-based
@@ -313,10 +385,18 @@ There is no separate `hotfix/*` branch. A hotfix is:
313
385
  4. Deployed via the same pipeline as any other change
314
386
 
315
387
  **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.
388
+ upfront SDD cycle for speed. This project commits to documenting the fix
389
+ within **24 hours** after it lands. Run `/dflow:modify-existing` in
390
+ **post-hoc mode** (`references/modify-existing-flow.md` Step 1.8): it opens a
391
+ minimal host of its own for the fix, records the implementation checkpoint as
392
+ `reconciled ({merged-hotfix-hash})`, and reconciles rather than re-running work
393
+ that is already on the mainline.
394
+ What gets written is whatever the cascade's tier calls for — a **T2** lands a
395
+ lightweight spec (root cause + fix + a `dflow/specs/architecture/tech-debt.md` entry
396
+ if the bug reveals a systemic issue); a **T3** lands one `_index.md` Lightweight
397
+ Changes row and no spec file. Step 1.8 admits **T2 / T3 only**: a **T1**
398
+ post-hoc keeps the normal phase-bearing route and documents the merged work
399
+ there.
320
400
  This is a **human-to-human commitment** — Dflow / AI cannot track the
321
401
  24-hour clock; the team enforces it in retros.
322
402