dflow-sdd-ddd 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.md +915 -0
  2. package/CONTRIBUTING.md +11 -1
  3. package/README.en.md +160 -212
  4. package/README.md +93 -147
  5. package/TEMPLATE-COVERAGE.md +13 -6
  6. package/TEMPLATE-LANGUAGE-GLOSSARY.md +15 -1
  7. package/bin/dflow.js +90 -4
  8. package/docs/closeout-check.en.md +204 -0
  9. package/docs/closeout-check.md +204 -0
  10. package/docs/commands.en.md +112 -0
  11. package/docs/commands.md +103 -0
  12. package/docs/doctor-uncertainty.en.md +212 -0
  13. package/docs/doctor-uncertainty.md +212 -0
  14. package/docs/evaluating-dflow.en.md +29 -11
  15. package/docs/evaluating-dflow.md +8 -6
  16. package/docs/release-versioning-policy.md +6 -0
  17. package/docs/upgrading.en.md +196 -0
  18. package/docs/upgrading.md +197 -0
  19. package/docs/using-with-claude-code.en.md +13 -4
  20. package/docs/using-with-claude-code.md +13 -4
  21. package/docs/using-with-codex.en.md +13 -4
  22. package/docs/using-with-codex.md +13 -4
  23. package/docs/using-with-github-copilot.en.md +13 -4
  24. package/docs/using-with-github-copilot.md +13 -4
  25. package/lib/closeout-check.js +690 -0
  26. package/lib/doc-shapes.json +1195 -0
  27. package/lib/doctor-checks.js +2500 -24
  28. package/lib/init.js +2861 -143
  29. package/lib/render-diagrams.js +1474 -0
  30. package/lib/render.js +865 -49
  31. package/package.json +2 -2
  32. package/templates/brownfield/references/drift-verification.md +4 -0
  33. package/templates/brownfield/references/finish-feature-flow.md +648 -98
  34. package/templates/brownfield/references/finish-feature-follow-up.md +60 -0
  35. package/templates/brownfield/references/finish-feature-minimal-host.md +427 -0
  36. package/templates/brownfield/references/finish-feature-post-hoc-hotfix.md +95 -0
  37. package/templates/brownfield/references/finish-feature-record-correction.md +45 -0
  38. package/templates/brownfield/references/git-integration.md +205 -26
  39. package/templates/brownfield/references/init-project-flow.md +23 -3
  40. package/templates/brownfield/references/modify-existing-flow.md +439 -88
  41. package/templates/brownfield/references/modify-existing-follow-up.md +122 -0
  42. package/templates/brownfield/references/modify-existing-post-hoc-hotfix.md +200 -0
  43. package/templates/brownfield/references/new-feature-flow.md +110 -37
  44. package/templates/brownfield/references/new-phase-flow.md +59 -9
  45. package/templates/brownfield/references/pr-review-checklist.md +328 -10
  46. package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +151 -34
  47. package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +1 -1
  48. package/templates/brownfield/scaffolding/Git-principles-gitflow.md +85 -8
  49. package/templates/brownfield/scaffolding/Git-principles-trunk.md +88 -10
  50. package/templates/brownfield/scaffolding/_conventions.md +50 -28
  51. package/templates/brownfield/scaffolding/_overview.md +1 -0
  52. package/templates/brownfield/templates/_index.md +158 -10
  53. package/templates/brownfield/templates/analysis.md +79 -0
  54. package/templates/brownfield/templates/behavior.md +1 -0
  55. package/templates/brownfield/templates/context-definition.md +1 -0
  56. package/templates/brownfield/templates/context-map.md +2 -1
  57. package/templates/brownfield/templates/glossary.md +1 -0
  58. package/templates/brownfield/templates/lightweight-spec.md +154 -11
  59. package/templates/brownfield/templates/models.md +1 -0
  60. package/templates/brownfield/templates/phase-spec.md +9 -1
  61. package/templates/brownfield/templates/rules.md +1 -0
  62. package/templates/brownfield/templates/tech-debt.md +1 -0
  63. package/templates/common/references/ddd-modeling-guide.md +33 -16
  64. package/templates/{greenfield → common}/references/dflow-feedback-flow.md +2 -1
  65. package/templates/common/references/flow-rationale-registry.md +146 -0
  66. package/templates/common/skill/SKILL.md +13 -11
  67. package/templates/greenfield/references/drift-verification.md +4 -0
  68. package/templates/greenfield/references/finish-feature-flow.md +639 -100
  69. package/templates/greenfield/references/finish-feature-follow-up.md +60 -0
  70. package/templates/greenfield/references/finish-feature-minimal-host.md +383 -0
  71. package/templates/greenfield/references/finish-feature-post-hoc-hotfix.md +95 -0
  72. package/templates/greenfield/references/finish-feature-record-correction.md +45 -0
  73. package/templates/greenfield/references/git-integration.md +193 -26
  74. package/templates/greenfield/references/init-project-flow.md +23 -3
  75. package/templates/greenfield/references/modify-existing-flow.md +395 -87
  76. package/templates/greenfield/references/modify-existing-follow-up.md +104 -0
  77. package/templates/greenfield/references/modify-existing-post-hoc-hotfix.md +200 -0
  78. package/templates/greenfield/references/new-feature-flow.md +116 -35
  79. package/templates/greenfield/references/new-phase-flow.md +58 -9
  80. package/templates/greenfield/references/pr-review-checklist.md +311 -8
  81. package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +146 -32
  82. package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +5 -2
  83. package/templates/greenfield/scaffolding/Git-principles-gitflow.md +84 -8
  84. package/templates/greenfield/scaffolding/Git-principles-trunk.md +94 -14
  85. package/templates/greenfield/scaffolding/_conventions.md +50 -28
  86. package/templates/greenfield/scaffolding/_overview.md +6 -2
  87. package/templates/greenfield/templates/_index.md +145 -10
  88. package/templates/greenfield/templates/aggregate-design.md +1 -0
  89. package/templates/greenfield/templates/analysis.md +79 -0
  90. package/templates/greenfield/templates/behavior.md +1 -0
  91. package/templates/greenfield/templates/context-definition.md +1 -0
  92. package/templates/greenfield/templates/context-map.md +2 -1
  93. package/templates/greenfield/templates/events.md +4 -1
  94. package/templates/greenfield/templates/glossary.md +1 -0
  95. package/templates/greenfield/templates/lightweight-spec.md +154 -11
  96. package/templates/greenfield/templates/models.md +1 -0
  97. package/templates/greenfield/templates/phase-spec.md +9 -1
  98. package/templates/greenfield/templates/rules.md +1 -0
  99. package/templates/greenfield/templates/tech-debt.md +1 -0
  100. package/templates/brownfield/references/dflow-feedback-flow.md +0 -251
@@ -14,8 +14,12 @@ that SDD traceability depends on.
14
14
 
15
15
  ## Branch-to-Workflow Mapping
16
16
 
17
- Dflow only requires that every SDD feature / bug-fix lives on its own branch
18
- that links back to a spec. The *base branch* that feature branches are cut
17
+ Dflow only requires that SDD work is traceable from the branch it lands on. A
18
+ feature, and a defect that owns its own branch, each get a branch that links
19
+ back to what was recorded. Work picked up by a feature that is still in
20
+ progress stays on that host's branch — the host `_index.md` `branch:` field is
21
+ authoritative — and a T3 change is traced by its `_index.md` row, not by a spec
22
+ file of its own. The *base branch* that feature branches are cut
19
23
  from (e.g. `main`, `develop`, `trunk`) is a project-level decision that Dflow
20
24
  does not mandate.
21
25
 
@@ -25,8 +29,12 @@ main (or your project's base branch)
25
29
  ├─ feature/{SPEC-ID}-{slug} ← Full SDD + DDD workflow
26
30
  │ Gate: spec + Aggregate design before first commit
27
31
  │
28
- └─ bugfix/{BUG-ID}-{slug} ← Lightweight SDD workflow
29
- Gate: lightweight spec with layer identification
32
+ └─ bugfix/{BUG-ID}-{slug} ← a defect that owns its own branch
33
+ (a defect with no feature to host it opens a minimal zero-phase host
34
+ of its own — see references/modify-existing-flow.md Step 1.7)
35
+ Gate: whatever the cascade's tier calls for (T2: a lightweight
36
+ spec with layer identification; T3: the host _index.md row only;
37
+ T1: escalate — it belongs on a feature/ branch)
30
38
  ```
31
39
 
32
40
  > If your project adopts Git Flow / GitHub Flow / trunk-based, the choice of
@@ -61,7 +69,9 @@ The branch slug follows the language the developer / AI discuss the
61
69
  feature in. **Both Chinese and English slugs are valid**; Dflow does not
62
70
  force translation in either direction. The same slug is reused for the
63
71
  feature directory name and the first phase-spec filename, so consistency
64
- across branch / dir / phase-spec is automatic.
72
+ across branch / dir / phase-spec is automatic. A **minimal (zero-phase)
73
+ host** has no phase-spec, so its slug is shared by the branch and the
74
+ directory only — the absent third name is the host's shape, not drift.
65
75
 
66
76
  Examples:
67
77
 
@@ -95,8 +105,13 @@ This is the one non-negotiable Git coupling Dflow enforces:
95
105
  - **Every SDD feature must have its own feature branch.** Branch name must
96
106
  match its SPEC-ID so that `git log`, PR titles, and spec documents can be
97
107
  traced back to one another.
98
- - **Every bug-fix (SDD-tracked) must have its own bugfix branch** following
99
- the same pattern.
108
+ - **A defect that owns its own branch uses a `bugfix/` branch** following the
109
+ same pattern — including a standalone defect whose own minimal host is what
110
+ owns it, and whose branch therefore carries a BUG-NUMBER rather than that
111
+ host's SPEC-ID. A defect picked up by a feature that is still in progress is
112
+ hosted work instead: it stays on that host's branch. Either way the host
113
+ `_index.md` `branch:` field is authoritative — every spec inside that host,
114
+ and every branch gate applied to it, takes its value.
100
115
  - Commits that span multiple specs (accidentally or deliberately) are
101
116
  discouraged; if you notice work on a new spec emerging mid-branch, stop
102
117
  and create a new branch off the correct base.
@@ -125,9 +140,34 @@ Both Git policies (`gitflow` / `trunk`, per `dflow/specs/shared/_conventions.md`
125
140
  project cuts features from — `main` / `develop` / `trunk`, or whatever your
126
141
  policy uses — or on an unrelated branch) — the AI offers to create and switch
127
142
  to the correct branch, switch to an existing matching one, or override and
128
- stay (recorded in the feature `_index.md` Checkpoint Log; three consecutive
129
- overrides → the AI suggests re-running `dflow init`, never changing the
130
- setting on its own).
143
+ stay (three consecutive overrides → the AI suggests re-running `dflow init`,
144
+ never changing the setting on its own).
145
+
146
+ **How "override and stay" is recorded, so closeout can honour it.** Write one
147
+ row in the feature `_index.md` Checkpoint Log:
148
+
149
+ | Timestamp | Checkpoint | Result |
150
+ |---|---|---|
151
+ | {YYYY-MM-DD HH:MM} | `branch-override` | `override ({branch-you-stayed-on})` |
152
+
153
+ The Result **names the branch you stayed on** — not the value of `branch:`,
154
+ which stays exactly as the host opened it. That name is what makes the record
155
+ usable, and it is exactly what closeout reads: **its branch check passes when
156
+ *any* `branch-override` row on this host names the branch `HEAD` is on** — not
157
+ only the most recent one, because a host may override onto different branches
158
+ in different phases and closeout fires no branch gate of its own, so it never
159
+ writes a newer row. A record that does not say *where* you stayed excuses
160
+ nothing.
161
+ ⚠ **This row is a record, not a lifecycle checkpoint.** It is not a commit and
162
+ it does not count toward the tier's checkpoint count.
163
+ ⚠ **Where it can appear at all: only on a phase-bearing host.**
164
+ `references/modify-existing-flow.md` withholds this override from every
165
+ **minimal host** (Step 1.6's follow-up variant, Step 1.7 standalone, Step 1.8
166
+ post-hoc), because those hosts assert branch equality against a `branch:` they
167
+ cut by change class. So `references/finish-feature-flow.md`'s closeout branch
168
+ check reads this row and honours it, while its minimal-host checkpoint count
169
+ is never looking at one — that count says so at the site rather than carrying
170
+ an exclusion for a row that cannot reach it.
131
171
 
132
172
  Dflow does not need to identify your base branch to evaluate the gate — it only
133
173
  checks whether you are on the right feature branch. The base branch matters only
@@ -137,7 +177,8 @@ project's decision (GitFlow → `develop`, Trunk / GitHub Flow → `main`).
137
177
  ### Commit checkpoints
138
178
 
139
179
  At lifecycle milestones the AI offers a commit checkpoint, folded into the
140
- existing Step Gate prompt (it does not add a separate question):
180
+ prompt the flow already shows there — a Step Gate, or the flow's closing
181
+ announcement (it does not add a separate question):
141
182
 
142
183
  ```
143
184
  ✓ {milestone} complete
@@ -148,12 +189,46 @@ existing Step Gate prompt (it does not add a separate question):
148
189
 
149
190
  Tier sets how many checkpoints a change has: T1 three (spec / implementation /
150
191
  closeout), T2 two (spec+implementation merged / closeout), T3 a single commit.
192
+ **What a checkpoint carries follows from where its flow offers it.**
193
+ `references/modify-existing-flow.md` offers its checkpoint at the end of its
194
+ artifact step (Step 5), so a T2's merged commit — and a T3's single commit —
195
+ carries the change together with the documentation that step writes.
196
+ `/dflow:new-feature` and `/dflow:new-phase` offer the implementation checkpoint
197
+ at the gate into their completion step, so what that step writes rides the
198
+ host's next commit, whichever that is — for example the next phase's first
199
+ checkpoint, a hosted lightweight change's commit, or closeout.
200
+ "T3 = a single commit" means a single **implementation** commit. On a hosted T3
201
+ the entries that carry its hash ride the host's **next** commit (more work, or
202
+ closeout), as every checkpoint's do (below). If the host has no next commit
203
+ scheduled, one ledger-only tracking commit that references the T3 hash is
204
+ allowed. It is bookkeeping, not a lifecycle milestone: it adds no Checkpoint Log
205
+ row of its own (unlike closeout, which is a checkpoint and does get a row).
206
+ **Minimal host (zero-phase) exception — there, tier does not set the count.**
207
+ On a minimal host (`references/modify-existing-flow.md` Step 1.7 standalone, or
208
+ its Step 1.6 follow-up minimal variant) there is no later host commit for a row
209
+ to ride, so the count is **two for every tier** — implementation, then closeout
210
+ — and every row, a T3's included, is written into checkpoint 1 itself; only the
211
+ entries that carry checkpoint 1's hash ride the closeout commit. Everything
212
+ above about "T3 = a single commit" describes a **hosted** T3, the case where a
213
+ later host commit exists.
151
214
  Whether you choose Y or N, the AI records one row in the feature `_index.md`
152
215
  Checkpoint Log — every checkpoint is accounted for (`committed` / `skipped` /
153
- `failed`), even when no commit happens. A commit hash is written only after the
154
- commit succeeds; a hook rejection or failed commit is recorded as `failed`
155
- (never a fake hash). **Exception — the closeout row**: the closeout commit
156
- cannot contain its own hash, so the closeout row is written before the commit
216
+ `failed`), even when no commit happens.
217
+ **No checkpoint commit can contain its own hash.** The entries that carry a
218
+ checkpoint's hash — its Checkpoint Log Result `committed ({hash})`, and any
219
+ Lightweight Changes `Commit` cell holding that hash — are written after the
220
+ commit succeeds and ride the host's **next** commit. A hook rejection or failed
221
+ commit is recorded as `failed` (never a fake hash).
222
+ **One further Result value — `reconciled ({merged-hotfix-hash})`.** It records
223
+ that this checkpoint documents a change that was **already merged** before any
224
+ ceremony ran, and it is written only on a post-hoc hotfix host's implementation
225
+ row (`references/modify-existing-flow.md` Step 1.8). The hash in the parentheses
226
+ belongs to the **merged hotfix**, not to this host's own documentation commit —
227
+ that one goes in the Lightweight Changes row's `Commit` cell, and the two have
228
+ different provenance and must never be swapped. On every other host the three
229
+ values above are the whole vocabulary.
230
+ **Exception — the closeout row**: no later commit of this host's lifecycle
231
+ carries it, so the closeout row is written before the commit
157
232
  as `closeout | committed` with **no hash** (see
158
233
  `references/finish-feature-flow.md` Step 4); trace that commit via
159
234
  `git log -1 -- dflow/specs/features/completed/{SPEC-ID}-{slug}` or the optional
@@ -276,16 +351,35 @@ heavily enough that git's similarity index dropped below the rename
276
351
  threshold; consider using `git mv` for the move, then making content
277
352
  edits in a follow-up commit).
278
353
 
279
- ### CI / hook automation (future)
354
+ ### CI / hook automation
280
355
 
281
- A pre-commit hook can refuse commits where `dflow/specs/features/active/` or
282
- `dflow/specs/features/completed/` show paired `D` + `A` instead of `R` for
283
- the same feature directory. Not part of Dflow today, but compatible
284
- with the rule.
356
+ Dflow ships `dflow check-closeout`, a gate for the closeout commit. For each
357
+ feature directory newly archived to `dflow/specs/features/completed/` it checks
358
+ that `_index.md` and every spec say `status: completed`, that nothing is left
359
+ under `active/`, that the Checkpoint Log has a real `closeout` row reading
360
+ `committed` or `skipped`, and — with `--staged` — that nothing under the
361
+ archived directory is left unstaged; it exits 1 when one fails. A project wires
362
+ it into a pre-commit hook (`--staged`) or a CI job (`--range <base>..<head>`)
363
+ itself — Dflow installs neither. `dflow check-closeout --help` names the page
364
+ with the hook and CI templates. When the hook refuses a closeout commit, handle
365
+ it as `references/finish-feature-flow.md` Step 4 instruction 3 says.
366
+
367
+ Passing it is not a clean closeout: the post-commit verification in
368
+ `references/finish-feature-flow.md` Step 4 still applies in full.
369
+
370
+ A hook that refuses paired `D` + `A` instead of `R` for the same feature
371
+ directory is compatible with the `git mv` rule, but it is not part of
372
+ `check-closeout`.
285
373
 
286
374
  ## Gate Checks by Branch Type
287
375
 
288
376
  ### feature/ — Before Creating
377
+
378
+ This is the **phase-bearing** (T1) list. A **minimal (zero-phase) host** cuts a
379
+ `feature/{SPEC-ID}-{slug}` branch too and takes the short list under it: it has
380
+ no phase-spec *by definition*, so every item that reads one is not merely unmet
381
+ but unmeetable, and demanding them would block the change the branch exists for.
382
+
289
383
  - [ ] Feature directory exists at `dflow/specs/features/active/{SPEC-ID}-{slug}/`
290
384
  with `_index.md` and at least one phase-spec inside
291
385
  - [ ] `_index.md` status: `in-progress`
@@ -294,14 +388,33 @@ with the rule.
294
388
  - [ ] Domain Events identified
295
389
  - [ ] At least one Given/When/Then scenario in the first phase-spec
296
390
 
391
+ **Minimal (zero-phase) host — this list instead**
392
+ (any route in `references/modify-existing-flow.md` that opens a zero-phase host
393
+ — Step 1.7 standalone, Step 1.6's follow-up variant, Step 1.8's post-hoc
394
+ hotfix, or one added later):
395
+ - [ ] Feature directory exists at `dflow/specs/features/active/{SPEC-ID}-{slug}/`
396
+ with a minimal `_index.md` — all seven sections, Phase Specs table
397
+ **empty**, and no `phase-spec-*` file
398
+ - [ ] `_index.md` status: `in-progress`, and its `branch:` equals the branch
399
+ being cut — that field is authoritative for everything in this host
400
+ - [ ] The tier's artifact is ready to be written into the first commit: a
401
+ lightweight-spec for a **T2**, a Lightweight Changes row for a **T3** —
402
+ in both cases with its implementation paths declared
403
+ - [ ] Bounded Context identified **only if this change has one**; a no-BC host
404
+ records `none` and must not acquire a context to pass this gate
405
+
297
406
  ### feature/ — Before Merging (Pre-PR / Pre-Integration)
298
407
  - [ ] `_index.md` status: completed
299
408
  - [ ] All `phase-spec-*.md` in the feature directory have `status: completed`
300
409
  - [ ] `_index.md` Current BR Snapshot has been synced to BC layer
301
410
  (`rules.md` / `behavior.md` / `events.md` / `context-map.md`) —
302
411
  typically by `/dflow:finish-feature`
303
- - [ ] Whole feature directory ready to `git mv` to `dflow/specs/features/completed/`
304
- (or already moved if `/dflow:finish-feature` ran)
412
+ - [ ] **Closeout complete**: `/dflow:finish-feature` has announced closeout
413
+ complete for this host — its Local-closeout gate is satisfied (the
414
+ closeout commit landed and passed post-commit verification) and, if
415
+ the host carries `follow-up-of`, the Step 6 tracking commit has also
416
+ landed and been verified. `status: completed` or a directory already
417
+ under `completed/` does not show this on its own.
305
418
  - [ ] Domain layer: zero external dependencies
306
419
  - [ ] No business logic outside Domain layer
307
420
  - [ ] Domain Events documented in events.md
@@ -309,13 +422,67 @@ with the rule.
309
422
  - [ ] Domain unit tests pass
310
423
  - [ ] No ORM/serialization attributes on Domain entities
311
424
 
425
+ > **On a minimal (zero-phase) host**, split this list by what each item reads.
426
+ > Items about **this host's own record** — `_index.md` status, **Closeout
427
+ > complete**, and the phase-spec check, which passes vacuously on an empty
428
+ > table — apply **unchanged**: they are what stops a host merging with its
429
+ > record still open. Every item that names a **Domain or bounded-context
430
+ > artifact**, the BR-Snapshot sync included, applies only to what this change
431
+ > **actually touched**: a **no-BC** host has no bounded context to sync or
432
+ > document, and a **T3** does no Domain work at all, so for those they read
433
+ > N/A. **Bounded-context-scoped only** — `glossary.md` and the tech-debt file
434
+ > belong to no bounded context, stay in a no-BC host's sweep, and are **not**
435
+ > N/A for it (closeout draws the same line). **Code invariants are not
436
+ > artifacts** — the items here that state a rule about the **source** rather
437
+ > than name a document to update are **never N/A**: they hold for any change
438
+ > that touches code at all, and a host wrongly claiming to be no-BC is exactly
439
+ > what they catch. Record the N/A — do not invent a context, a Domain document,
440
+ > an event, or a BR row to tick one.
441
+
312
442
  ### bugfix/ — Before Creating
313
- - [ ] Lightweight spec exists or is created during this session
314
- - [ ] Root cause is documented
443
+
444
+ > **A `bugfix/` branch is always a minimal (zero-phase) host**, so the
445
+ > minimal-host list above applies here **in full** — the `_index.md` shape, the
446
+ > authoritative `branch:` field, and the artifact's declaration of the paths it
447
+ > touches, which is what closeout blocks on. Every route that cuts one opens the
448
+ > host through `references/modify-existing-flow.md` **Step 1.7's mechanics** —
449
+ > its own numbered **step 4**, "Branch gate — by change class". The known routes
450
+ > are Step 1.7 directly, Step 1.6's minimal follow-up variant, and Step 1.8's
451
+ > post-hoc hotfix; the latter two delegate to that same step (steps 2–4), and a
452
+ > route added later reaches it the same way.
453
+ > Not the top-level `## Step 4`, which cuts no branch. A **T1**
454
+ > escalates to `feature/`, and a defect hosted under a phase-bearing feature
455
+ > never gets a branch of its own. This matters because a functional bug walks
456
+ > **this** gate and never the `feature/` one. The items below are what
457
+ > `bugfix/` adds on top.
458
+
459
+ - [ ] **The tier's artifact** exists or is created during this session — a
460
+ **lightweight spec** for a T2; for a **T3**, the host `_index.md`
461
+ Lightweight Changes row and *no* spec file, exactly as the branch map
462
+ above says. A T3 spec file does not exist in Dflow, so asking for one
463
+ blocks the change instead of documenting it. A **T1** does not belong on
464
+ a `bugfix/` branch — escalate it to `feature/`.
465
+ - [ ] Root cause is documented — a T2's `## Root Cause`, or the evidence
466
+ section its no-BR family substitutes for it; for a **T3** the row
467
+ Description is the whole record and there is no separate root-cause
468
+ artifact
315
469
  - [ ] Fix approach is noted (which layer the fix belongs in)
316
470
 
317
471
  ### bugfix/ — Before Merging (Pre-PR / Pre-Integration)
318
- - [ ] Spec has the fix documented
472
+ - [ ] `_index.md` status: `completed`
473
+ - [ ] **Closeout complete**: `/dflow:finish-feature` has announced closeout
474
+ complete for this host — its Local-closeout gate is satisfied (the
475
+ closeout commit landed and passed post-commit verification) and, if
476
+ the host carries `follow-up-of`, the Step 6 tracking commit has also
477
+ landed and been verified. `status: completed` or a directory already
478
+ under `completed/` does not show this on its own.
479
+ A `bugfix/` host closes out exactly like a `feature/` one; an
480
+ un-closed-out host must not merge.
481
+ - [ ] **The tier's artifact** has the fix documented — a **T2**'s lightweight
482
+ spec, or for a **T3** the host `_index.md` Lightweight Changes row, which
483
+ is its whole record. Do not ask a T3 for a spec file here either: the
484
+ Before-Creating item above says why, and this gate is the last place that
485
+ mistake can still block the merge.
319
486
  - [ ] Tech debt recorded if the underlying issue is broader (record in
320
487
  `dflow/specs/architecture/tech-debt.md` if the bug reveals a systemic issue)
321
488
  - [ ] Fix is in the correct architectural layer (Domain / Application /
@@ -354,7 +521,7 @@ with the rule.
354
521
  These checks could eventually be automated in CI:
355
522
  - Verify Domain project has zero external package-manager dependencies (beyond allowed list)
356
523
  - Verify no ORM/serialization attributes on Domain entities
357
- - Verify spec file exists for any branch with feature/ or bugfix/ prefix
524
+ - Verify a spec file exists for any branch with feature/ or bugfix/ prefix — except a host whose entire record is inline in its `_index.md` and therefore has no spec file by design (a T3-only host today, and any later shape with that same property); check for the row instead
358
525
  - Verify glossary.md / rules.md / events.md updated when Domain/ files change
359
526
  - Lint commit messages for spec ID format
360
527
 
@@ -256,8 +256,18 @@ Key Greenfield-track notes:
256
256
  - **`behavior.md` is NOT generated here.** Per F-05, per-context
257
257
  `behavior.md` files are created by `/dflow:new-feature` Step 8.3
258
258
  (completion flow) or by the P007a baseline-capture flow at the
259
- moment the first bounded context is established. Creating empty
260
- `behavior.md` files here would create stale placeholders.
259
+ moment the first bounded context is established.
260
+ - **`analysis.md` is NOT generated here**, at either of its paths. It holds
261
+ the system-level knowledge no single context document owns — an ordered flow
262
+ that crosses contexts (always the domain-root copy), the lifecycle a status
263
+ field moves through, a figure computed rather than stored, the mechanism
264
+ behind a behavior no single rule explains, which roles reach which function
265
+ (always the domain-root copy), and the spots in them this project keeps
266
+ working around until a domain decision settles them (each in the copy that
267
+ holds the knowledge it is stuck on). What one context owns is recorded in
268
+ `domain/{context}/analysis.md` and the rest in `domain/analysis.md`, each
269
+ created from `templates/analysis.md` the first time a session records
270
+ something that belongs there.
261
271
 
262
272
  ### 3.2 Optional files (from Step 2 Q7)
263
273
 
@@ -306,12 +316,19 @@ skip, and wait for developer confirmation:
306
316
  > |---|---|
307
317
  > | `dflow/specs/domain/glossary.md` | already exists (47 lines) |
308
318
  >
309
- > **Not creating** (per F-05 decision):
319
+ > **Not creating**:
310
320
  > - No `dflow/specs/domain/{context}/behavior.md` files. These are created
311
321
  > later by `/dflow:new-feature` Step 8.3 or P007a when the first
312
322
  > bounded context is established.
313
323
  > - No pre-seeded ADR files in `dflow/specs/architecture/decisions/`. Write
314
324
  > ADRs as architecture decisions come up; Day-0 is too early.
325
+ > - No `dflow/specs/domain/analysis.md` and no
326
+ > `dflow/specs/domain/{context}/analysis.md`. Each is created the first time
327
+ > one of these turns up and belongs there — an ordered cross-context flow
328
+ > (always the domain-root copy), the lifecycle of a status field, a derived
329
+ > figure, a mechanism no single rule explains, which roles reach which
330
+ > function (always the domain-root copy), or a spot in one of them this
331
+ > project keeps working around until a domain decision settles it.
315
332
  >
316
333
  > Looks good? Reply 'yes' to proceed with the writes, or tell me what to
317
334
  > adjust."
@@ -456,6 +473,9 @@ Init complete. Summary:
456
473
  Deferred (not created here by design):
457
474
  - dflow/specs/domain/{context}/behavior.md — created by /dflow:new-feature
458
475
  Step 8.3 or P007a baseline capture
476
+ - dflow/specs/domain/{context}/analysis.md — needs a real bounded context
477
+ - dflow/specs/domain/analysis.md — created the first time a session records a
478
+ cross-context flow, role reach, or other knowledge no single context owns
459
479
  - dflow/specs/architecture/decisions/ADR-*.md — write ADRs as
460
480
  architecture decisions come up, not speculatively
461
481
  ```