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
@@ -0,0 +1,104 @@
1
+ # Step 1.6: Create Follow-up Feature — Greenfield Clean Architecture
2
+
3
+ Branch file of `references/modify-existing-flow.md`. It **adds** the
4
+ follow-up-specific rules; it does not restate or override anything in that flow.
5
+
6
+ **You are here because** that flow's Step 1.6 dispatched you — it owns whether
7
+ this route applies, and what has already been decided by the time you arrive.
8
+
9
+ Build the follow-up feature using the same machinery as
10
+ `/dflow:new-feature` (see `new-feature-flow.md` Steps 3.5 and 4), with
11
+ these follow-up-specific differences. **Use the tier Part A already decided.**
12
+ This is the same change Part A classified, and re-running the cascade on it can
13
+ return a second answer to one question. Re-enter Part A **only** when the
14
+ Step 1.5 A/B/C discussion materially changed the scope (work added or dropped);
15
+ say so explicitly when you do, and let that re-run **replace** the earlier tier
16
+ rather than stand beside it. On that tier: a **T1** follow-up takes the full
17
+ new-feature machinery below; a **T2 / T3** follow-up takes
18
+ the **minimal (zero-phase) variant** described after the reverse-link step —
19
+ it does **not** delegate new-feature Step 4's unconditional first phase-spec.
20
+ A **post-hoc hotfix** whose host linkage Step 1.8 resolved to *follow-up*
21
+ also arrives here (never through the Step 1.5 prompt, and always T2 / T3, so
22
+ always the minimal variant); its first checkpoint keeps the `implementation`
23
+ name but carries Result `reconciled (...)` per Step 1.8.
24
+
25
+ - **New SPEC-ID** (today's date sequence — do NOT reuse the original
26
+ SPEC-ID): e.g. original `SPEC-20260201-003-訂單折扣` → follow-up
27
+ `SPEC-20260424-002-訂單折扣-匯率擴充` (or any new slug)
28
+ - **New slug**: not required to equal the original slug; pick whatever
29
+ best describes the follow-up scope
30
+ - **`_index.md` Metadata**: `follow-up-of: {原 SPEC-ID}` is REQUIRED
31
+ (uncomment the optional line in the template; can be a YAML array if
32
+ the follow-up spans multiple originals)
33
+ - **`_index.md` Goals & Scope** auto-prepended note:
34
+ ```
35
+ > 本 feature 為 `{原 SPEC-ID}-{原 slug}` 的 follow-up,原 feature
36
+ > 完成於 `{date}`,詳見 `completed/{原 SPEC-ID}-{原 slug}/_index.md`。
37
+ ```
38
+ - **`_index.md` Current BR Snapshot baseline** (**BC-bearing follow-up only**):
39
+ if the follow-up touches a bounded context, AI reads the BC's
40
+ `dflow/specs/domain/{context}/rules.md` and inherits the BRs that are
41
+ in-scope for this follow-up. Mark each inherited row with First Seen
42
+ = `inherited from rules.md` and Last Updated = (empty until the new
43
+ feature's first phase Delta — or, for a minimal follow-up, its
44
+ lightweight-spec's delta — touches it). For a **no-BC follow-up** (the
45
+ minimal variant on a completed no-BC host), leave the Current BR Snapshot
46
+ **empty** — do not read or fabricate a BC's `rules.md`.
47
+
48
+ **Reverse-link into the old `_index.md`**: AI also updates
49
+ `dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md` —
50
+ uncomment the Follow-up Tracking section (if not already present) and
51
+ add a row. When `follow-up-of` names **more than one** original (it may be a
52
+ YAML array), do this in **every** one of them; a parent left without its row
53
+ never gets the `absent → in-progress → completed` transition the contract
54
+ requires, and on a **minimal** follow-up host finish-feature Step 1 blocks
55
+ closeout on it (that check is scoped "Minimal host (zero-phase), follow-up
56
+ only" and proves the *opening* half; on a phase-bearing follow-up Step 6 still
57
+ flips and verifies the closing half, but nothing checks that the row was ever
58
+ opened as `in-progress`):
59
+
60
+ ```
61
+ | {新 SPEC-ID} | {新 slug} | {today} | in-progress |
62
+ ```
63
+
64
+ This update is **part of the same change set** as opening the host. For a
65
+ **T1** follow-up the AI may offer to commit the new host and this initial
66
+ `absent → in-progress` reverse-link together (commit message should mention
67
+ "Add follow-up reference to `{新 SPEC-ID}`"). For the **minimal (T2 / T3)
68
+ variant** the AI does **not** offer a separate host-open commit — the
69
+ initial reverse-link edit rides along in the implementation checkpoint (see
70
+ the variant paragraph below), keeping the follow-up at exactly two host
71
+ checkpoints. The reverse link is a derived index — the new feature's
72
+ `follow-up-of` field is the authoritative source.
73
+
74
+ After a **T1** follow-up feature is set up, this flow hands off to the
75
+ `/dflow:new-phase` flow (or stays in this flow at Step 2 for the first
76
+ phase's content).
77
+
78
+ **Minimal (zero-phase) follow-up variant (T2 / T3).** When the follow-up
79
+ change is itself lightweight, do **not** delegate new-feature Step 4 (which
80
+ would create an unconditional first phase-spec). Instead treat the follow-up
81
+ host exactly like a standalone minimal host — open it via **Step 1.7's
82
+ mechanics, steps 2–4 only** (assign identifiers + collision check, create the
83
+ minimal `_index.md` with an empty Phase Specs table, branch gate **by change
84
+ class**: `bugfix/BUG-{NUMBER}-{slug}` for a functional bug,
85
+ `feature/{SPEC-ID}-{slug}` otherwise — this **overrides** new-feature's
86
+ hardcoded `feature/` branch). Step 1.7's **step 1 does not apply**: it is the
87
+ standalone-classification gate, and this caller has already been classified as
88
+ a follow-up. Everything Step 1.7 states **after** step 4 *does* apply
89
+ unchanged — every artifact's row written before checkpoint 1, the
90
+ implementation-path declaration, the finalization before checkpoint 1 and
91
+ "Finalize + close" after it, and the two
92
+ commit-evidence surfaces — because finish-feature reads for all of it on a
93
+ follow-up host exactly as on a standalone one. Then record the change's
94
+ artifacts — a T2 lightweight-spec, one
95
+ or more T3 inline rows, or both for a compound follow-up (Step 1.7's
96
+ "minimal means zero-phase, not one-artifact") — and close with
97
+ `/dflow:finish-feature`. The lifecycle is **two host checkpoints**
98
+ (implementation, then closeout) **plus one post-closeout reverse-link flip
99
+ tracking commit** — the flip (the original feature's Follow-up Tracking row
100
+ `in-progress → completed`, done by `/dflow:finish-feature` Step 6) is a
101
+ **sanctioned post-completion mutation, not a host checkpoint**, and is
102
+ recorded in **neither** the follow-up host's Checkpoint Log **nor** the
103
+ original feature's. Option C of Step 1.5 ("a follow-up containing only one
104
+ T3 row") lands here.
@@ -0,0 +1,200 @@
1
+ # Step 1.8: Hotfix T2 / T3 Post-Hoc — Greenfield Clean Architecture
2
+
3
+ Branch file of `references/modify-existing-flow.md`. It **adds** the
4
+ post-hoc-specific rules; it does not restate or override anything in that flow.
5
+
6
+ **You are here because** that flow's Step 1.8 dispatched you — it owns whether
7
+ this route applies, and what has already been decided by the time you arrive.
8
+
9
+ Sometimes an urgent fix is merged, pushed, and its branch cleaned up
10
+ **before** any Dflow ceremony runs. When you come back to record it,
11
+ declare **post-hoc mode** and reconcile rather than re-implement.
12
+
13
+ **Admission condition — T2 / T3 only.** This step builds a *minimal
14
+ (zero-phase)* host, so it admits only a post-hoc change Part A classified
15
+ **T2 or T3**. A **T1** post-hoc keeps the normal phase-bearing route
16
+ (`/dflow:new-phase` / `/dflow:new-feature`) and documents the merged work
17
+ there — it is not routed here, and giving it a zero-phase host would be wrong.
18
+ If you arrived here with a T1, go back to Part A's routing.
19
+
20
+ 1. **Host-linkage choice first.** A post-hoc hotfix is **already merged on the
21
+ mainline**, so no in-flight feature branch can host it: documenting it into
22
+ an unmerged `feature/...` host would strand the production fix's record on a
23
+ branch the mainline cannot see — possibly for weeks — and would let that
24
+ feature's Integration Summary claim work it never did. The hotfix therefore
25
+ always gets a host of its own, and the only question is whether that host is
26
+ linked:
27
+ - **A related completed feature** → run it as a **follow-up** (Step 1.6
28
+ minimal variant — keep `follow-up-of` and its two reverse-link
29
+ transitions). A hotfix on a completed feature filed as an unlinked
30
+ standalone loses its lineage.
31
+ - **Otherwise** → open a **standalone** minimal host (Step 1.7). "Otherwise"
32
+ includes *a related feature that is still in flight* — see above for why
33
+ it cannot be the host.
34
+
35
+ Make the choice here, and **act on it only after item 2's branch-base
36
+ check**: on either route, nothing is opened, linked or cut before that
37
+ check.
38
+
39
+ Do not skip this choice. If a feature that was in flight turns out to have
40
+ touched the same code, that is a **merge** question, settled when the
41
+ branches actually meet — see `finish-feature-flow.md` Step 5.
42
+ 2. **Reconcile, do not re-run.** The implementation already happened on the
43
+ (now often deleted) hotfix branch. Do **not** reopen an implementation
44
+ branch for it or redo the work. The documentation is recorded on **this
45
+ host's own branch**, cut by change class at Step 1.7 step 4 (or at Step
46
+ 1.6's delegation to it) like any other minimal host — that branch *is* the
47
+ **post-hoc branch** the rest of this step names, and the value `_index.md`
48
+ `branch:` records.
49
+
50
+ **Branch-base check — run it before Step 1.7 step 3 creates anything**
51
+ (on the follow-up route: before Step 1.6 opens the host and writes the
52
+ reverse link). It settles which base branch this host's branch is cut
53
+ from. Closeout requires the commit item 3 records to be an ancestor of
54
+ this branch, so a branch cut from a base that does not contain that commit
55
+ yet passes every step until closeout and is blocked there. Settle that
56
+ commit with the developer first (item 3), then:
57
+ 1. Settle the base branch and fetch it. The developer decides which
58
+ branch is the base — Dflow does not know it, though the project may
59
+ record it under `_conventions.md` § Git Policy — and it is the branch
60
+ Step 1.7 step 4 cuts from anyway. `{base-ref}` is that branch's latest
61
+ ref (for example `origin/develop`). Fetch the remote it belongs to
62
+ (`git fetch origin` for `origin/develop`; `git fetch --all` when
63
+ unsure): a bare `git fetch` updates only the default remote, so a base
64
+ on another remote stays stale and the steps below misjudge it. The fix
65
+ is merged and pushed by now, and it often reached the base on the
66
+ server — a PR merge or a squash — that this clone has not fetched yet.
67
+ 2. Run `git cat-file -t {hash}`. It must print `commit`. If it prints
68
+ anything else or fails, and step 1's fetch failed, the commit may only
69
+ be missing from this clone: stop, say the check needs the fetch, and
70
+ run it again once the remote is reachable. Otherwise the hash is
71
+ mistyped, names an object that is not a commit, or names a commit that
72
+ remote does not have — stop and ask the developer. Do not guess.
73
+ 3. Run `git show --stat {hash}`. At least one path it lists must be an
74
+ implementation path this record will declare. If none is, stop and
75
+ settle the commit with the developer — closeout's (c) would block it.
76
+ A last commit that touches only tests does this. Then run
77
+ `git rev-list --parents -n 1 {hash}`: more than two hashes means a
78
+ merge commit — for example the one a PR page shows as its merged
79
+ commit. Item 3 never records one, and a merge usually passes the path
80
+ check above, so stop here and settle the commit with the developer.
81
+ 4. Run `git merge-base --is-ancestor {hash} {base-ref}`:
82
+ - **Exit `0`** — cut this host's branch from `{base-ref}` at Step 1.7
83
+ step 4. Do **not** let the new branch track the base: run
84
+ `git checkout -b {branch} --no-track {base-ref}`, or update the local
85
+ base branch the way the project normally does and cut from that. A
86
+ branch that tracks `origin/develop` can, under some push settings,
87
+ push its documentation commits straight to `develop`.
88
+ - **Exit `1`** — the fix is not in that base yet. Tell the developer
89
+ both causes. **The fix has not been merged back yet**: merge it back
90
+ first (under GitFlow, into `develop`). **The recorded commit is not
91
+ the one item 3 names**: under a squash or rebase merge, or a
92
+ cherry-pick into the base, the fix's own commits never reach it —
93
+ record the commit the fix landed as (item 3).
94
+ ⚠ Do **not** cut from `main` instead to make the check pass: the
95
+ documentation branch would carry `main`'s merge commits into
96
+ `develop` when it merges, and its documents would start from
97
+ `main`'s older Domain documents and conflict there.
98
+ - **Any other exit code** — a mistyped ref or a failed command. Stop
99
+ and show the developer the output.
100
+ - **If step 1's fetch failed** (offline): exit `0` is still
101
+ trustworthy — the ref you cut from does contain the commit. Exit `1`
102
+ may only mean the local ref is behind; treat it as provisional and
103
+ say so.
104
+ 3. **Implementation checkpoint Result = `reconciled ({merged-hotfix-hash})`.**
105
+ In the host's Checkpoint Log the implementation row's Result is
106
+ `reconciled (...)` — the value meaning "this checkpoint documents an
107
+ already-merged change" — carrying the hash of **one of the fix's own
108
+ commits**, or of **the commit the fix landed as** when it reached the base
109
+ branch by a squash, a rebase or a cherry-pick — a commit on the base
110
+ branch this host's branch is cut from (item 2).
111
+ It sits alongside the usual `committed` / `skipped` / `failed` Results (see
112
+ `references/git-integration.md` § Commit Checkpoints, Branch Gate & AI
113
+ Commits). That hash belongs to the **hotfix**, so it is **not** evidence
114
+ that this host's own first commit landed — the documentation work still owes
115
+ checkpoint 1 a real commit of its own (item 4), made **before** closeout.
116
+ Committing the documentation together with closeout collapses the host to
117
+ one commit and fails finish-feature Step 1.
118
+
119
+ **Which commit that is depends on how the fix reached the base branch:**
120
+
121
+ | The fix reached the base branch by | Record |
122
+ |---|---|
123
+ | a merge (under GitFlow, merging the hotfix branch back into `develop`) or a fast-forward | the last of **the fix's own commits** that touches a declared implementation path — never a merge commit, and under GitFlow never the tagged merge commit on `main`, which the back-merge does not bring into `develop` |
124
+ | a squash merge | the squash commit on the base branch |
125
+ | a rebase merge or a cherry-pick | the last of the fix's commits **as they landed on the base branch** that touches a declared implementation path |
126
+
127
+ When the fix's own commits are on the base branch, record one of them even if
128
+ a copy of the fix got there first. Closeout accepts a commit that touches only
129
+ some of the declared paths: it asks for at least one. The hotfix branch's own
130
+ name still goes in `hotfix-branch:` (item 4).
131
+
132
+ **You are asserting this hash, not deriving it.** Nothing in the repository
133
+ records which commit was the hotfix, so no check in this flow can confirm
134
+ it — finish-feature's reconciliation gate is explicit that it tests
135
+ plausibility only. So state the identity
136
+ and **cite what it rests on**: the PR, incident, or tracker reference that
137
+ identifies this fix. **Cite the source, not the hash** — a corrected hash
138
+ (item 6) then never has to touch the citation. Record the citation
139
+ alongside the per-tier trace
140
+ (item 4). An **uncited** hash blocks closeout —
141
+ `references/pr-review-checklist.md` is what confirms the identity, and it
142
+ needs something to confirm against.
143
+ 4. **Per-tier trace.** A **T2** records the merged-hotfix branch in its
144
+ lightweight-spec `hotfix-branch:` field; a **T3** marks its `_index.md`
145
+ Lightweight Changes row Description as a hotfix (no new field, no T3 spec
146
+ file). Item 3's identity citation goes in the same place — beside
147
+ `hotfix-branch:` for a T2, in the row Description for a T3 — so the trace
148
+ and the thing it rests on stay together. In **both** tiers the host's
149
+ Lightweight Changes row carries a `Commit` value, and that value is the
150
+ **post-hoc documentation commit**
151
+ hash (the row is produced by the documentation work) — **not** the
152
+ merged hotfix hash, which already lives in the `reconciled (...)` checkpoint
153
+ above; the two have different provenance and must not be conflated. This
154
+ row hash is what finish-feature Step 1 reads to prove the documentation
155
+ commit exists separately from closeout, so fill it in as soon as that
156
+ commit lands.
157
+ 5. **Branch equality** for the host is asserted against the **post-hoc
158
+ documentation branch** (the `_index.md` `branch:` value), never the deleted
159
+ hotfix branch.
160
+ 6. **Closeout: (b) fails on the `reconciled (...)` hash.**
161
+ `references/finish-feature-minimal-host.md`'s `Minimal host, hotfix
162
+ post-hoc only` check sends you here. Report which cause it is — never only
163
+ "not an ancestor" — and give the developer the repair for that cause. First
164
+ fetch the remote `{base-ref}` belongs to (item 2 step 1) and find the
165
+ commit item 3 says to record, then test where it is. If the fetch fails, a
166
+ result that depends on `{base-ref}`, or on a commit this clone does not
167
+ have, is provisional — say so, as item 2 does:
168
+ - **It is already on this branch** (`git merge-base --is-ancestor
169
+ {its-hash} HEAD` exits `0`) — the record names the right fix but the
170
+ wrong commit — for example the tagged merge commit on `main`. Correct
171
+ only the Checkpoint Log hash. The citation (item 3 cites the source, not
172
+ the hash), `hotfix-branch:` and the declared paths stay as they are, so
173
+ the correction rides the closeout commit — closeout's closed list admits
174
+ Checkpoint Log rows. Checkpoint 1 is not touched.
175
+ - **It is on the base branch but not on this branch** (`git merge-base
176
+ --is-ancestor {its-hash} {base-ref}` exits `0`) — this branch was cut
177
+ before the fix reached the base, so correcting the hash is not enough.
178
+ Merge `{base-ref}` into this branch — or, if nothing is pushed yet,
179
+ rebase this branch onto it and refill every Lightweight Changes row's
180
+ `Commit` cell — then record that commit. Set closeout's uncommitted
181
+ finalization edits aside first with `git stash push --include-untracked`
182
+ (a plain `git stash` leaves newly created files behind), check that
183
+ `git status --porcelain` prints nothing, and restore them afterwards
184
+ with `git stash pop`: `git rebase` refuses to run over uncommitted
185
+ edits, and `git merge` refuses when the base changed the same files. If
186
+ `git stash pop` reports a conflict — it can when the base changed the
187
+ same part of a file those edits touch — resolve it before closeout
188
+ continues.
189
+ - **It is not on the base branch either** — the fix was never merged back.
190
+ Merge it back first (under GitFlow, into `develop`), then take the case
191
+ above.
192
+ - ⚠ **Never merge `main` or the tag into this branch to make (b) pass.** It
193
+ lets the wrongly recorded commit pass unchanged, and it carries `main`'s
194
+ commits into `develop` when this branch merges.
195
+ - **The record names a different fix** (the citation, the hotfix branch and
196
+ the declared paths are all wrong) — checkpoint 1's own record is wrong,
197
+ and closeout cannot repair that. Follow
198
+ `references/finish-feature-record-correction.md`: it says when
199
+ checkpoint 1 can be amended and when to stop for the developer, and it
200
+ covers `reconciled (...)`, which names the wrong fix too.
@@ -14,7 +14,7 @@ Crossing any step gate above also updates the host feature's `_index.md` Resume
14
14
 
15
15
  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.
16
16
 
17
- **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).
17
+ **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 (the ordered cascade — T1 / T2 / T3 / below workflow) applies to `/dflow:modify-existing` and `/dflow:bug-fix`; the criteria live in AI-AGENT-GUIDE.md § Ceremony Scaling, and `references/modify-existing-flow.md` is where they are applied.
18
18
 
19
19
  ## Step 1: Intake — Understand the Request
20
20
 
@@ -28,6 +28,25 @@ Ask naturally:
28
28
  2. **Who needs it?** Stakeholder or user role.
29
29
  3. **Why now?** Priority and urgency.
30
30
 
31
+ > **`/dflow:new-feature` is always T1 — it does not re-run the cascade.**
32
+ > Entering here declares "genuinely new work" (a new capability, page, or
33
+ > navigable surface). If the request is really a **modification** of existing
34
+ > behaviour — a tweak, a bug fix, an appearance change, or anything that would
35
+ > land at T2 / T3 / below-workflow — it belongs in `/dflow:modify-existing`,
36
+ > whose Step 1 cascade (step 0) is the only place a misroute is caught. So
37
+ > sanity-check at intake: if this looks like a small change to something that
38
+ > already exists, redirect to `/dflow:modify-existing` rather than minting a T1
39
+ > feature. ⚠ **Do not redirect a request that already came from there.** A
40
+ > `/dflow:modify-existing` or `/dflow:bug-fix` request the cascade landed at T1
41
+ > — including one a project convention escalated to T1, which the overlay may
42
+ > only ever raise — is routed here **by** step 0 and has already been caught;
43
+ > sending it back is a loop, because step 0 provably returns the same answer.
44
+ > `AI-AGENT-GUIDE.md` § Ceremony Scaling's T1 row says so directly. The guard
45
+ > is for a request that arrived at `/dflow:new-feature` **without** passing the
46
+ > cascade. (A follow-up to a *completed* feature is the one new-feature-shaped
47
+ > case that may still be lightweight — it arrives through `modify-existing`
48
+ > Step 1.6's minimal variant, not here.)
49
+
31
50
  Check existing assets:
32
51
  - Search `dflow/specs/domain/` for related concepts
33
52
  - Search `dflow/specs/features/` for related features
@@ -148,6 +167,20 @@ valid outcome; extending silently is not.
148
167
  - Service interfaces for external systems
149
168
  - Define in Domain layer, implement in Infrastructure
150
169
 
170
+ ### System-Level Knowledge
171
+ ```
172
+ "Which parts of this feature will no single context document hold?"
173
+ ```
174
+
175
+ - What crosses a bounded context, and what does each step hand to the next? (always the domain-root copy)
176
+ - Which status fields does this feature introduce, and what transitions do they move through?
177
+ - Which figures are derived rather than stored?
178
+ - Who reaches this feature, and what data scope does each role see? (always the domain-root copy)
179
+
180
+ Record each answer in `dflow/specs/domain/{context}/analysis.md` when one context owns what it describes and in `dflow/specs/domain/analysis.md` when no one context does, creating the file from `templates/analysis.md` the first time there is something to record. That template's sections carry the notation.
181
+
182
+ Domain events keep their definitions and payloads in `events.md`; name them in the flow here instead of restating them.
183
+
151
184
  If foundational domain docs are missing, create them from templates before writing content:
152
185
  - `dflow/specs/domain/glossary.md` → `templates/glossary.md`
153
186
  - `dflow/specs/domain/{context}/models.md` → `templates/models.md`
@@ -159,7 +192,7 @@ If foundational domain docs are missing, create them from templates before writi
159
192
  **→ Step Gate: Step 3 → Step 3.5**
160
193
 
161
194
  Announce to developer:
162
- > "Aggregate / VO / Events identified. Before I create any files, let me confirm the SPEC-ID, slug, directory name, and branch name with you (Step 3.5). `/dflow:next` to proceed."
195
+ > "Aggregate / VO / Events identified. Before I create the feature directory or branch, let me confirm the SPEC-ID, slug, directory name, and branch name with you (Step 3.5). `/dflow:next` to proceed."
163
196
 
164
197
  Wait for confirmation before entering Step 3.5.
165
198
 
@@ -208,7 +241,30 @@ If the developer asks to change the slug, re-propose and re-confirm.
208
241
 
209
242
  ## Step 4: Write the Spec
210
243
 
211
- Create the **feature directory** + **`_index.md`** + **first phase-spec**:
244
+ > **Minimal hosts do not come here (defensive guard).** Step 4 creates a first
245
+ > phase-spec, which only a genuinely **T1** new feature has. A **minimal host**
246
+ > is zero-phase and is recorded through its own path in `modify-existing-flow.md`,
247
+ > **not here**: Step 1.6 explicitly does **not** delegate to this step. If you
248
+ > reached Step 4 while handling a minimal / zero-phase host, **stop and re-enter
249
+ > `modify-existing-flow.md` at Step 1** — *not* at Step 1.6, 1.7 or 1.8.
250
+ >
251
+ > Those steps each assume work Step 1 has already done: Part A has decided the
252
+ > tier, and Part B has done the host linkage. An entry that arrived *here* ran
253
+ > neither, so recovering into one of them skips the authoritative cascade and
254
+ > the completed-feature scan — which is how a change that should have been a
255
+ > follow-up gets archived as an unlinked standalone. Step 1 routes it from
256
+ > there, and its Part B hotfix callout is what sends a **T2 / T3 post-hoc**
257
+ > to Step 1.8 — the only route that attaches `reconciled
258
+ > ({merged-hotfix-hash})`, the identity citation, and the per-tier hotfix
259
+ > trace, all of which a host recovered straight into 1.6 / 1.7 would silently
260
+ > lack. (A **T1** post-hoc is not a minimal host and is not this guard's
261
+ > business.)
262
+ >
263
+ > Either way, do not create a phase-spec, and do not treat this step as a
264
+ > zero-phase execution path.
265
+
266
+ Create the **feature directory** + **`_index.md`** + **first phase-spec** (T1
267
+ new feature):
212
268
 
213
269
  ```
214
270
  dflow/specs/features/active/{SPEC-ID}-{slug}/
@@ -216,6 +272,8 @@ dflow/specs/features/active/{SPEC-ID}-{slug}/
216
272
  └── phase-spec-{YYYY-MM-DD}-{slug}.md
217
273
  ```
218
274
 
275
+ > **Table-cell formatting**: keep table cells concise — separate multiple short items with `<br>` (never chain them into one line with ;/; separators), and move long narrative detail out of the cell into a document section (full convention: the formatting comment at each spec doc's head).
276
+
219
277
  1. **Create the directory**: `dflow/specs/features/active/{SPEC-ID}-{slug}/`
220
278
  2. **Create `_index.md`** using `templates/_index.md`:
221
279
  - Metadata: fill `spec-id`, `slug`, `status: in-progress`, `created`, `branch`
@@ -391,7 +449,7 @@ During implementation, continuously verify:
391
449
  **→ Step Gate: Step 7 → Step 8**
392
450
 
393
451
  Announce to developer:
394
- > "Implementation appears complete across all four layers. Ready to run the completion checklist (verify against spec, update domain docs + context-map, ensure test coverage, archive the spec)? `/dflow:next` to proceed."
452
+ > "Implementation appears complete across all four layers. Ready to run the completion checklist (verify against spec, update domain docs + context-map, ensure test coverage, complete the phase)? `/dflow:next` to proceed."
395
453
 
396
454
  > Commit checkpoint (T1 milestone 2 of 3): offer to commit the implementation, then record the result in the `_index.md` Checkpoint Log. Milestone 3 (closeout) is the `/dflow:finish-feature` checkpoint.
397
455
 
@@ -414,7 +472,7 @@ AI reports `✓` / `✗` for every item before touching docs. Items marked *(pos
414
472
  - [ ] Aggregate invariants still hold after the change (all state changes go through methods, no public setters)
415
473
  - [ ] ORM / persistence mapping is kept outside Domain entities (no persistence attributes/annotations on Domain entities)
416
474
  - [ ] *(post-8.3)* `dflow/specs/domain/{context}/behavior.md` contains a section anchor for every `BR-*` introduced by this spec (mechanical input for `/dflow:verify`)
417
- - [ ] *(post-8.3)* `dflow/specs/domain/{context}/rules.md` `last-updated` is later than this spec's `created` date (mechanical drift guard)
475
+ - [ ] *(post-8.3)* for **every `BR-*` this spec introduced or changed**, that rule's row in `dflow/specs/domain/{context}/rules.md` carries a `Last updated` not earlier than this spec's `created` date (mechanical drift guard). ⚠ Quantified per-BR on purpose, like the item above: a T1 may legitimately introduce **no** BR (§ Ceremony Scaling step 0 admits it), and this then passes vacuously rather than blocking. `rules.md` has no document-level `last-updated` — it is a column in the Rule Index, which is what 8.3 sub-step B4 updates.
418
476
 
419
477
  If any item fails, report the gap and pause — don't proceed to 8.2.
420
478
 
@@ -433,44 +491,67 @@ Ask these one-by-one; do not dump all six at once.
433
491
 
434
492
  ### 8.3 Documentation updates
435
493
 
494
+ > **Table-cell formatting**: keep table cells concise — separate multiple short items with `<br>` (never chain them into one line with ;/; separators), and move long narrative detail out of the cell into a document section (full convention: the formatting comment at each spec doc's head).
495
+
436
496
  - [ ] `dflow/specs/domain/glossary.md` — new terms added
497
+ - [ ] `dflow/specs/domain/analysis.md` — ordered cross-context flows, role reach, or anything else no one context owns, that this feature introduced, found or altered; any spot this feature worked around pending a domain decision, in those or in unrecorded knowledge that belongs here; and any open row there this feature settled (created from `templates/analysis.md` the first time there is something to record)
437
498
  - [ ] `dflow/specs/domain/{context}/models.md` — model definitions updated
499
+ - [ ] `dflow/specs/domain/{context}/analysis.md` — lifecycles, derived figures or mechanisms no single rule explains this feature introduced, found or altered, in the owning context's copy, which may not be this host's; any spot this feature worked around pending a domain decision, in those or in a rule or unrecorded knowledge that belongs there; and any open row there this feature settled (created from `templates/analysis.md` the first time there is something to record) — including the lifecycle any `aggregate-design.md` worksheet recorded as State Transition Methods: that worksheet freezes with the feature directory, this file does not
438
500
  - [ ] `dflow/specs/domain/{context}/rules.md` — business rules updated
439
501
  - [ ] `dflow/specs/domain/{context}/behavior.md` — merge completed spec's Given/When/Then scenarios (incl. Aggregate transitions + Events) into consolidated behavior. Sub-steps:
440
502
  - Promote any Activity 3 (Spec Writing) draft sections (from B3 mid-sync) to formal sections
441
503
  - Update the corresponding `rules.md` anchor's `last-updated` date (B4)
442
504
  - [ ] `behavior.md` draft cleanup — if the spec was abandoned mid-way, keep the `## 提案中變更` section's history or explicitly REMOVE it
505
+ - [ ] `analysis.md`, at either of its two paths — re-check every entry this feature recorded before building: an entry for what the feature was to add or change against what was built (corrected where the build differs, removed where nothing was built for it), and an entry for something already in the system against the system as it now stands (corrected where this feature changed it, never removed because this feature built nothing for it). Read the entries in the file, not in a diff: a checkpoint may already have committed them.
443
506
  - [ ] `dflow/specs/domain/{context}/events.md` — Domain Events updated
444
507
  - [ ] `dflow/specs/domain/context-map.md` — updated if cross-context interaction was added or changed
445
508
  - [ ] `dflow/specs/architecture/tech-debt.md` — tech debt discovered during implementation recorded
446
509
 
447
- ### 8.4 Archival
448
-
449
- For a single-phase feature, this is the closeout point. If the feature has
450
- later phases still ahead, this phase is complete but the feature is not —
451
- don't archive yet; run `/dflow:new-phase` to start the next phase, not
452
- `/dflow:finish-feature` yet. For a multi-phase feature, the developer
453
- typically reaches this point at the end of the final phase — at which time
454
- `/dflow:finish-feature` is the recommended trigger (it bundles steps 8.1 /
455
- 8.2 verification, BC sync, and archival into one explicit ceremony). Either
456
- path is acceptable; pick the one that matches the developer's habit.
457
-
458
- - [ ] `_index.md` `status` field changed to `completed`
459
- - [ ] All `phase-spec-*.md` files in the feature directory have `status:
460
- completed` in their frontmatter
461
- - [ ] **Whole feature directory** moved from `dflow/specs/features/active/`
462
- to `dflow/specs/features/completed/` using `git mv` (preserves rename
463
- tracking — see `references/git-integration.md` § "Directory Moves
464
- Must Use git mv"):
465
- ```
466
- git mv dflow/specs/features/active/{SPEC-ID}-{slug} \
467
- dflow/specs/features/completed/{SPEC-ID}-{slug}
468
- ```
469
-
470
- > **Recommended path for multi-phase features**: instead of doing
471
- > 8.1–8.4 manually at the end of every phase, run `/dflow:finish-feature`
472
- > once the feature's last phase is complete. It executes the same checks
473
- > + BC sync + `git mv` + emits an Integration Summary. See
474
- > `references/finish-feature-flow.md`.
475
-
476
- Only announce "feature complete" after 8.4 is done.
510
+ ### 8.4 Phase completion and handoff
511
+
512
+ This step completes the phase and hands the feature on. It does not close the
513
+ feature out: `/dflow:finish-feature` is the only closeout path — it flips the
514
+ `_index.md` `status`, moves the feature directory to `completed/`, and takes
515
+ the closeout commit checkpoint.
516
+
517
+ **Complete this phase** — all four items, whether or not another phase
518
+ follows:
519
+
520
+ - [ ] This phase-spec's frontmatter `status` changed from `in-progress` to
521
+ `completed`
522
+ - [ ] This phase's row in the `_index.md` Phase Specs table changed from
523
+ `in-progress` to `completed`
524
+ - [ ] `_index.md` Current BR Snapshot reconciled against this phase-spec's
525
+ **Business Rules** section — this is the feature's first phase, so it
526
+ has no Delta from prior phases. If implementation changed a rule, update
527
+ the phase-spec first, then reconcile. Touch only this phase's rows: a
528
+ row that another change in this host wrote — a lightweight change
529
+ hosted under this feature, for example — stays as it is. Where this
530
+ phase and such a change both changed the same rule, keep the later
531
+ change's text; if the host's record does not show which change came
532
+ later, ask the developer which text is current instead of choosing.
533
+ - [ ] `_index.md` Resume Pointer: rewrite **both** narrative lines — Current
534
+ Progress says this phase is completed, and Next Action names the
535
+ command the handoff below picks. Step 4 wrote "phase-1 in progress:
536
+ drafting phase-spec." and "finish phase-spec, then implement …" into
537
+ these two lines; either one left standing reads as open work.
538
+
539
+ `/dflow:finish-feature` relies on these four whenever the feature reaches it,
540
+ next or after later phases. Its Step 1 checks the phase-spec `status`, the
541
+ Phase Specs row and the Resume Pointer, and stops closeout on a stale one.
542
+ Its Step 3 syncs the Current BR Snapshot into the bounded context as it
543
+ stands, without re-deriving it from the phase-specs.
544
+
545
+ `Implementation Tasks` is not on this list: 8.1 verified it, and 8.2 may have
546
+ collapsed or removed it by team convention. BC document sync is not on it
547
+ either: 8.3 did it.
548
+
549
+ **Hand off:**
550
+
551
+ - Another phase is still ahead → run `/dflow:new-phase` next.
552
+ - No further phase — a single-phase feature, or this was the last phase →
553
+ run `/dflow:finish-feature` next. It is the only closeout path.
554
+
555
+ Announce that this phase is completed and name the next command. Do not
556
+ announce the feature as complete: `/dflow:finish-feature` announces that once
557
+ its closeout is complete.