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.
- package/CHANGELOG.md +96 -0
- package/README.en.md +73 -48
- package/README.md +46 -36
- package/TEMPLATE-COVERAGE.md +0 -1
- package/TEMPLATE-LANGUAGE-GLOSSARY.md +1 -0
- package/bin/dflow.js +7 -11
- package/docs/evaluating-dflow.en.md +11 -7
- package/docs/evaluating-dflow.md +9 -4
- package/docs/using-with-claude-code.en.md +40 -23
- package/docs/using-with-claude-code.md +34 -23
- package/docs/using-with-codex.en.md +125 -42
- package/docs/using-with-codex.md +93 -34
- package/docs/using-with-github-copilot.en.md +135 -34
- package/docs/using-with-github-copilot.md +120 -43
- package/docs/why-dflow.en.md +72 -0
- package/docs/why-dflow.md +72 -0
- package/lib/init.js +867 -214
- package/package.json +2 -2
- package/templates/brownfield/references/drift-verification.md +41 -10
- package/templates/brownfield/references/finish-feature-flow.md +3 -2
- package/templates/brownfield/references/git-integration.md +0 -1
- package/templates/brownfield/references/init-project-flow.md +31 -17
- package/templates/brownfield/references/modify-existing-flow.md +44 -38
- package/templates/brownfield/references/new-feature-flow.md +41 -11
- package/templates/brownfield/references/new-phase-flow.md +9 -2
- package/templates/brownfield/references/pr-review-checklist.md +7 -1
- package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +258 -29
- package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +5 -8
- package/templates/brownfield/scaffolding/_conventions.md +10 -9
- package/templates/brownfield/templates/_index.md +1 -1
- package/templates/brownfield/templates/context-map.md +12 -4
- package/templates/brownfield/templates/lightweight-spec.md +1 -1
- package/templates/brownfield/templates/phase-spec.md +1 -1
- package/templates/common/references/ddd-modeling-guide.md +643 -0
- package/templates/common/skill/SKILL.md +9 -6
- package/templates/greenfield/references/drift-verification.md +60 -15
- package/templates/greenfield/references/finish-feature-flow.md +3 -2
- package/templates/greenfield/references/git-integration.md +0 -1
- package/templates/greenfield/references/init-project-flow.md +31 -17
- package/templates/greenfield/references/modify-existing-flow.md +5 -7
- package/templates/greenfield/references/new-feature-flow.md +49 -19
- package/templates/greenfield/references/new-phase-flow.md +5 -2
- package/templates/greenfield/references/pr-review-checklist.md +9 -1
- package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +221 -29
- package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +10 -15
- package/templates/greenfield/scaffolding/Git-principles-trunk.md +1 -1
- package/templates/greenfield/scaffolding/_conventions.md +9 -8
- package/templates/greenfield/templates/_index.md +1 -1
- package/templates/greenfield/templates/aggregate-design.md +6 -0
- package/templates/greenfield/templates/context-map.md +13 -4
- package/templates/greenfield/templates/events.md +4 -1
- package/templates/greenfield/templates/lightweight-spec.md +1 -1
- package/templates/greenfield/templates/phase-spec.md +1 -1
- package/docs/migrating-to-dflow-v1.md +0 -230
- package/templates/brownfield/templates/CLAUDE.md +0 -165
- package/templates/greenfield/references/ddd-modeling-guide.md +0 -351
- 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.
|
|
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
|
|
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 (
|
|
11
|
+
### This command does (core + optional hygiene)
|
|
12
12
|
|
|
13
|
-
|
|
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
|
|
43
|
-
|
|
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`
|
|
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.
|
|
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
|
|
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 →
|
|
53
|
-
>
|
|
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
|
|
166
|
-
> never overwritten; Dflow
|
|
167
|
-
>
|
|
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
|
-
|
|
|
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` |
|
|
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
|
|
331
|
-
snippet under `dflow/specs/shared/` and
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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** (
|
|
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}/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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}/
|
|
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.
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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
|
|
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
|
-
- [ ] **
|
|
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:
|