dflow-sdd-ddd 0.7.0 → 0.9.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 +73 -0
- package/LICENSE +679 -21
- package/README.en.md +5 -4
- package/README.md +3 -3
- package/bin/dflow.js +3 -2
- package/docs/evaluating-dflow.en.md +14 -5
- package/docs/evaluating-dflow.md +14 -5
- package/docs/using-with-claude-code.en.md +17 -9
- package/docs/using-with-claude-code.md +15 -8
- package/docs/using-with-codex.en.md +12 -8
- package/docs/using-with-codex.md +8 -6
- package/lib/init.js +480 -87
- package/package.json +2 -2
- package/templates/brownfield/references/dflow-feedback-flow.md +251 -0
- package/templates/brownfield/references/drift-verification.md +183 -0
- package/templates/brownfield/references/finish-feature-flow.md +294 -0
- package/templates/brownfield/references/git-integration.md +371 -0
- package/templates/brownfield/references/init-project-flow.md +430 -0
- package/templates/brownfield/references/modify-existing-flow.md +448 -0
- package/templates/brownfield/references/new-feature-flow.md +382 -0
- package/templates/brownfield/references/new-phase-flow.md +274 -0
- package/templates/brownfield/references/pr-review-checklist.md +179 -0
- package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +31 -4
- package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +12 -8
- package/templates/brownfield/scaffolding/Git-principles-gitflow.md +14 -13
- package/templates/brownfield/scaffolding/Git-principles-trunk.md +14 -17
- package/templates/brownfield/scaffolding/_conventions.md +1 -1
- package/templates/brownfield/scaffolding/_overview.md +3 -3
- package/templates/brownfield/templates/_index.md +20 -2
- package/templates/brownfield/templates/context-map.md +1 -1
- package/templates/brownfield/templates/glossary.md +1 -1
- package/templates/brownfield/templates/models.md +1 -1
- package/templates/brownfield/templates/rules.md +1 -1
- package/templates/brownfield/templates/tech-debt.md +1 -1
- package/templates/common/skill/SKILL.md +35 -0
- package/templates/greenfield/references/ddd-modeling-guide.md +351 -0
- package/templates/greenfield/references/dflow-feedback-flow.md +251 -0
- package/templates/greenfield/references/drift-verification.md +195 -0
- package/templates/greenfield/references/finish-feature-flow.md +314 -0
- package/templates/greenfield/references/git-integration.md +344 -0
- package/templates/greenfield/references/init-project-flow.md +464 -0
- package/templates/greenfield/references/modify-existing-flow.md +366 -0
- package/templates/greenfield/references/new-feature-flow.md +412 -0
- package/templates/greenfield/references/new-phase-flow.md +288 -0
- package/templates/greenfield/references/pr-review-checklist.md +130 -0
- package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +31 -4
- package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +15 -13
- package/templates/greenfield/scaffolding/Git-principles-gitflow.md +14 -13
- package/templates/greenfield/scaffolding/Git-principles-trunk.md +14 -18
- package/templates/greenfield/scaffolding/_conventions.md +1 -1
- package/templates/greenfield/scaffolding/_overview.md +5 -3
- package/templates/greenfield/scaffolding/architecture-decisions-README.md +1 -1
- package/templates/greenfield/templates/_index.md +20 -2
- package/templates/greenfield/templates/context-map.md +1 -1
- package/templates/greenfield/templates/events.md +1 -1
- package/templates/greenfield/templates/glossary.md +1 -1
- package/templates/greenfield/templates/models.md +1 -1
- package/templates/greenfield/templates/rules.md +1 -1
- package/templates/greenfield/templates/tech-debt.md +1 -1
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# Finish Feature Workflow
|
|
2
|
+
|
|
3
|
+
Step-by-step guide for when a developer triggers `/dflow:finish-feature` —
|
|
4
|
+
the feature closeout ceremony.
|
|
5
|
+
|
|
6
|
+
This command makes the previously-implicit closeout step (originally a
|
|
7
|
+
sub-step of `new-feature-flow` / `modify-existing-flow`) explicit and
|
|
8
|
+
directly callable. It validates that all phase-specs are completed,
|
|
9
|
+
syncs the feature-level BR Snapshot to the bounded context's system-level
|
|
10
|
+
state, archives the feature directory, and emits a Git-strategy-neutral
|
|
11
|
+
**Integration Summary** for the developer's PR / merge / push step.
|
|
12
|
+
|
|
13
|
+
**Important boundaries**:
|
|
14
|
+
- This command **does not auto-merge** and never pushes or opens a PR on its
|
|
15
|
+
own. Merge strategy follows the team's selected Git policy (`gitflow` /
|
|
16
|
+
`trunk`, recorded in `dflow/specs/shared/_conventions.md` § Git Policy).
|
|
17
|
+
- Closeout is split into two gates so it works offline: a **Local-closeout
|
|
18
|
+
gate** (Steps 1–4: validation, status flip, BC sync, archive + an optional
|
|
19
|
+
commit checkpoint — all doable with no network) and an **Integration / PR
|
|
20
|
+
gate** (Step 5: push / merge / PR — needs network; the AI only runs
|
|
21
|
+
`git push` / `gh pr create` when you explicitly ask).
|
|
22
|
+
- At the archive checkpoint the AI may offer to commit using your Git identity;
|
|
23
|
+
you can always decline. The commit marker mode is read from `_conventions.md`
|
|
24
|
+
§ AI Commit Policy. This replaces Dflow's earlier "the AI never commits"
|
|
25
|
+
stance — the AI helps at natural checkpoints, you keep the final say.
|
|
26
|
+
- The BC-layer sync in Step 3 **reuses the existing Step 8.3 mechanism**
|
|
27
|
+
from `new-feature-flow` — it does not introduce a new sync flow. Treat
|
|
28
|
+
it as "lift Step 8.3 out of the per-phase checklist and run it once at
|
|
29
|
+
feature closeout, with the `_index.md` Current BR Snapshot as input."
|
|
30
|
+
|
|
31
|
+
**Step Gates** in this flow (stop-and-confirm before proceeding):
|
|
32
|
+
- Step 1 → Step 2 (validation passed → flip status)
|
|
33
|
+
- Step 3 → Step 4 (BC sync done → archive)
|
|
34
|
+
- Step 5 → Step 6 (Integration Summary emitted → optional follow-up reverse-link)
|
|
35
|
+
|
|
36
|
+
All other step transitions are **step-internal**: announce "Step N complete,
|
|
37
|
+
entering Step N+1" and proceed without waiting. See SKILL.md § Workflow
|
|
38
|
+
Transparency for the full transparency protocol and confirmation signals.
|
|
39
|
+
|
|
40
|
+
## Step 1: Validate Phase Specs and `_index.md`
|
|
41
|
+
|
|
42
|
+
Before producing any closeout prose or Integration Summary text, read
|
|
43
|
+
`dflow/specs/shared/_conventions.md` and apply the `## Prose Language`
|
|
44
|
+
setting. If the setting is missing or not an explicit language tag, ask the
|
|
45
|
+
developer to update `_conventions.md` before continuing.
|
|
46
|
+
|
|
47
|
+
AI runs mechanical checks first. Report `✓` / `✗` for every item; if any
|
|
48
|
+
`✗` appears, **stop here** and ask the developer to address them before
|
|
49
|
+
proceeding (do not flip status, do not archive, do not emit summary).
|
|
50
|
+
|
|
51
|
+
- [ ] Locate the feature directory at `dflow/specs/features/active/{SPEC-ID}-{slug}/`
|
|
52
|
+
- [ ] `_index.md` exists and parses (YAML front matter intact, seven required
|
|
53
|
+
sections present, including the Checkpoint Log)
|
|
54
|
+
- [ ] Every row in `_index.md` Phase Specs table has Status = `completed`
|
|
55
|
+
- [ ] Every phase-spec file referenced in the Phase Specs table exists at
|
|
56
|
+
the path the table claims
|
|
57
|
+
- [ ] Every phase-spec file's frontmatter has `status: completed`
|
|
58
|
+
- [ ] `_index.md` has no obvious open items in Resume Pointer (e.g. "phase-N
|
|
59
|
+
drafting" / "implementation pending" / "TODO" markers)
|
|
60
|
+
- [ ] Current BR Snapshot table is non-empty (or feature is intentionally
|
|
61
|
+
a no-BR feature — confirm with developer if uncertain)
|
|
62
|
+
|
|
63
|
+
If any check fails:
|
|
64
|
+
> "Cannot finish feature `{SPEC-ID}-{slug}` yet — {N} validation issues
|
|
65
|
+
> found:
|
|
66
|
+
> ✗ phase-spec-2026-04-15-foo.md status is still `in-progress`
|
|
67
|
+
> ✗ Phase Specs table row 3 references missing file phase-spec-...
|
|
68
|
+
>
|
|
69
|
+
> Address these (run `/dflow:new-phase` to add missing work, or fix the
|
|
70
|
+
> stale status manually), then re-run `/dflow:finish-feature`."
|
|
71
|
+
|
|
72
|
+
**→ Step Gate: Step 1 → Step 2**
|
|
73
|
+
|
|
74
|
+
If all checks pass:
|
|
75
|
+
> "All {N} phase-specs are completed and `_index.md` is internally
|
|
76
|
+
> consistent. Ready to flip the feature status to `completed`?
|
|
77
|
+
> `/dflow:next` to proceed."
|
|
78
|
+
|
|
79
|
+
Wait for confirmation before entering Step 2.
|
|
80
|
+
|
|
81
|
+
## Step 2: Flip `_index.md` Status to `completed`
|
|
82
|
+
|
|
83
|
+
Update the feature's `_index.md` Metadata block:
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
---
|
|
87
|
+
spec-id: SPEC-{YYYYMMDD}-{NNN}
|
|
88
|
+
slug: {slug}
|
|
89
|
+
status: completed # ← flipped from in-progress
|
|
90
|
+
created: {YYYY-MM-DD}
|
|
91
|
+
branch: feature/{SPEC-ID}-{slug}
|
|
92
|
+
---
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Also update the **Resume Pointer** to reflect closeout:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
**Current Progress**: feature completed ({date}); all phase-specs status = completed.
|
|
99
|
+
**Next Action**: integration — push / merge / PR per the selected Git policy.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**→ Transition (step-internal)**: Step 2 complete. Announce "Step 2 complete (status flipped). Entering Step 3: Sync BR Snapshot to BC layer." and continue.
|
|
103
|
+
|
|
104
|
+
## Step 3: Sync `_index.md` Current BR Snapshot to BC Layer
|
|
105
|
+
|
|
106
|
+
This step **reuses the existing sync mechanism** from `new-feature-flow`
|
|
107
|
+
Step 8.3 (`dflow/specs/domain/{context}/rules.md` + `behavior.md` updates). The
|
|
108
|
+
input is the feature's `_index.md` Current BR Snapshot table; the output
|
|
109
|
+
is the BC's `rules.md` and `behavior.md` updated to reflect the
|
|
110
|
+
feature's net effect.
|
|
111
|
+
|
|
112
|
+
Before syncing, ensure required BC files exist. If missing, create from templates:
|
|
113
|
+
- `dflow/specs/domain/{context}/rules.md` → `templates/rules.md`
|
|
114
|
+
- `dflow/specs/domain/{context}/behavior.md` → `templates/behavior.md`
|
|
115
|
+
|
|
116
|
+
For each row in Current BR Snapshot where Status = `active`:
|
|
117
|
+
|
|
118
|
+
- If the BR-ID is **not yet in `rules.md`** → add it (new ADDED rule
|
|
119
|
+
introduced by this feature)
|
|
120
|
+
- If the BR-ID is **already in `rules.md`** but the rule text differs →
|
|
121
|
+
update it (MODIFIED rule, reflect the new text)
|
|
122
|
+
- If the BR-ID was previously in `rules.md` and is now in Current BR
|
|
123
|
+
Snapshot with Status = `removed` → remove the corresponding section in
|
|
124
|
+
`rules.md` (REMOVED rule)
|
|
125
|
+
- For any RENAMED BR-ID → rename the BR-ID in `rules.md` and update
|
|
126
|
+
`glossary.md` if the term itself changed
|
|
127
|
+
|
|
128
|
+
For `behavior.md`:
|
|
129
|
+
|
|
130
|
+
- For every BR-ID still active after this feature, ensure
|
|
131
|
+
`dflow/specs/domain/{context}/behavior.md` has a scenario section (anchor)
|
|
132
|
+
matching the BR-ID
|
|
133
|
+
- For REMOVED BR-IDs, delete the corresponding scenario section from
|
|
134
|
+
`behavior.md`
|
|
135
|
+
- Update the BR-ID anchor's `last-updated` date in `behavior.md` to today
|
|
136
|
+
|
|
137
|
+
This is the **mechanical input that `/dflow:verify` later uses** for the
|
|
138
|
+
rules.md ↔ behavior.md drift check (see `references/drift-verification.md`).
|
|
139
|
+
|
|
140
|
+
Cross-reference each phase-spec's Delta-from-prior-phases section to
|
|
141
|
+
double-check the net result; the Snapshot is the SSOT but the per-phase
|
|
142
|
+
Deltas are the audit trail.
|
|
143
|
+
|
|
144
|
+
> Note: this step does NOT read individual phase-specs to re-derive the BR
|
|
145
|
+
> set — that work was already reconciled by `/dflow:new-phase` Step 7 each
|
|
146
|
+
> time a phase completed. We trust `_index.md` Current BR Snapshot as the
|
|
147
|
+
> feature-level truth here. If the developer finds drift between Snapshot
|
|
148
|
+
> and the phase-specs, fix `_index.md` first, then re-run
|
|
149
|
+
> `/dflow:finish-feature`.
|
|
150
|
+
|
|
151
|
+
Also update `migration/tech-debt.md` / `models.md` / `glossary.md` as
|
|
152
|
+
discovered during the feature (the same items listed in
|
|
153
|
+
`new-feature-flow.md` Step 8.3) — these may have been touched per phase
|
|
154
|
+
already; this is the closeout sweep.
|
|
155
|
+
|
|
156
|
+
**→ Step Gate: Step 3 → Step 4**
|
|
157
|
+
|
|
158
|
+
> "BC `{context}` synced — `rules.md` updated ({n_added} added,
|
|
159
|
+
> {n_modified} modified, {n_removed} removed), `behavior.md` anchors
|
|
160
|
+
> updated, `last-updated` set to {date}. Ready to archive the feature
|
|
161
|
+
> directory? `/dflow:next` to proceed."
|
|
162
|
+
|
|
163
|
+
Wait for confirmation before entering Step 4.
|
|
164
|
+
|
|
165
|
+
## Step 4: Archive — `git mv` the Feature Directory
|
|
166
|
+
|
|
167
|
+
AI runs:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
git mv dflow/specs/features/active/{SPEC-ID}-{slug} \
|
|
171
|
+
dflow/specs/features/completed/{SPEC-ID}-{slug}
|
|
172
|
+
git status # confirm rename detection
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
`git mv` is mandatory — never use plain `mv` + `git add`. This preserves
|
|
176
|
+
git's directory rename detection so `git log --follow` / `git blame` /
|
|
177
|
+
PR diff quality stays intact across the move. See
|
|
178
|
+
`references/git-integration.md` § "Directory Moves Must Use git mv" for
|
|
179
|
+
the full rule set.
|
|
180
|
+
|
|
181
|
+
After the move, also `git add` any modified files from Step 3 (the
|
|
182
|
+
updated `rules.md`, `behavior.md`, `glossary.md`, `tech-debt.md`, etc.)
|
|
183
|
+
into the same stage.
|
|
184
|
+
|
|
185
|
+
**Closeout commit checkpoint** (completes the offline Local-closeout gate):
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
✓ Feature archived to completed/ and closeout files staged
|
|
189
|
+
Commit this closeout now?
|
|
190
|
+
[Y] Yes — the AI commits with your Git identity (marker per _conventions.md § AI Commit Policy)
|
|
191
|
+
[N] No — skip; you commit yourself
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Whether you choose Y or N, record one row in the feature `_index.md`
|
|
195
|
+
Checkpoint Log (`closeout | committed ({hash})` or `closeout | skipped`). Only
|
|
196
|
+
write a hash after the commit actually succeeds; if a pre-commit hook rejects it
|
|
197
|
+
or the commit fails, record `failed` and surface the error — never write a fake
|
|
198
|
+
hash.
|
|
199
|
+
|
|
200
|
+
The Local-closeout gate is satisfied **only when the closeout is committed**:
|
|
201
|
+
closeout complete, Checkpoint Log updated, and the working tree clean (no
|
|
202
|
+
uncommitted changes). If you declined the commit (chose N) or it failed,
|
|
203
|
+
Local-closeout is **not** satisfied yet — commit the staged closeout yourself
|
|
204
|
+
before continuing; do not enter the Integration / PR gate with uncommitted
|
|
205
|
+
changes. Once committed, the gate stands on its own offline; integration happens
|
|
206
|
+
in Step 5 when you have network.
|
|
207
|
+
|
|
208
|
+
**→ Transition (step-internal)**: Step 4 complete. Branch on whether the closeout commit landed:
|
|
209
|
+
|
|
210
|
+
- **Closeout commit landed (working tree clean)** → announce "Step 4 complete (feature archived; Local-closeout gate satisfied). Entering Step 5: Integration / PR gate." and continue.
|
|
211
|
+
- **Closeout commit was declined (N) or failed** → **stop here.** Announce "Step 4 complete (feature archived), but the Local-closeout gate is not satisfied yet — the closeout is staged but uncommitted. Commit those changes (or address the failure), then resume to Step 5." Do **not** enter Step 5 with uncommitted closeout changes.
|
|
212
|
+
|
|
213
|
+
## Step 5: Emit Integration Summary (Git-strategy-neutral)
|
|
214
|
+
|
|
215
|
+
Produce a plain-text summary of what this feature did. The summary is
|
|
216
|
+
**not** a commit message template — it is reference material the
|
|
217
|
+
developer adapts to whichever merge strategy their project uses
|
|
218
|
+
(merge commit, squash, rebase, fast-forward — Dflow stays neutral).
|
|
219
|
+
|
|
220
|
+
The selected Git policy's `Git-principles-{gitflow|trunk}.md` (seeded at init
|
|
221
|
+
under `dflow/specs/shared/`) explains, in its "Integration Commit Message
|
|
222
|
+
Conventions" section, how to format the actual commit / merge message from this
|
|
223
|
+
summary.
|
|
224
|
+
|
|
225
|
+
Format:
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
== Integration Summary: {SPEC-ID}-{slug} ==
|
|
229
|
+
|
|
230
|
+
Feature Goal: {1-2 sentences from _index.md Goals & Scope}
|
|
231
|
+
|
|
232
|
+
Change Scope:
|
|
233
|
+
- BC: {context-name}
|
|
234
|
+
- Phase Count: {N} (phase-spec-{date1}-{slug1} ... phase-spec-{dateN}-{slugN})
|
|
235
|
+
- Lightweight Changes: {n_t2} T2 lightweight specs + {n_t3} T3 inline rows
|
|
236
|
+
|
|
237
|
+
Related BR-IDs (post-closeout state):
|
|
238
|
+
- ADDED: BR-NN, BR-NN, ...
|
|
239
|
+
- MODIFIED: BR-NN, BR-NN, ...
|
|
240
|
+
- REMOVED: BR-NN, BR-NN, ...
|
|
241
|
+
|
|
242
|
+
Phase List:
|
|
243
|
+
- phase-1 ({date}): {phase-slug} — {1 line}
|
|
244
|
+
- phase-2 ({date}): {phase-slug} — {1 line}
|
|
245
|
+
- ...
|
|
246
|
+
|
|
247
|
+
Next Steps (developer) — Integration / PR gate (needs network):
|
|
248
|
+
- Per the selected Git policy (`gitflow` / `trunk` in `_conventions.md`), choose
|
|
249
|
+
a merge strategy (merge commit / squash / rebase / fast-forward) and execute
|
|
250
|
+
- Push to remote / open a PR — the AI can run `git push` / `gh pr create` for
|
|
251
|
+
you, but only when you explicitly ask; it never pushes on its own
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Print the summary to the conversation; do not write it to a file (it is
|
|
255
|
+
ephemeral closeout output).
|
|
256
|
+
|
|
257
|
+
**→ Step Gate: Step 5 → Step 6**
|
|
258
|
+
|
|
259
|
+
If the feature has `follow-up-of: {原 SPEC-ID}` in its Metadata, prompt
|
|
260
|
+
the developer:
|
|
261
|
+
> "This feature is a follow-up of `{原 SPEC-ID}`. Ready to update the
|
|
262
|
+
> original feature's `_index.md` Follow-up Tracking row to mark this
|
|
263
|
+
> follow-up as `completed`? `/dflow:next` to proceed (or skip if you
|
|
264
|
+
> prefer to do it manually)."
|
|
265
|
+
|
|
266
|
+
If no `follow-up-of` field, skip Step 6 and announce closeout complete:
|
|
267
|
+
> "`/dflow:finish-feature` complete for `{SPEC-ID}-{slug}`. Feature
|
|
268
|
+
> directory is now at `dflow/specs/features/completed/{SPEC-ID}-{slug}/`.
|
|
269
|
+
> If you skipped the closeout commit, commit the staged changes first to
|
|
270
|
+
> finish the Local-closeout gate. Then integration — merge / push / PR —
|
|
271
|
+
> follows the selected Git policy, at your discretion."
|
|
272
|
+
|
|
273
|
+
## Step 6: Reverse-Update Follow-up Tracking (only if follow-up)
|
|
274
|
+
|
|
275
|
+
For features that were created as follow-ups of an earlier completed
|
|
276
|
+
feature, update the original feature's
|
|
277
|
+
Follow-up Tracking table.
|
|
278
|
+
|
|
279
|
+
1. Locate `dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md`
|
|
280
|
+
2. Find the Follow-up Tracking section's row for this feature's SPEC-ID
|
|
281
|
+
3. Flip Status → `completed`
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# The AI makes the edit and may offer to commit it (Y / N), per the AI commit policy
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
After the update:
|
|
288
|
+
> "Follow-up Tracking row in `{原 SPEC-ID}-{原 slug}/_index.md` updated
|
|
289
|
+
> to Status = `completed`. Closeout complete."
|
|
290
|
+
|
|
291
|
+
The connection is bidirectional and weakly redundant: the new feature's
|
|
292
|
+
`follow-up-of` field is the authoritative source; the old feature's
|
|
293
|
+
Follow-up Tracking row is a derived index. If they ever disagree, trust
|
|
294
|
+
`follow-up-of`.
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# Git Integration with SDD/DDD
|
|
2
|
+
|
|
3
|
+
This reference defines the minimal Git coupling Dflow requires for SDD, and
|
|
4
|
+
what checks should happen at key branch transitions. Dflow is intentionally
|
|
5
|
+
agnostic about which Git *branching strategy* your project adopts (Git Flow,
|
|
6
|
+
GitHub Flow, trunk-based, single-`main`, etc.) — it only prescribes the
|
|
7
|
+
feature-branch-per-feature convention that SDD traceability depends on.
|
|
8
|
+
|
|
9
|
+
> Dflow does not pick `gitflow` vs `trunk` for you, but it now requires you to
|
|
10
|
+
> record one at `dflow init` so the runtime branch gate and finish-stage merge
|
|
11
|
+
> guidance can adapt. The selected policy's `Git-principles-{gitflow|trunk}.md`
|
|
12
|
+
> is seeded under `dflow/specs/shared/`.
|
|
13
|
+
|
|
14
|
+
## Branch-to-Workflow Mapping
|
|
15
|
+
|
|
16
|
+
Dflow only requires that every SDD feature / bug-fix lives on its own branch
|
|
17
|
+
that links back to a spec. The *base branch* that feature branches are cut
|
|
18
|
+
from (e.g. `main`, `develop`, `trunk`) is a project-level decision that Dflow
|
|
19
|
+
does not mandate.
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
main (or your project's base branch)
|
|
23
|
+
│
|
|
24
|
+
├─ feature/{SPEC-ID}-{slug} ← Full SDD workflow
|
|
25
|
+
│ Gate: spec must exist BEFORE first commit
|
|
26
|
+
│
|
|
27
|
+
└─ bugfix/{BUG-ID}-{slug} ← Lightweight SDD workflow
|
|
28
|
+
Gate: at minimum a lightweight spec
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> If your project adopts Git Flow / GitHub Flow / trunk-based, the choice of
|
|
32
|
+
> base branch (and whether you use `develop`, `release/*`, or a single `main`)
|
|
33
|
+
> is up to the project. Dflow does not decide this.
|
|
34
|
+
|
|
35
|
+
## Branch Naming Convention
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
feature/{SPEC-ID}-{slug}
|
|
39
|
+
Examples:
|
|
40
|
+
feature/EXP-001-jpy-currency-support
|
|
41
|
+
feature/HR-003-leave-approval-workflow
|
|
42
|
+
feature/SHARED-002-audit-logging
|
|
43
|
+
|
|
44
|
+
bugfix/{BUG-ID}-{slug}
|
|
45
|
+
Examples:
|
|
46
|
+
bugfix/BUG-042-rounding-inconsistency
|
|
47
|
+
bugfix/BUG-051-exchange-rate-cache
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The SPEC-ID / BUG-ID prefix links the branch to its spec document. This is
|
|
51
|
+
the traceability chain:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Git Branch → Spec Document → Domain Concepts → Code Implementation → Tests
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Slug Language
|
|
58
|
+
|
|
59
|
+
The branch slug follows the language the developer / AI discuss the
|
|
60
|
+
feature in. **Both Chinese and English slugs are valid**; Dflow does not
|
|
61
|
+
force translation in either direction. The same slug is reused for the
|
|
62
|
+
feature directory name and the first phase-spec filename, so consistency
|
|
63
|
+
across branch / dir / phase-spec is automatic.
|
|
64
|
+
|
|
65
|
+
Examples:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
feature/SPEC-20260421-001-報表調整 (Chinese discussion)
|
|
69
|
+
feature/SPEC-20260421-002-jpy-currency-support (English discussion)
|
|
70
|
+
feature/SPEC-20260423-003-訂單折扣-匯率擴充 (Chinese, hyphenated)
|
|
71
|
+
bugfix/BUG-051-rounding-fix (English)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Empirical note: an Obts production team has run Dflow with Chinese
|
|
75
|
+
branch / directory / PR titles in 2026-Q1–Q2 without encountering
|
|
76
|
+
encoding issues on common Git hosts (GitHub, Azure DevOps), CI runners,
|
|
77
|
+
or PR review bots. Other Git platforms may still need spot-checking;
|
|
78
|
+
when in doubt, run a smoke test on the project's CI pipeline with one
|
|
79
|
+
representative Chinese-slug branch before adopting it widely.
|
|
80
|
+
|
|
81
|
+
Slug-shape guidance (regardless of language):
|
|
82
|
+
- Keep it short (2–4 words / 2–6 中文字 plus separators)
|
|
83
|
+
- Avoid characters that break filesystems on contributors' platforms
|
|
84
|
+
(forward slash, backslash, colon, asterisk, question mark, double
|
|
85
|
+
quote, angle brackets, pipe)
|
|
86
|
+
- Avoid leading dots, trailing spaces
|
|
87
|
+
- Lowercase ASCII / 繁體中文 are both fine; mixed-case is OK but be
|
|
88
|
+
consistent within a project
|
|
89
|
+
|
|
90
|
+
## Feature Branch per Feature (Required)
|
|
91
|
+
|
|
92
|
+
This is the one non-negotiable Git coupling Dflow enforces:
|
|
93
|
+
|
|
94
|
+
- **Every SDD feature must have its own feature branch.** Branch name must
|
|
95
|
+
match its SPEC-ID so that `git log`, PR titles, and spec documents can be
|
|
96
|
+
traced back to one another.
|
|
97
|
+
- **Every bug-fix (SDD-tracked) must have its own bugfix branch** following
|
|
98
|
+
the same pattern.
|
|
99
|
+
- Commits that span multiple specs (accidentally or deliberately) are
|
|
100
|
+
discouraged; if you notice work on a new spec emerging mid-branch, stop
|
|
101
|
+
and create a new branch off the correct base.
|
|
102
|
+
|
|
103
|
+
This requirement is independent of the branching strategy — whether you
|
|
104
|
+
branch off `develop`, `main`, or something else, the feature-per-branch
|
|
105
|
+
convention stays.
|
|
106
|
+
|
|
107
|
+
## Commit Checkpoints, Branch Gate & AI Commits
|
|
108
|
+
|
|
109
|
+
Dflow actively helps keep the Git trace aligned with the workflow — the AI
|
|
110
|
+
reminds, can do the work, and leaves policy to the team.
|
|
111
|
+
|
|
112
|
+
### Branch gate
|
|
113
|
+
|
|
114
|
+
Before implementation starts (and before the first commit), the AI checks
|
|
115
|
+
whether the current branch is the feature / bugfix branch this work belongs to.
|
|
116
|
+
Both Git policies (`gitflow` / `trunk`, per `dflow/specs/shared/_conventions.md`
|
|
117
|
+
§ Git Policy) use a feature branch, so:
|
|
118
|
+
|
|
119
|
+
- **Already on the matching `feature/{SPEC-ID}-{slug}` (or
|
|
120
|
+
`bugfix/{BUG-ID}-{slug}`) branch** — e.g. continuing an active feature with
|
|
121
|
+
`new-phase`, `modify-existing`, or `bug-fix` — the gate is satisfied; nothing
|
|
122
|
+
is created or switched.
|
|
123
|
+
- **Not on this work's feature / bugfix branch** (you are on the base branch the
|
|
124
|
+
project cuts features from — `main` / `develop` / `trunk`, or whatever your
|
|
125
|
+
policy uses — or on an unrelated branch) — the AI offers to create and switch
|
|
126
|
+
to the correct branch, switch to an existing matching one, or override and
|
|
127
|
+
stay (recorded in the feature `_index.md` Checkpoint Log; three consecutive
|
|
128
|
+
overrides → the AI suggests re-running `dflow init`, never changing the
|
|
129
|
+
setting on its own).
|
|
130
|
+
|
|
131
|
+
Dflow does not need to identify your base branch to evaluate the gate — it only
|
|
132
|
+
checks whether you are on the right feature branch. The base branch matters only
|
|
133
|
+
when a new branch is actually created, and which base to cut from is your
|
|
134
|
+
project's decision (GitFlow → `develop`, Trunk / GitHub Flow → `main`).
|
|
135
|
+
|
|
136
|
+
### Commit checkpoints
|
|
137
|
+
|
|
138
|
+
At lifecycle milestones the AI offers a commit checkpoint, folded into the
|
|
139
|
+
existing Step Gate prompt (it does not add a separate question):
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
✓ {milestone} complete
|
|
143
|
+
Commit here?
|
|
144
|
+
[Y] Yes — the AI commits with your Git identity (marker per _conventions.md § AI Commit Policy)
|
|
145
|
+
[N] No — skip this checkpoint
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Tier sets how many checkpoints a change has: T1 three (spec / implementation /
|
|
149
|
+
closeout), T2 two (spec+implementation merged / closeout), T3 a single commit.
|
|
150
|
+
Whether you choose Y or N, the AI records one row in the feature `_index.md`
|
|
151
|
+
Checkpoint Log. A commit hash is written only after the commit succeeds; a hook
|
|
152
|
+
rejection or failed commit is recorded as `failed` (never a fake hash). After
|
|
153
|
+
several consecutive skips in a project the AI mentions you can turn checkpoints
|
|
154
|
+
off in config — it does not turn them off for you.
|
|
155
|
+
|
|
156
|
+
### AI commits
|
|
157
|
+
|
|
158
|
+
The AI may commit at these checkpoints using your Git identity; you can always
|
|
159
|
+
decline. How AI commits are marked is the `## AI Commit Policy` setting in
|
|
160
|
+
`_conventions.md` (`none` / `co-authored-by` / `prefix`), chosen once at init.
|
|
161
|
+
This is a deliberate reversal of Dflow's earlier "the AI never commits" stance:
|
|
162
|
+
the AI helps at natural break points, while merge / push / PR still follow the
|
|
163
|
+
team's policy and your explicit go-ahead.
|
|
164
|
+
|
|
165
|
+
## Directory Moves Must Use `git mv`
|
|
166
|
+
|
|
167
|
+
When you rename or move a directory or file that is tracked in Dflow
|
|
168
|
+
(feature directories, spec files, domain knowledge files, reference
|
|
169
|
+
files), **always use `git mv` instead of a plain `mv` + `git add`**.
|
|
170
|
+
|
|
171
|
+
### Why this is non-negotiable in Dflow
|
|
172
|
+
|
|
173
|
+
Dflow is intentionally tightly coupled to Git for the feature-branch /
|
|
174
|
+
feature-directory pairing (one feature = one branch = one directory).
|
|
175
|
+
This coupling means feature lifecycle events trigger directory moves,
|
|
176
|
+
and rename history is what makes the spec auditable across time.
|
|
177
|
+
|
|
178
|
+
A plain `mv` followed by `git add` shows up as `delete + add` in git's
|
|
179
|
+
diff. That breaks:
|
|
180
|
+
- `git log --follow {path}` (won't trace history across the move)
|
|
181
|
+
- `git blame` on lines that crossed the rename boundary
|
|
182
|
+
- PR diff quality (reviewers see two unrelated big-blob changes
|
|
183
|
+
instead of one rename + small content diff)
|
|
184
|
+
- `/dflow:verify` and other tools that walk feature history
|
|
185
|
+
|
|
186
|
+
This is a known weakness of OpenSpec's directory-rename pattern; Dflow
|
|
187
|
+
deliberately avoids it by mandating `git mv`.
|
|
188
|
+
|
|
189
|
+
### Where `git mv` is required
|
|
190
|
+
|
|
191
|
+
All of the following situations require `git mv`:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# 1. /dflow:finish-feature: archive an entire feature directory
|
|
195
|
+
git mv dflow/specs/features/active/{SPEC-ID}-{slug} \
|
|
196
|
+
dflow/specs/features/completed/{SPEC-ID}-{slug}
|
|
197
|
+
|
|
198
|
+
# 2. Slug correction (rare — done right after Step 3.5 if the developer
|
|
199
|
+
# realises the agreed slug needs a tweak)
|
|
200
|
+
git mv dflow/specs/features/active/{SPEC-ID}-{old-slug} \
|
|
201
|
+
dflow/specs/features/active/{SPEC-ID}-{new-slug}
|
|
202
|
+
|
|
203
|
+
# 3. Phase-spec rename inside a feature directory
|
|
204
|
+
# (e.g. fixing a wrong date in the filename)
|
|
205
|
+
git mv dflow/specs/features/active/{SPEC-ID}-{slug}/phase-spec-2026-04-23-foo.md \
|
|
206
|
+
dflow/specs/features/active/{SPEC-ID}-{slug}/phase-spec-2026-04-24-foo.md
|
|
207
|
+
|
|
208
|
+
# 4. Lightweight-spec rename inside a feature directory
|
|
209
|
+
git mv dflow/specs/features/active/{SPEC-ID}-{slug}/lightweight-2026-04-15-old.md \
|
|
210
|
+
dflow/specs/features/active/{SPEC-ID}-{slug}/lightweight-2026-04-15-new.md
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Commit-message hint for renames
|
|
214
|
+
|
|
215
|
+
When the rename is the primary action (not a rename + many edits),
|
|
216
|
+
prefer a commit message that calls it out:
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
[SPEC-ID] git mv {SPEC-ID}-{slug}: active/ → completed/
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
If the rename is bundled with content edits (e.g. archival commit also
|
|
223
|
+
updates `rules.md`), one commit is fine — git's rename detection still
|
|
224
|
+
holds via similarity index.
|
|
225
|
+
|
|
226
|
+
### What NOT to do
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# ❌ Wrong: produces delete + add, loses rename detection
|
|
230
|
+
mv dflow/specs/features/active/{SPEC-ID}-{slug} dflow/specs/features/completed/
|
|
231
|
+
git add -A
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# ❌ Also wrong: deleting the source then later adding the destination
|
|
236
|
+
# in a separate commit prevents git rename detection across commits.
|
|
237
|
+
git rm -r dflow/specs/features/active/{SPEC-ID}-{slug}
|
|
238
|
+
# ... commit ...
|
|
239
|
+
# ... later, add the destination: rename trail is now broken
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Verifying a rename took
|
|
243
|
+
|
|
244
|
+
After `git mv`, run `git status` — a successful rename shows:
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
Changes to be committed:
|
|
248
|
+
renamed: dflow/specs/features/active/{SPEC-ID}-{slug}/_index.md ->
|
|
249
|
+
dflow/specs/features/completed/{SPEC-ID}-{slug}/_index.md
|
|
250
|
+
...
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
If you see `deleted` + `new file` instead, the rename detection failed
|
|
254
|
+
— investigate before committing (most often, the file was edited
|
|
255
|
+
heavily enough that git's similarity index dropped below the rename
|
|
256
|
+
threshold; consider using `git mv` for the move, then making content
|
|
257
|
+
edits in a follow-up commit).
|
|
258
|
+
|
|
259
|
+
### CI / hook automation (future)
|
|
260
|
+
|
|
261
|
+
A pre-commit hook can refuse commits where `dflow/specs/features/active/` or
|
|
262
|
+
`dflow/specs/features/completed/` show paired `D` + `A` instead of `R` for
|
|
263
|
+
the same feature directory. Not part of Dflow today, but compatible
|
|
264
|
+
with the rule.
|
|
265
|
+
|
|
266
|
+
## Gate Checks by Branch Type
|
|
267
|
+
|
|
268
|
+
### feature/ branch — Before Creating
|
|
269
|
+
|
|
270
|
+
AI should verify:
|
|
271
|
+
- [ ] Feature directory exists at `dflow/specs/features/active/{SPEC-ID}-{slug}/`
|
|
272
|
+
with `_index.md` and at least one phase-spec inside
|
|
273
|
+
- [ ] `_index.md` has status: `in-progress`
|
|
274
|
+
- [ ] Bounded Context is identified
|
|
275
|
+
- [ ] At least one Given/When/Then scenario is defined in the first phase-spec
|
|
276
|
+
- [ ] Domain concepts are identified (even if not yet in models.md)
|
|
277
|
+
|
|
278
|
+
If any are missing, guide the developer through creating them BEFORE the branch.
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
"Before we create the branch, let's set up the spec.
|
|
282
|
+
I see this touches the Expense context. Let me help you draft the
|
|
283
|
+
spec — it should only take a few minutes and it'll keep us focused
|
|
284
|
+
during implementation."
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### feature/ branch — Before Merging (Pre-PR / Pre-Integration)
|
|
288
|
+
|
|
289
|
+
AI should verify:
|
|
290
|
+
- [ ] `_index.md` status updated to `completed`
|
|
291
|
+
- [ ] All `phase-spec-*.md` in the feature directory have `status: completed`
|
|
292
|
+
- [ ] `_index.md` Current BR Snapshot has been synced to BC layer
|
|
293
|
+
(`rules.md` / `behavior.md`) — typically by `/dflow:finish-feature`
|
|
294
|
+
- [ ] Whole feature directory ready to `git mv` to `dflow/specs/features/completed/`
|
|
295
|
+
(or already moved if `/dflow:finish-feature` ran)
|
|
296
|
+
- [ ] All new business logic is in `src/Domain/` (not delivery/entrypoint code — presentation/UI layer, controllers, handlers, jobs, message consumers, data pipelines, or stored procedures)
|
|
297
|
+
- [ ] New terms added to `glossary.md`
|
|
298
|
+
- [ ] `rules.md` and `models.md` updated if applicable
|
|
299
|
+
- [ ] Tech debt recorded for any shortcuts taken
|
|
300
|
+
- [ ] Domain layer code has no delivery-framework references
|
|
301
|
+
|
|
302
|
+
### bugfix/ branch — Before Creating
|
|
303
|
+
|
|
304
|
+
AI should verify:
|
|
305
|
+
- [ ] Lightweight spec exists or is created during this session
|
|
306
|
+
- [ ] Root cause is documented
|
|
307
|
+
- [ ] Fix approach is noted
|
|
308
|
+
|
|
309
|
+
### bugfix/ branch — Before Merging (Pre-PR / Pre-Integration)
|
|
310
|
+
|
|
311
|
+
- [ ] Spec has the fix documented
|
|
312
|
+
- [ ] Tech debt recorded if the underlying issue is broader (record in
|
|
313
|
+
`dflow/specs/migration/tech-debt.md` if the bug reveals a systemic issue)
|
|
314
|
+
- [ ] If business logic was touched, evaluate Domain extraction
|
|
315
|
+
|
|
316
|
+
> The exact merge strategy (merge commit, squash, rebase, fast-forward)
|
|
317
|
+
> follows the team's selected Git policy. See the seeded
|
|
318
|
+
> `Git-principles-{gitflow|trunk}.md` under `dflow/specs/shared/` for that
|
|
319
|
+
> policy's integration commit conventions.
|
|
320
|
+
|
|
321
|
+
## Commit Message Convention
|
|
322
|
+
|
|
323
|
+
Tie commits to specs:
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
[SPEC-ID] Short description
|
|
327
|
+
|
|
328
|
+
Examples:
|
|
329
|
+
[EXP-001] Add JPY currency support to Money value object
|
|
330
|
+
[EXP-001] Extract exchange rate logic to Domain service
|
|
331
|
+
[BUG-042] Fix rounding inconsistency, extract to Money.Round()
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Daily Development Flow
|
|
335
|
+
|
|
336
|
+
```
|
|
337
|
+
1. Developer: "I'm starting work on [feature/bug]"
|
|
338
|
+
AI: Check for spec → Guide through spec creation if missing
|
|
339
|
+
→ Suggest branch name based on spec ID
|
|
340
|
+
|
|
341
|
+
2. Developer creates branch
|
|
342
|
+
AI: Confirm branch name matches convention
|
|
343
|
+
→ Remind: "Business logic goes in src/Domain/"
|
|
344
|
+
|
|
345
|
+
3. During development
|
|
346
|
+
AI: Answer questions referencing dflow/specs/domain/ knowledge
|
|
347
|
+
→ Flag if business logic is going into delivery/entrypoint code
|
|
348
|
+
→ Suggest Domain layer patterns when appropriate
|
|
349
|
+
→ Help maintain thin delivery/entrypoint code
|
|
350
|
+
|
|
351
|
+
4. Before PR/merge
|
|
352
|
+
AI: Run through merge checklist
|
|
353
|
+
→ Help update specs, glossary, tech-debt
|
|
354
|
+
→ Suggest moving completed spec to completed/
|
|
355
|
+
|
|
356
|
+
5. After merge
|
|
357
|
+
AI: Confirm all artifacts are updated
|
|
358
|
+
→ Suggest next items from backlog/ if relevant
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Integration with CI/CD (Future Enhancement)
|
|
362
|
+
|
|
363
|
+
These checks could eventually be automated in CI:
|
|
364
|
+
- Verify no delivery-framework references in `src/Domain/` directory
|
|
365
|
+
- Verify spec file exists for any branch with feature/ or bugfix/ prefix
|
|
366
|
+
- Verify glossary.md and rules.md were updated when Domain/ files change
|
|
367
|
+
- Lint commit messages for spec ID format
|
|
368
|
+
|
|
369
|
+
For now, the AI handles these checks conversationally during development.
|
|
370
|
+
|
|
371
|
+
<!-- R8b verified: no Chinese structural terms in scope; per F-17 Path A. -->
|