dflow-sdd-ddd 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -0
- package/README.en.md +57 -43
- package/README.md +36 -33
- package/TEMPLATE-LANGUAGE-GLOSSARY.md +1 -0
- package/bin/dflow.js +4 -8
- package/docs/why-dflow.en.md +72 -0
- package/docs/why-dflow.md +72 -0
- package/lib/init.js +114 -77
- package/package.json +2 -2
- package/templates/brownfield/references/drift-verification.md +40 -6
- package/templates/brownfield/references/finish-feature-flow.md +85 -29
- package/templates/brownfield/references/git-integration.md +29 -9
- package/templates/brownfield/references/modify-existing-flow.md +61 -0
- package/templates/brownfield/references/new-feature-flow.md +62 -1
- package/templates/brownfield/references/new-phase-flow.md +19 -1
- package/templates/brownfield/references/pr-review-checklist.md +7 -1
- package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +46 -33
- package/templates/brownfield/scaffolding/Git-principles-gitflow.md +1 -1
- package/templates/brownfield/scaffolding/Git-principles-trunk.md +2 -2
- package/templates/brownfield/templates/_index.md +23 -4
- package/templates/brownfield/templates/context-map.md +12 -4
- package/templates/brownfield/templates/lightweight-spec.md +3 -3
- package/templates/brownfield/templates/phase-spec.md +3 -3
- package/templates/common/references/ddd-modeling-guide.md +837 -0
- package/templates/greenfield/references/drift-verification.md +60 -12
- package/templates/greenfield/references/finish-feature-flow.md +86 -29
- package/templates/greenfield/references/git-integration.md +29 -9
- package/templates/greenfield/references/modify-existing-flow.md +23 -0
- package/templates/greenfield/references/new-feature-flow.md +70 -8
- package/templates/greenfield/references/new-phase-flow.md +15 -1
- package/templates/greenfield/references/pr-review-checklist.md +9 -1
- package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +40 -33
- package/templates/greenfield/scaffolding/Git-principles-gitflow.md +1 -1
- package/templates/greenfield/scaffolding/Git-principles-trunk.md +4 -2
- package/templates/greenfield/templates/_index.md +23 -4
- package/templates/greenfield/templates/aggregate-design.md +8 -1
- package/templates/greenfield/templates/context-map.md +13 -4
- package/templates/greenfield/templates/events.md +5 -1
- package/templates/greenfield/templates/lightweight-spec.md +3 -3
- package/templates/greenfield/templates/phase-spec.md +3 -3
- package/docs/migrating-to-dflow-v1.md +0 -234
- package/templates/greenfield/references/ddd-modeling-guide.md +0 -351
|
@@ -37,9 +37,9 @@ main (or your project's base branch)
|
|
|
37
37
|
```
|
|
38
38
|
feature/{SPEC-ID}-{slug}
|
|
39
39
|
Examples:
|
|
40
|
-
feature/
|
|
41
|
-
feature/
|
|
42
|
-
feature/
|
|
40
|
+
feature/SPEC-20260424-001-jpy-currency-support
|
|
41
|
+
feature/SPEC-20260430-001-leave-approval-workflow
|
|
42
|
+
feature/SPEC-20260502-002-audit-logging
|
|
43
43
|
|
|
44
44
|
bugfix/{BUG-ID}-{slug}
|
|
45
45
|
Examples:
|
|
@@ -148,10 +148,30 @@ existing Step Gate prompt (it does not add a separate question):
|
|
|
148
148
|
Tier sets how many checkpoints a change has: T1 three (spec / implementation /
|
|
149
149
|
closeout), T2 two (spec+implementation merged / closeout), T3 a single commit.
|
|
150
150
|
Whether you choose Y or N, the AI records one row in the feature `_index.md`
|
|
151
|
-
Checkpoint Log
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
Checkpoint Log — every checkpoint is accounted for (`committed` / `skipped` /
|
|
152
|
+
`failed`), even when no commit happens. A commit hash is written only after the
|
|
153
|
+
commit succeeds; a hook rejection or failed commit is recorded as `failed`
|
|
154
|
+
(never a fake hash). **Exception — the closeout row**: the closeout commit
|
|
155
|
+
cannot contain its own hash, so the closeout row is written before the commit
|
|
156
|
+
as `closeout | committed` with **no hash** (see
|
|
157
|
+
`references/finish-feature-flow.md` Step 4); trace that commit via
|
|
158
|
+
`git log -1 -- dflow/specs/features/completed/{SPEC-ID}-{slug}` or the optional
|
|
159
|
+
`Dflow-Checkpoint` trailer below. After several consecutive skips in a project
|
|
160
|
+
the AI mentions you can turn checkpoints off in config — it does not turn them
|
|
161
|
+
off for you.
|
|
162
|
+
|
|
163
|
+
**Optional machine-greppable trailer.** Teams that want cross-flow checkpoint
|
|
164
|
+
accounting can append a commit trailer at checkpoint commits:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
Dflow-Checkpoint: {SPEC-ID} {spec|impl|closeout}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The `_index.md` Checkpoint Log **remains the source of truth**; the trailer is
|
|
171
|
+
a cheap derived mirror (`git log --grep 'Dflow-Checkpoint: {SPEC-ID}'`). Use
|
|
172
|
+
role names, not (k/N) counts — the checkpoint total can change mid-feature
|
|
173
|
+
(tier escalation, follow-ups), and a role gap ("impl exists but no closeout for
|
|
174
|
+
this SPEC-ID") is detectable without predicting N, even across flows.
|
|
155
175
|
|
|
156
176
|
### AI commits
|
|
157
177
|
|
|
@@ -325,8 +345,8 @@ Tie commits to specs:
|
|
|
325
345
|
[SPEC-ID] Short description
|
|
326
346
|
|
|
327
347
|
Examples:
|
|
328
|
-
[
|
|
329
|
-
[
|
|
348
|
+
[SPEC-20260424-001] Add JPY currency support to Money value object
|
|
349
|
+
[SPEC-20260424-001] Extract exchange rate logic to Domain service
|
|
330
350
|
[BUG-042] Fix rounding inconsistency, extract to Money.Round()
|
|
331
351
|
```
|
|
332
352
|
|
|
@@ -7,6 +7,8 @@ Step-by-step guide for when a developer triggers `/dflow:modify-existing` or `/d
|
|
|
7
7
|
- Step 4 → Step 5 (extraction decision → start implementation)
|
|
8
8
|
- Step 5 → Step 6 (implementation done → update artifacts)
|
|
9
9
|
|
|
10
|
+
Crossing any step gate above also updates the host feature's `_index.md` Resume Pointer cursor (Active Workflow / Current Step / Gates Passed / Awaiting) once the host feature directory exists — fold it into that gate's existing `_index.md` / Resume Pointer edit, no separate ceremony (see the `_index.md` template's Resume Pointer notes).
|
|
11
|
+
|
|
10
12
|
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
13
|
|
|
12
14
|
**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).
|
|
@@ -63,6 +65,16 @@ Walk through these in order:
|
|
|
63
65
|
this is a new concern. For T1, use `/dflow:new-feature`. For T2 / T3
|
|
64
66
|
on a standalone bug, see Step 1.5 — `/dflow:bug-fix` will create a
|
|
65
67
|
minimal feature directory to host the lightweight-spec.
|
|
68
|
+
4. **In-flight overlap scan (cross-branch)**: this branch's `active/` is not
|
|
69
|
+
everything in flight. Run the in-flight scan (classification and dedup
|
|
70
|
+
rules in `AI-AGENT-GUIDE.md` § Status / Control Commands) — `git fetch`
|
|
71
|
+
when the network allows, then
|
|
72
|
+
`git branch --all --list '*feature/*' --list '*bugfix/*'` — and also list
|
|
73
|
+
other unfinished features in this branch's `active/` (one cursor line
|
|
74
|
+
each). If a scanned branch classified as in flight elsewhere, closed out
|
|
75
|
+
awaiting integration, or unknown — or an unfinished feature — semantically
|
|
76
|
+
overlaps this change, surface it and wait for the developer to decide
|
|
77
|
+
before creating anything new (stale branches are non-blocking).
|
|
66
78
|
|
|
67
79
|
> **Why scan completed too?** Completed features are frozen history
|
|
68
80
|
> and **cannot accept** any T2 / T3 directly
|
|
@@ -282,8 +294,57 @@ Decision framework:
|
|
|
282
294
|
- **Extract now** if: the logic is being significantly modified anyway
|
|
283
295
|
- **Extract now** if: the logic is duplicated elsewhere and we need the single source of truth
|
|
284
296
|
- **Defer extraction** if: the change is a one-line fix and the surrounding code is too tangled
|
|
297
|
+
- **Consider not extracting at all** if: the context is `generic` (per the
|
|
298
|
+
context-map Subdomain Type) — a commodity capability's endgame is wholesale
|
|
299
|
+
replacement with an off-the-shelf package / service, so extracting its rules
|
|
300
|
+
one by one is wasted effort; record the replacement intent as the tech-debt
|
|
301
|
+
entry instead
|
|
285
302
|
- **Always record** the extraction opportunity in tech-debt.md even if deferring
|
|
286
303
|
|
|
304
|
+
If the target context has **no Subdomain Type** (not in `context-map.md`, or
|
|
305
|
+
the column is absent), ask the developer once to classify it. If they'd rather
|
|
306
|
+
not decide now, record it as an Open Question in the spec and run the
|
|
307
|
+
extraction decision on the framework above — do **not** assume `generic`.
|
|
308
|
+
|
|
309
|
+
**Aggregate emergence check.** Before extracting yet another rule onto an
|
|
310
|
+
existing concept, look at what has already accumulated on it (in `models.md` /
|
|
311
|
+
`rules.md`). The signal that it has stopped being a loose entity and is
|
|
312
|
+
becoming an **Aggregate Root with a consistency boundary**: **2+ non-trivial
|
|
313
|
+
state-transition rules on the same lifecycle identity, or any invariant that
|
|
314
|
+
must check / update multiple fields or child records atomically.** (A
|
|
315
|
+
*consistency boundary* means state that must hold or change **together,
|
|
316
|
+
atomically** — not mere relatedness: same screen, related nouns, or local
|
|
317
|
+
single-field input validation do **not** count.) When you see it, continuing
|
|
318
|
+
to extract rules one by one as T2 will leave the boundary undrawn — surface it
|
|
319
|
+
and **suggest escalating to T1** (`/dflow:new-phase` inside an active feature,
|
|
320
|
+
else `/dflow:new-feature`) to model the Aggregate deliberately: its invariants,
|
|
321
|
+
what must change atomically, what it protects. For *how* to model it —
|
|
322
|
+
invariant classification, set-based / uniqueness rules, aggregate sizing — read
|
|
323
|
+
`references/ddd-modeling-guide.md` (its **Edition note** maps each recording
|
|
324
|
+
surface to brownfield's `models.md` / `rules.md`). In `models.md`, **mark the
|
|
325
|
+
existing Entity row as the Aggregate Root and note the protected invariants /
|
|
326
|
+
atomic-change scope in its Responsibility / Notes** — brownfield `models.md`
|
|
327
|
+
has no separate Aggregates section, do not invent one; update the Repository
|
|
328
|
+
row if one exists. If the developer defers, **record the emergence observation
|
|
329
|
+
in `tech-debt.md`** so the boundary decision is not silently lost.
|
|
330
|
+
|
|
331
|
+
**Established-model re-read (the emergence check's mirror).** When the rule
|
|
332
|
+
you are extracting lands on an **already-modeled** Aggregate / concept,
|
|
333
|
+
re-read what was recorded when it was shaped (its `models.md` row + Notes
|
|
334
|
+
and the relevant `rules.md` entries) before extending it. If this change
|
|
335
|
+
matches a recorded re-evaluation condition ("revisit when …") or trips a
|
|
336
|
+
model-resistance signal, follow `references/ddd-modeling-guide.md`
|
|
337
|
+
§ "Revising an Established Model": record one short passage in the spec's
|
|
338
|
+
design decisions / open questions — proceed as-is, split, or rename, with
|
|
339
|
+
the reason. Deciding to keep the current model, recorded, is a valid
|
|
340
|
+
outcome; extending silently is not.
|
|
341
|
+
|
|
342
|
+
If the context is **`generic`** (Subdomain Type), emergence is usually a
|
|
343
|
+
*replacement / adapter-boundary* debt signal, not a cue for deep T1 modeling —
|
|
344
|
+
record the replacement intent (consistent with the generic extraction fallback
|
|
345
|
+
above) rather than escalating, unless the developer explicitly chooses to
|
|
346
|
+
model it.
|
|
347
|
+
|
|
287
348
|
### Generate Implementation Tasks List
|
|
288
349
|
|
|
289
350
|
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).
|
|
@@ -8,6 +8,8 @@ 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
|
+
Crossing any step gate above also updates the host feature's `_index.md` Resume Pointer cursor (Active Workflow / Current Step / Gates Passed / Awaiting) once the feature directory exists — fold it into that gate's existing `_index.md` / Resume Pointer edit, no separate ceremony (see the `_index.md` template's Resume Pointer notes).
|
|
12
|
+
|
|
11
13
|
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
14
|
|
|
13
15
|
**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).
|
|
@@ -30,6 +32,27 @@ Then check existing assets:
|
|
|
30
32
|
- Search `dflow/specs/features/` for related or overlapping features
|
|
31
33
|
- Check `dflow/specs/domain/glossary.md` for relevant terms
|
|
32
34
|
|
|
35
|
+
**In-flight overlap scan (cross-branch + other unfinished features)** — this
|
|
36
|
+
branch's `dflow/specs/` does not show everything in flight. Run the in-flight
|
|
37
|
+
scan (classification and dedup rules in `AI-AGENT-GUIDE.md` § Status / Control
|
|
38
|
+
Commands):
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
git fetch # when the network allows; skip gracefully offline
|
|
42
|
+
git branch --all --list '*feature/*' --list '*bugfix/*'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- List other unfinished features already in this branch's `active/` (one
|
|
46
|
+
cursor line each, from their `_index.md` Resume Pointer).
|
|
47
|
+
- Classify every listed branch by the guide's rules — in flight elsewhere /
|
|
48
|
+
closed out awaiting integration / stale (completed here) / unknown — do
|
|
49
|
+
not shortcut the classification. If a branch classified as **in flight
|
|
50
|
+
elsewhere, closed out awaiting integration, or unknown** has an ID / slug
|
|
51
|
+
that semantically overlaps this request, surface it and wait for the
|
|
52
|
+
developer to decide — continue there / integrate it first / treat as
|
|
53
|
+
related / unrelated — **before creating any new directory, spec, or
|
|
54
|
+
branch**. Only stale (completed here) branches are non-blocking.
|
|
55
|
+
|
|
33
56
|
Share what you found: "I see we already have [X] documented. This new feature seems to extend
|
|
34
57
|
that — is that right?"
|
|
35
58
|
|
|
@@ -50,6 +73,23 @@ If no matching context exists:
|
|
|
50
73
|
2. Create `dflow/specs/domain/{new-context}/context.md` using the context-definition template
|
|
51
74
|
3. Get developer confirmation before proceeding
|
|
52
75
|
|
|
76
|
+
Once the BC is confirmed, classify and record its **Subdomain Type** as part
|
|
77
|
+
of the same confirmation (not a separate gate):
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
"Is this capability core (差異化來源), supporting (必要但非差異化),
|
|
81
|
+
or generic (可買 / 可套件 / 簡單 CRUD)? I'll record it in context-map.md."
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
If the BC already has a Subdomain Type, reuse it — don't re-ask unless the
|
|
85
|
+
developer wants to reclassify. Record it in
|
|
86
|
+
`dflow/specs/domain/context-map.md`:
|
|
87
|
+
|
|
88
|
+
- If the file **does not exist** (the Brownfield track does not mandate it —
|
|
89
|
+
contexts emerge organically), create it from `templates/context-map.md`.
|
|
90
|
+
- If it exists but the **Subdomain Type column is missing**, add the column
|
|
91
|
+
**preserving every existing row** — do not rewrite their content.
|
|
92
|
+
|
|
53
93
|
**→ Transition (step-internal)**: Step 2 complete. Announce "Step 2 complete (BC identified). Entering Step 3: Domain Concept Discovery." and continue.
|
|
54
94
|
|
|
55
95
|
## Step 3: Domain Concept Discovery
|
|
@@ -62,6 +102,27 @@ Walk through these questions:
|
|
|
62
102
|
- **What are the states/statuses?** → State machines to model
|
|
63
103
|
- **What external data is needed?** → Interfaces to define
|
|
64
104
|
|
|
105
|
+
If one concept gathers rules / invariants that must hold together — **a state
|
|
106
|
+
machine over its lifecycle, or invariants spanning several of its fields /
|
|
107
|
+
child records** — treat it as a candidate **Aggregate Root** (a consistency
|
|
108
|
+
boundary = atomic, not mere relatedness), not just an Entity. Note its
|
|
109
|
+
invariants and what must change atomically against its `models.md` Entity row,
|
|
110
|
+
and confirm the boundary with the developer. (A state machine is one common
|
|
111
|
+
signal, not a prerequisite.) For the tactical patterns — invariant
|
|
112
|
+
classification, set-based / uniqueness rules, value objects, aggregate sizing —
|
|
113
|
+
read `references/ddd-modeling-guide.md` (its **Edition note** maps recording
|
|
114
|
+
surfaces to brownfield's `models.md` / `rules.md`).
|
|
115
|
+
|
|
116
|
+
The mirror case — the concept is **already modeled**: when extending an
|
|
117
|
+
existing Aggregate / modeled concept, re-read what was recorded when it was
|
|
118
|
+
shaped (its `models.md` row + Notes and the relevant `rules.md` entries)
|
|
119
|
+
before extending it. If this change matches a recorded re-evaluation
|
|
120
|
+
condition ("revisit when …") or trips a model-resistance signal, follow
|
|
121
|
+
`references/ddd-modeling-guide.md` § "Revising an Established Model":
|
|
122
|
+
record one short passage in the spec's design decisions / open questions —
|
|
123
|
+
proceed as-is, split, or rename, with the reason. Deciding to keep the
|
|
124
|
+
current model, recorded, is a valid outcome; extending silently is not.
|
|
125
|
+
|
|
65
126
|
For each new concept:
|
|
66
127
|
1. Check glossary — add if missing
|
|
67
128
|
2. Check if it already exists in models.md — extend if needed
|
|
@@ -142,7 +203,7 @@ dflow/specs/features/active/{SPEC-ID}-{slug}/
|
|
|
142
203
|
- Current BR Snapshot: initialise from the first phase's planned BRs
|
|
143
204
|
(will be refreshed when the phase-spec finalises)
|
|
144
205
|
- Lightweight Changes: empty table at start
|
|
145
|
-
- Resume Pointer: "phase-1 in progress: drafting phase-spec." / "Next Action: finish phase-spec, then implement."
|
|
206
|
+
- Resume Pointer: "phase-1 in progress: drafting phase-spec." / "Next Action: finish phase-spec, then implement." / cursor fields: Active Workflow `new-feature`, Current Step `Step 4 — write the spec`, Gates Passed `3→3.5`, Awaiting `none (mid-step)`
|
|
146
207
|
3. **Create the first phase-spec** at `phase-spec-{YYYY-MM-DD}-{slug}.md`
|
|
147
208
|
using `templates/phase-spec.md`. The "Delta from prior phases" section
|
|
148
209
|
is filled with "首 phase,無前置 Delta" (first phase has nothing to
|
|
@@ -19,6 +19,8 @@ adds a new phase to an in-progress feature only.
|
|
|
19
19
|
- Step 5 → Step 6 (`_index.md` refreshed → start implementation)
|
|
20
20
|
- Step 6 → Step 7 (implementation done → complete the phase)
|
|
21
21
|
|
|
22
|
+
Crossing any step gate above also updates the feature's `_index.md` Resume Pointer cursor (Active Workflow / Current Step / Gates Passed / Awaiting) — fold it into that gate's existing `_index.md` / Resume Pointer edit, no separate ceremony (see the `_index.md` template's Resume Pointer notes).
|
|
23
|
+
|
|
22
24
|
All other step transitions are **step-internal**: announce "Step N complete,
|
|
23
25
|
entering Step N+1" and proceed without waiting. See AI-AGENT-GUIDE.md § Workflow
|
|
24
26
|
Transparency for the full transparency protocol and confirmation signals.
|
|
@@ -63,6 +65,11 @@ AI must locate the target feature and load its current state:
|
|
|
63
65
|
- Read the most recent phase-spec to understand where the prior phase
|
|
64
66
|
left off (its Business Rules and Delta-from-prior-phases sections in
|
|
65
67
|
particular)
|
|
68
|
+
- Run the in-flight overlap scan (classification and dedup rules in
|
|
69
|
+
`AI-AGENT-GUIDE.md` § Status / Control Commands): list other unfinished
|
|
70
|
+
features in `active/` and any feature / bugfix branches whose work is
|
|
71
|
+
not visible on this branch — if the incoming phase scope overlaps one
|
|
72
|
+
of them, surface it before writing the phase-spec.
|
|
66
73
|
|
|
67
74
|
4. **Branch gate — ensure you are on this feature's branch (before any commit)**
|
|
68
75
|
|
|
@@ -92,7 +99,18 @@ Walk the developer through what the new phase covers:
|
|
|
92
99
|
BRs (ADDED), changed BRs (MODIFIED), removed BRs (REMOVED), renamed
|
|
93
100
|
(RENAMED). Items not mentioned stay UNCHANGED implicitly.
|
|
94
101
|
3. **Any Domain concepts introduced or changed?** New Entities / Value
|
|
95
|
-
Objects / Services touching `src/Domain/{context}/`?
|
|
102
|
+
Objects / Services touching `src/Domain/{context}/`? If this phase is an
|
|
103
|
+
**Aggregate-emergence escalation** (handed off from `/dflow:modify-existing`),
|
|
104
|
+
record the candidate Aggregate Root, the invariants it protects, and what
|
|
105
|
+
must change atomically — marking the Aggregate Root on its `models.md`
|
|
106
|
+
Entity row (no separate Aggregates section). For how to model it (invariant
|
|
107
|
+
classification, set-based / uniqueness rules, aggregate sizing), read
|
|
108
|
+
`references/ddd-modeling-guide.md` (its **Edition note** maps recording
|
|
109
|
+
surfaces to brownfield's `models.md` / `rules.md`). If the phase **extends
|
|
110
|
+
an already-modeled Aggregate / concept**, apply the established-model
|
|
111
|
+
re-read from `references/ddd-modeling-guide.md` § "Revising an Established
|
|
112
|
+
Model" (match recorded re-evaluation conditions; record proceed / split /
|
|
113
|
+
rename in the phase-spec).
|
|
96
114
|
4. **Data structure impact?** New tables, columns, indices?
|
|
97
115
|
5. **Why now?** Priority — informs sequencing relative to other phases.
|
|
98
116
|
|
|
@@ -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:
|
|
@@ -102,6 +102,12 @@ input like this (supporting files live in the workflow bundle at
|
|
|
102
102
|
`dflow/specs/features/backlog/` and suggest work based on migration value.
|
|
103
103
|
- **"I'm creating a branch"** → read `references/git-integration.md`; verify
|
|
104
104
|
branch naming and ensure a spec exists before coding starts.
|
|
105
|
+
- **"I'm designing a domain model" / "How should I model X?" / building or
|
|
106
|
+
reshaping an Aggregate** → read `references/ddd-modeling-guide.md` (DDD
|
|
107
|
+
tactical patterns: aggregates, invariants, value objects, domain events). It
|
|
108
|
+
is written with Greenfield artifact names; see its **Edition note** for where
|
|
109
|
+
Brownfield records the same decisions (`models.md` / `rules.md` /
|
|
110
|
+
`behavior.md` / `migration/tech-debt.md`).
|
|
105
111
|
- **"Dflow seems wrong" / "this template is confusing"** (or you notice Dflow
|
|
106
112
|
guidance drift) → suggest `/dflow:report-dflow-feedback`; never submit
|
|
107
113
|
anything upstream automatically.
|
|
@@ -112,10 +118,43 @@ input like this (supporting files live in the workflow bundle at
|
|
|
112
118
|
|
|
113
119
|
## Status / Control Commands
|
|
114
120
|
|
|
115
|
-
`/dflow:status` reports
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
`/dflow:status` reports in two parts.
|
|
122
|
+
|
|
123
|
+
**Part 1 — in-flight overview (always shown, workflow active or not).**
|
|
124
|
+
Aggregate every in-flight feature so unfinished work surfaces without anyone
|
|
125
|
+
remembering to look:
|
|
126
|
+
|
|
127
|
+
- Scan this branch's `dflow/specs/features/active/*/_index.md` and print one
|
|
128
|
+
line per feature: SPEC-ID / Active Workflow / Current Step / Awaiting / last
|
|
129
|
+
Checkpoint Log row (read from each Resume Pointer cursor).
|
|
130
|
+
- Cross-branch: run `git fetch` when the network allows (skip gracefully
|
|
131
|
+
offline), then `git branch --all --list '*feature/*' --list '*bugfix/*'`,
|
|
132
|
+
deduplicating local and remote refs of the same branch (prefer local). For
|
|
133
|
+
each branch, classify in order: (1) its feature directory exists in this
|
|
134
|
+
branch's `active/` → already covered above; (2) exists in this branch's
|
|
135
|
+
`completed/` → a stale undeleted branch — list as "completed; branch can be
|
|
136
|
+
deleted", **not** in-flight; (3)
|
|
137
|
+
`git show {branch}:dflow/specs/features/active/{dir}/_index.md` is readable
|
|
138
|
+
→ in flight on that branch, print its cursor line (no branch switching);
|
|
139
|
+
(4) the `completed/` path is readable on that branch → closed out there,
|
|
140
|
+
awaiting integration; (5) nothing readable → list the branch as unknown
|
|
141
|
+
state.
|
|
142
|
+
- If `features/backlog/` is non-empty, append one count line.
|
|
143
|
+
- Inherent limit: work never committed anywhere is invisible to any git scan.
|
|
144
|
+
|
|
145
|
+
**Part 2 — current feature detail (when a workflow is active).** Read the
|
|
146
|
+
Resume Pointer cursor as the **declared** state, then cross-check it against
|
|
147
|
+
derived evidence (Checkpoint Log, phase-spec statuses, recent git log). On
|
|
148
|
+
mismatch, report both sides explicitly and ask the developer to correct the
|
|
149
|
+
cursor — the cursor is a claim; evidence wins. If the cursor fields are absent
|
|
150
|
+
(an older `_index.md`), fall back to pure derivation. For readability you may
|
|
151
|
+
expand the cursor into a step checklist (done / in progress / not started)
|
|
152
|
+
derived live from the flow file — display only, never stored.
|
|
153
|
+
|
|
154
|
+
Include these fields: workflow, step, completed, in-progress, remaining,
|
|
155
|
+
pending decision, and next valid action. If no workflow is active, say so and
|
|
156
|
+
list valid flow-entry or standalone commands (Part 1 still shows the
|
|
157
|
+
in-flight overview).
|
|
119
158
|
|
|
120
159
|
`/dflow:next` is valid only at a step gate in an active workflow. Treat it as
|
|
121
160
|
developer confirmation equivalent to "OK" or "continue", then move to the next
|
|
@@ -123,7 +162,9 @@ workflow step.
|
|
|
123
162
|
|
|
124
163
|
`/dflow:cancel` aborts the current workflow and returns to free conversation.
|
|
125
164
|
Do not rollback changes, delete artifacts, or rewrite specs merely because the
|
|
126
|
-
workflow was cancelled.
|
|
165
|
+
workflow was cancelled. If the feature directory exists, set the Resume
|
|
166
|
+
Pointer cursor's Active Workflow to `none` (keep Current Progress as a trace
|
|
167
|
+
of where the cancellation happened).
|
|
127
168
|
|
|
128
169
|
When no workflow is active, `/dflow:next` and `/dflow:cancel` must report that
|
|
129
170
|
there is no active workflow to advance or cancel.
|
|
@@ -344,34 +385,6 @@ during the completion checklist, not via template section markers.
|
|
|
344
385
|
- Direct SQL in delivery/entrypoint code? → Record
|
|
345
386
|
- Magic numbers or undocumented statuses? → Record and add to glossary
|
|
346
387
|
|
|
347
|
-
## Pre-V1 Artifacts Detection
|
|
348
|
-
|
|
349
|
-
When working in a project that adopted Dflow before `dflow-sdd-ddd@0.1.0`,
|
|
350
|
-
you may encounter layout or naming patterns that predate the V1 baseline.
|
|
351
|
-
If any of the following appear, surface the observation to the developer
|
|
352
|
-
and recommend manual migration; do not rewrite anything silently.
|
|
353
|
-
|
|
354
|
-
Signals:
|
|
355
|
-
|
|
356
|
-
- Top-level `specs/` directory containing Dflow-shaped content (V1 layout
|
|
357
|
-
uses `dflow/specs/`).
|
|
358
|
-
- `_共用/` directory under `specs/` or `dflow/specs/` (V1 uses `shared/`).
|
|
359
|
-
- Section headings in Traditional Chinese where V1 templates render
|
|
360
|
-
canonical English; compare against `TEMPLATE-LANGUAGE-GLOSSARY.md` if
|
|
361
|
-
available.
|
|
362
|
-
- References to a runtime `/dflow:init-project` slash command (V1
|
|
363
|
-
replaced it with the Dflow CLI init command (`dflow init`, or
|
|
364
|
-
`npx dflow-sdd-ddd init` when using the no-install path)).
|
|
365
|
-
- A root `CLAUDE.md`, `AGENTS.md`, or equivalent that holds the full
|
|
366
|
-
Dflow workflow text instead of being a thin shim pointing to this
|
|
367
|
-
file.
|
|
368
|
-
- `dflow/specs/shared/_conventions.md` is missing the `> Dflow Version:`
|
|
369
|
-
front-matter line (V1 init writes it automatically).
|
|
370
|
-
|
|
371
|
-
Recommend `docs/migrating-to-dflow-v1.md` for the manual migration
|
|
372
|
-
checklist. Migration affects every spec the team has written; manual
|
|
373
|
-
review is required.
|
|
374
|
-
|
|
375
388
|
## Workflow Steps
|
|
376
389
|
|
|
377
390
|
This guide is the **command registry, routing rules, and project context**.
|
|
@@ -140,7 +140,7 @@ When applicable, prefix with a type (conventional commits-style):
|
|
|
140
140
|
| test | tests only |
|
|
141
141
|
| chore | build / tooling |
|
|
142
142
|
|
|
143
|
-
Example: `[
|
|
143
|
+
Example: `[SPEC-20260424-001] feat: add JPY currency support to Money VO`
|
|
144
144
|
|
|
145
145
|
---
|
|
146
146
|
|
|
@@ -95,8 +95,8 @@ adopted, the format is:
|
|
|
95
95
|
| test | tests only |
|
|
96
96
|
| chore | build / tooling |
|
|
97
97
|
|
|
98
|
-
Example: `feat(expense): add JPY currency support` with
|
|
99
|
-
the body.
|
|
98
|
+
Example: `feat(expense): add JPY currency support` with
|
|
99
|
+
`[SPEC-20260424-001]` in the body.
|
|
100
100
|
|
|
101
101
|
---
|
|
102
102
|
|
|
@@ -97,23 +97,42 @@ Template note (for AI):
|
|
|
97
97
|
> T3 單一 commit。
|
|
98
98
|
>
|
|
99
99
|
> commit hash 只在 commit 實際成功後填入;pre-commit hook reject 或 commit
|
|
100
|
-
> 失敗記 `failed`、不寫假 hash
|
|
100
|
+
> 失敗記 `failed`、不寫假 hash。**例外:closeout 列不填 hash**——closeout
|
|
101
|
+
> commit 無法自含自身 hash,該列於 commit 前寫入、隨歸檔目錄一起進 commit;
|
|
102
|
+
> 溯源用 `git log -1 -- completed/{SPEC-ID}-{slug}` 或選配的
|
|
103
|
+
> `Dflow-Checkpoint` trailer(見 references/git-integration.md)。
|
|
101
104
|
|
|
102
105
|
| Timestamp | Checkpoint | Result |
|
|
103
106
|
|---|---|---|
|
|
104
107
|
| {YYYY-MM-DD HH:MM} | spec-baseline | committed ({hash}) / skipped / failed |
|
|
105
108
|
| {YYYY-MM-DD HH:MM} | implementation | committed ({hash}) / skipped / failed |
|
|
106
|
-
| {YYYY-MM-DD HH:MM} | closeout | committed
|
|
109
|
+
| {YYYY-MM-DD HH:MM} | closeout | committed / skipped / failed |
|
|
107
110
|
|
|
108
111
|
## Resume Pointer
|
|
109
112
|
|
|
110
|
-
>
|
|
111
|
-
>
|
|
113
|
+
> 目前進展到哪?下一個動作是什麼?開新對話接續工作時,從這裡讀起。
|
|
114
|
+
>
|
|
115
|
+
> 下方四個 cursor 欄位是 workflow 進度的**存放層(宣告,claim)**:
|
|
116
|
+
> 進入 flow 時設 Active Workflow;**每過一個 step gate** 更新 Current Step /
|
|
117
|
+
> Gates Passed / Awaiting(與該 gate 既有的 `_index.md` 更新合併,不另加儀式);
|
|
118
|
+
> closeout / `/dflow:cancel` 時 Active Workflow 設回 `none`。
|
|
119
|
+
> `/dflow:status` 讀 cursor 後會與推導證據(Checkpoint Log、phase-spec
|
|
120
|
+
> status、git log)交叉,不一致會明確報 mismatch——cursor 是宣告、證據優先。
|
|
121
|
+
> Phase 粒度進度由上方 Phase Specs 表承載;cursor 只補 workflow step / gate
|
|
122
|
+
> 粒度,不展開成 per-step 全表(步驟線性,游標可推導每一步的完成/未做)。
|
|
112
123
|
|
|
113
124
|
**Current Progress**: {one-line summary}
|
|
114
125
|
|
|
115
126
|
**Next Action**: {suggested next action}
|
|
116
127
|
|
|
128
|
+
**Active Workflow**: {new-feature | modify-existing | bug-fix | new-phase | finish-feature | none}
|
|
129
|
+
|
|
130
|
+
**Current Step**: {Step N — short step name | n/a}
|
|
131
|
+
|
|
132
|
+
**Gates Passed**: {e.g. "3→3.5, 4→5" | n/a}
|
|
133
|
+
|
|
134
|
+
**Awaiting**: {step-gate description | none}
|
|
135
|
+
|
|
117
136
|
<!--
|
|
118
137
|
## Follow-up Tracking
|
|
119
138
|
>(選用段;只有當本 feature 衍生出 follow-up feature 時才填)
|
|
@@ -6,15 +6,23 @@
|
|
|
6
6
|
|
|
7
7
|
## Context List
|
|
8
8
|
|
|
9
|
-
| Bounded Context | Responsibility | Owner / Team | Primary Code Area | Notes |
|
|
10
|
-
|
|
11
|
-
| {Context name} | {業務責任} | {owner} | `{project/path/or/namespace}` | {optional notes} |
|
|
9
|
+
| Bounded Context | Responsibility | Subdomain Type | Owner / Team | Primary Code Area | Notes |
|
|
10
|
+
|---|---|---|---|---|---|
|
|
11
|
+
| {Context name} | {業務責任} | core / supporting / generic | {owner} | `{project/path/or/namespace}` | {optional notes} |
|
|
12
|
+
|
|
13
|
+
> **Subdomain Type** — 判別問句:「這塊功能換成現成 SaaS / 套件,系統的差異化會消失嗎?」
|
|
14
|
+
> (差異化不限商業競爭優勢;內部系統指獨特的營運優勢 / 任務成果。)會 → `core`;
|
|
15
|
+
> 不會、但需要為自家流程客製 → `supporting`(必要、常需客製、非差異化);
|
|
16
|
+
> 不會、且現成方案存在 → `generic`。多數 BC 是 supporting,`core` 通常只有 1–2 個;
|
|
17
|
+
> 全標 core = 沒分類。分類是可修訂的初判,改判時更新本欄並在 Notes 留一行理由。
|
|
18
|
+
> 它影響漸進抽離的取捨(`generic` 傾向整塊替換而非逐條抽離,見 modify-existing-flow
|
|
19
|
+
> Step 4),但**不**降低 BR 紀錄、Tier ceremony、或安全 / 測試 / 可靠性要求。
|
|
12
20
|
|
|
13
21
|
## Relationships
|
|
14
22
|
|
|
15
23
|
| Source Context | Target Context | Relationship Type | Integration Mechanism | Notes |
|
|
16
24
|
|---|---|---|---|---|
|
|
17
|
-
| {Source} | {Target} | {Customer/Supplier, Conformist, ACL, Shared Kernel, etc.} | {DB table, service call, file, manual process} | {optional notes} |
|
|
25
|
+
| {Source} | {Target} | {Customer/Supplier, Conformist, ACL, Shared Kernel, Separate Ways, Big Ball of Mud (BBoM), OHS, etc.} | {DB table, service call, file, manual process} | {optional notes} |
|
|
18
26
|
|
|
19
27
|
## Integration Notes
|
|
20
28
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
id: BUG-{NUMBER}
|
|
2
|
+
id: BUG-{NUMBER} # bug-type T2 only; a non-bug T2 (lightweight-{date}-{slug}.md) carries no id — the filename identifies it
|
|
3
3
|
title: {簡述問題}
|
|
4
|
-
status: in-progress
|
|
4
|
+
status: in-progress # in-progress | completed
|
|
5
5
|
bounded-context: {ContextName}
|
|
6
6
|
created: {YYYY-MM-DD}
|
|
7
|
-
branch: bugfix/BUG-{NUMBER}-{
|
|
7
|
+
branch: bugfix/BUG-{NUMBER}-{slug}
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
<!--
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
id: {
|
|
2
|
+
spec-id: SPEC-{YYYYMMDD}-{NNN} # the owning feature's SPEC-ID (matches the feature directory name)
|
|
3
3
|
title: Feature title
|
|
4
|
-
status:
|
|
4
|
+
status: in-progress # in-progress | completed
|
|
5
5
|
bounded-context: {ContextName}
|
|
6
6
|
created: {YYYY-MM-DD}
|
|
7
7
|
author: {developer-name}
|
|
8
|
-
branch: feature/{
|
|
8
|
+
branch: feature/{SPEC-ID}-{slug}
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# {Feature Title}
|