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,60 @@
1
+ # Step 6: Reverse-Update Follow-up Tracking — Greenfield Clean Architecture
2
+
3
+ Branch file of `references/finish-feature-flow.md`. It **adds** the follow-up
4
+ closing rules; it does not restate or override anything in that flow.
5
+
6
+ **You are here because** that flow's Step 6 dispatched you — it owns whether
7
+ this route applies.
8
+
9
+ For features that were created as follow-ups of an earlier completed
10
+ feature, update the Follow-up Tracking table of **every** original this host's
11
+ `follow-up-of` names — one parent, or several when the field is a YAML array.
12
+ For each of them:
13
+
14
+ 1. Locate `dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md`
15
+ 2. Find the Follow-up Tracking section's row for this feature's SPEC-ID
16
+ 3. Flip Status → `completed`
17
+
18
+ ```bash
19
+ # The AI makes the edit and may offer to commit it (Y / N), per the AI commit policy
20
+ ```
21
+
22
+ This flip is a **sanctioned post-completion mutation, not a checkpoint** —
23
+ the follow-up host is already closed out and archived, so it is recorded in
24
+ **no** Checkpoint Log (neither this original feature's nor the follow-up
25
+ host's). It **must still be committed**, though: the flip is a real edit to
26
+ the original feature's `_index.md`. Require the tracking commit — the AI offers
27
+ it (Y / N); if the developer declines or the commit fails, **stop and do not
28
+ declare closeout complete** until the flip is committed. After it commits,
29
+ verify **per original** with
30
+ `git show HEAD:dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md`
31
+ that the Follow-up Tracking row now reads `completed` in the **committed** blob,
32
+ and that `git status --short` is clean. **Then check the commit itself, two ways
33
+ — neither replaces the other.**
34
+ **(1) Its full path set** (`git show --stat HEAD`) contains **only** the
35
+ `_index.md` of the originals this host's `follow-up-of` names: nothing under the
36
+ archived follow-up host — that would be a third host-mutating commit, which the
37
+ two-checkpoint lifecycle does not allow — and nothing else at all.
38
+ **(2) Its patch per original** (`git show HEAD -- {that path}`) carries **that
39
+ row's own transition** — the `in-progress` line removed, the `completed` line
40
+ added — and **no Checkpoint Log change**: this flip enters *neither* ledger, so
41
+ a Checkpoint Log row appearing in a parent is a violation even when the flip
42
+ itself is correct.
43
+ Why both: the blob proves the final state, not who wrote it — a commit that
44
+ merely edits other text in parent A while flipping parent B leaves both blobs
45
+ reading `completed` with the flips split across two commits — and the patch in
46
+ (2) is **path-filtered**, so it cannot see what else the commit touched. Only
47
+ (1) can. The commit message references the
48
+ follow-up host's SPEC-ID. Where there are several originals, flip them **in one
49
+ commit** — for a minimal follow-up host that keeps this the single post-closeout
50
+ tracking commit named in `modify-existing-flow.md` Step 1.6's minimal variant.
51
+
52
+ After the update:
53
+ > "Follow-up Tracking row updated to Status = `completed` in
54
+ > `{原 SPEC-ID}-{原 slug}/_index.md` (and every other original listed).
55
+ > Closeout complete."
56
+
57
+ The connection is bidirectional and weakly redundant: the new feature's
58
+ `follow-up-of` field is the authoritative source; the old feature's
59
+ Follow-up Tracking row is a derived index. If they ever disagree, trust
60
+ `follow-up-of`.
@@ -0,0 +1,383 @@
1
+ # Minimal Host (Zero-Phase) Closeout — Greenfield Clean Architecture
2
+
3
+ Branch file of `references/finish-feature-flow.md`. It **adds** the checks and
4
+ field rules a minimal (zero-phase) host takes; it does not restate or override
5
+ anything in that flow.
6
+
7
+ **You are here when** `references/finish-feature-flow.md` Step 1's minimal-host
8
+ selector sent you — it states the condition; this file does not restate it.
9
+
10
+ **Keep this file for the whole closeout.** It adds to four of that flow's
11
+ steps — Step 1, Step 3, Step 4's post-commit verification, and Step 5 — and each
12
+ of those places points back here.
13
+
14
+ ## Hash evidence
15
+
16
+ **Hash evidence** (several checks in this file use this test). A hash recorded in
17
+ `_index.md` passes *hash evidence* when all three hold:
18
+ - **(a) it is a commit** — `git cat-file -t {hash}` reports `commit`;
19
+ - **(b) it is on this branch** — `git merge-base --is-ancestor {hash} HEAD`
20
+ succeeds;
21
+ - **(c) its diff carries what the record claims** — the commit's **changed
22
+ paths** include the artifact that row or checkpoint points at; each check
23
+ in this file names which. **Tree presence is not enough**: every commit
24
+ inherits the files an earlier one added, so a commit that only touched the
25
+ implementation would otherwise satisfy (c) for an artifact it never wrote. (a)
26
+ and (b) alone prove only that *some* earlier commit exists on this branch; (c)
27
+ is what ties it to the record.
28
+
29
+ ## Step 1 — additional validation checks
30
+
31
+ Run these as part of `references/finish-feature-flow.md` Step 1's checklist, in
32
+ the order given here, and report `✓` / `✗` for each exactly as that flow says.
33
+ A `✗` here stops closeout there, on the same terms.
34
+
35
+ - [ ] **Minimal host (zero-phase) only** — every row in `_index.md` Lightweight
36
+ Changes has a **non-empty `Commit` cell that passes hash evidence**; for
37
+ (c), the commit carries that row's own work: a **T2**'s
38
+ `lightweight-*.md` / `BUG-*.md` file, or for a **T3** an `_index.md` that
39
+ already carries this row at that hash — Step 1.7 writes every row *before*
40
+ checkpoint 1, which is what makes that provable here. This applies to
41
+ **T2 and T3 rows alike**. Three failures, all blocking — **report the one
42
+ that is true**, because the message is the developer's only clue about what
43
+ to do next: an **empty** cell means that change is not committed yet; a
44
+ cell holding a **placeholder** (`{hash}`, `{pending}`, `(待 commit)` —
45
+ anything `git cat-file -t` cannot resolve) means the cell was **never
46
+ filled in**, which is a different repair and may well have a commit sitting
47
+ there unrecorded; a **resolvable** value that fails (a)–(c) means the hash
48
+ is the wrong one. ⚠ Do not collapse the middle case into the first.
49
+ (`modify-existing-flow.md` Step 1.7 "Finalize + close" is where the
50
+ **cell** gets backfilled once its commit exists.)
51
+ **Deliberately not run on a phase-bearing host.** Those hosts keep
52
+ `references/finish-feature-flow.md` Step 1's two `Tier = T2` checks, which
53
+ never covered a T3 row anyway — a T3 has
54
+ no spec file in Dflow (`references/git-integration.md` § Gate Checks by
55
+ Branch Type).
56
+ - [ ] **Minimal host (zero-phase) only** — the Lightweight Changes table has
57
+ **at least one row** (a T2 or T3 row). An empty Phase Specs table **and**
58
+ an empty Lightweight Changes table is an **empty host** → reject closeout.
59
+ - [ ] **Minimal host (zero-phase) only** — **every spec file in the host
60
+ directory is named by a row.** The row-driven checks — this file's
61
+ `Commit` cell check and `references/finish-feature-flow.md` Step 1's two
62
+ `Tier = T2` items — walk rows → files, so a spec file that no row names is
63
+ never examined by them; this item closes
64
+ the other direction. A `phase-spec-*` always fails (the Phase Specs table
65
+ is empty by definition); a `lightweight-*.md` / `BUG-*.md` with no
66
+ Tier = T2 row fails the same way. A **T3-only** host carries no spec file
67
+ at all, so any spec file there fails this check.
68
+ - [ ] **Minimal host (zero-phase) only** — the Checkpoint Log shows a
69
+ **committed** first checkpoint before this closeout: Checkpoint
70
+ `implementation` with Result `committed ({hash})` (normal) or `reconciled
71
+ ({merged-hotfix-hash})` (hotfix post-hoc). A first checkpoint still
72
+ reading `skipped` or `failed` **blocks** closeout — but they are not the
73
+ same problem. `failed` means the commit was attempted and did not land:
74
+ the work is genuinely uncommitted and has to land. `skipped` means only
75
+ that **the AI's offer was declined** (`references/git-integration.md`
76
+ § Commit Checkpoints), *not* that no commit exists — the developer may
77
+ have made it themselves, which leaves the ledger **incomplete rather than
78
+ final**. Complete it: `modify-existing-flow.md` Step 1.7's "Finalize +
79
+ close" backfills the row to `committed ({hash})` with the developer's real
80
+ hash. Do **not** waive this check for a `skipped` row, and do **not** write
81
+ a hash you have not verified.
82
+ - [ ] **Minimal host (zero-phase) only** — **the Checkpoint Log carries exactly
83
+ one row at this point.** A minimal host takes exactly two checkpoints and
84
+ the second is the closeout row `references/finish-feature-flow.md` Step 4
85
+ instruction 1 adds, so before closeout there is exactly one: the first
86
+ checkpoint the preceding item validated. Any second pre-closeout row
87
+ **blocks** — **report the one that is true**, because the repairs differ.
88
+ What separates them is **whether the row records a checkpoint this host
89
+ actually reached**, not what its cells hold. A row that records none is
90
+ repaired **by deleting it**, however it is filled in: a `closeout` row is
91
+ one, because no closeout has run yet — Step 4 instruction 1 writes it at
92
+ closeout — and so is any row carried over from `templates/_index.md`'s
93
+ example table. A row that does record a reached checkpoint — a second
94
+ `implementation`, a leftover from an abandoned attempt, or one this list
95
+ does not name — says the host did not take the two-commit lifecycle, and
96
+ that is settled with the developer, not by deleting a line. A failed or
97
+ declined attempt does **not** add a row: both are recorded by editing the
98
+ existing one in place.
99
+ This counts the rows in **this host's own table** — it is not
100
+ the whole-history assertion, which stays with
101
+ `references/pr-review-checklist.md`.
102
+ - [ ] **Minimal host (zero-phase) only** — **that first commit is real, and it
103
+ is this host's.** The Checkpoint Log is prose; verify the hash behind it
104
+ against **hash evidence**. Take the hash that stands for checkpoint 1 —
105
+ for a **normal** host the `committed ({hash})` value; for a **hotfix
106
+ post-hoc** host the Lightweight Changes row's `Commit` cell (**not** the
107
+ `reconciled (...)` hash, which names the already-merged hotfix). For (c),
108
+ touching *some* path under
109
+ `dflow/specs/features/active/{SPEC-ID}-{slug}/` is **not enough** — a
110
+ stray host-open commit does that much while the work is still
111
+ uncommitted. Require the tier's artifact **among the commit's changed
112
+ paths** — (c) is what this commit wrote, not what its tree contains: a
113
+ **T2**'s `lightweight-*.md` / `BUG-*.md` spec file, or for a **T3** an
114
+ `_index.md` the commit **changed** *and* which, as committed at that hash,
115
+ already carries this change's Lightweight Changes row — `git show --stat
116
+ {hash}` **and** `git show
117
+ {hash}:dflow/specs/features/active/{SPEC-ID}-{slug}/_index.md`, both, not
118
+ either. Any of (a)–(c) failing **blocks** closeout.
119
+ - [ ] **Minimal host (zero-phase) only** — **checkpoint 1 is *one* commit, and
120
+ every row names it.** For a **normal** host the Checkpoint Log's
121
+ `committed ({hash})` and **every** Lightweight Changes row's `Commit` must
122
+ be the **same** hash, and that commit's diff must **touch the
123
+ implementation paths** its lightweight-spec or rows describe. Step 1.7
124
+ requires the artifact to **declare** those paths; an artifact naming none
125
+ leaves nothing to compare against, so a missing declaration **blocks** —
126
+ it never passes vacuously.
127
+ Assert the **equality itself**, not merely that each value passes hash
128
+ evidence on its own: two hashes that each resolve, are each reachable, and
129
+ each contain some named artifact describe a **three**-commit host —
130
+ host+spec at A, implementation at B, closeout at C — which clears every
131
+ other check on this list while breaking the two-commit lifecycle.
132
+ **Exempt — post-hoc hotfix only, and only this much:** the
133
+ `reconciled (...)` checkpoint hash and the row `Commit` cells name
134
+ different commits **by design** (Step 1.8), so do not assert equality
135
+ *between those two*, and do not apply the implementation-path condition to
136
+ this host's own commit — this file's `Minimal host, hotfix post-hoc only`
137
+ check tests the merged hotfix instead.
138
+ **Everything else still holds:** a post-hoc host can be compound too
139
+ (Step 1.7, "minimal means zero-phase, not one-artifact"), so **every** row
140
+ `Commit` must still name the **same single documentation commit**.
141
+ - [ ] **Minimal host (zero-phase) only** — **nothing that constitutes the change
142
+ itself is still uncommitted.** This is deliberately not "the host
143
+ directory is clean": **checkpoint 1 carries the change and the record
144
+ Step 5 writes; the closeout commit carries what the flow writes after
145
+ checkpoint 1.** Checkpoint 1 is offered at the end of
146
+ `modify-existing-flow.md`'s Step 5 (§ 5.5) and holds the change itself —
147
+ for a **T2** its lightweight-spec plus the implementation source, for a
148
+ **T3** its `_index.md` row plus the implementation source — together with
149
+ Step 5's completion checklist. What the flow writes *after* checkpoint 1 —
150
+ Step 1.7's "Finalize + close" — is derived record and rides into the
151
+ closeout commit, and so may a correction to Step 5's record made after
152
+ checkpoint 1.
153
+ **A post-hoc host (Step 1.8) inverts the source half, and this is where
154
+ the reconciliation contract is enforced.** Its change is the *already
155
+ merged* hotfix; checkpoint 1 is the **documentation** commit. So that
156
+ commit must carry the spec / row and this host's `_index.md` and must
157
+ **not** touch any implementation path the artifact declares — read
158
+ `git show --stat {checkpoint-1-hash}` and block if one appears. A
159
+ re-implementation committed there passes every other gate on this list
160
+ (rows agree, the `reconciled` hash differs from it and touches the
161
+ declared paths, the tree is clean) while breaking §8's "reconcile, do not
162
+ re-run" outright, so nothing else catches it.
163
+ **What this proves and what it does not — do not widen it here.** It
164
+ proves checkpoint 1 is documentation-only. It does **not** prove the
165
+ branch carries no re-implementation elsewhere: a second commit beside
166
+ checkpoint 1, or a re-implementation in a path the artifact does not
167
+ declare, both survive it. Widening it to the branch was tried and does not
168
+ work from inside closeout — the range needs a base branch, and Dflow
169
+ deliberately does not know yours. ⚠ **No check covers it today.** The
170
+ whole-history item `references/finish-feature-flow.md` Step 1 assigns to
171
+ `references/pr-review-checklist.md` is **not** it: that one counts commits
172
+ under this host's spec directory, so a re-implementation commit touching
173
+ only source never appears in its output. Review is where the missing
174
+ assertion belongs — a reviewer has the base branch in front of them — but
175
+ do not read the existing item as discharging it.
176
+ **Blocks closeout:** any of the **implementation source** files this
177
+ host's lightweight-spec or rows describe, staged or unstaged in
178
+ `git status --porcelain`; any **untracked** file under
179
+ `dflow/specs/features/active/{SPEC-ID}-{slug}/`; and any tracked file
180
+ dirty beyond the closed list below.
181
+ **May ride into the closeout commit — this list and nothing else:**
182
+ (i) `_index.md`, with its uncommitted delta confined to Lightweight
183
+ Changes `Commit` cells, Checkpoint Log rows, Resume Pointer, and Current
184
+ BR Snapshot;
185
+ (ii) an **already-committed** `lightweight-*.md` / `BUG-*.md`, with its
186
+ uncommitted delta confined to the frontmatter `status:` flip to
187
+ `completed` and the `Implementation Tasks` edits
188
+ `modify-existing-flow.md` Step 5's completion checklist makes ("applies
189
+ to both phase-spec and lightweight-spec"): ticking the tasks this change
190
+ completed and labelling each unchecked one as follow-up (5.1), and — when
191
+ the developer accepted the offer — collapsing or removing the section
192
+ (5.2). That checklist runs before checkpoint 1, so these edits are
193
+ normally committed already; this admits a correction to them made after
194
+ checkpoint 1;
195
+ (iii) the Domain-layer documents **this change's Step 5.3 sweep** updates
196
+ — under `dflow/specs/domain/`, plus
197
+ `dflow/specs/architecture/tech-debt.md` — scoped to *this change's*
198
+ delta. A **T3** has no Domain sweep at all (`modify-existing-flow.md`
199
+ Step 5's tier-conditional
200
+ note), so nothing qualifies under (iii) for a T3. A **no-BC** host has no
201
+ *BC-scoped* sweep — a dirty `dflow/specs/domain/{context}/…` or
202
+ `context-map.md` under one is fiction and **blocks** — but the **global**
203
+ documents (`glossary.md`, `domain/analysis.md`,
204
+ `architecture/tech-debt.md`) belong to no bounded context, stay in its
205
+ sweep, and therefore still qualify under (iii).
206
+ Read each delta with `git diff HEAD -- {path}` — plain `git diff` hides
207
+ what is already staged — and do not infer it from the filename.
208
+ **The list is closed** — if a later change adds another
209
+ finalization field, add it here explicitly; "a host file is dirty" is never
210
+ on its own a reason to pass. (Unrelated work in progress elsewhere is
211
+ fine; say which files you judged unrelated.)
212
+ **Checkpoint 1's own record, corrected after checkpoint 1, is outside the
213
+ list** — the spec's content beyond (ii)'s edits, a row's own text, or the
214
+ reverse-link row a follow-up wrote into its original's `_index.md`. It
215
+ blocks: the closeout commit does not carry checkpoint 1's content. The
216
+ dispatch right after this item gives the repair.
217
+
218
+ **Open `references/finish-feature-record-correction.md` and follow it there.**
219
+ Do this only when the check above blocked on a correction to checkpoint 1's own
220
+ record: the repair depends on where checkpoint 1 stands now, and that file gives
221
+ it for each case. Otherwise go on to the next check.
222
+
223
+ - [ ] **Minimal host (zero-phase), no-BC only** — **the host did not commit a
224
+ bounded context it does not have.** This file's `nothing that constitutes
225
+ the change itself is still uncommitted` check reads the *working
226
+ tree*; this one reads the **committed** side, because a fictitious
227
+ `{context}` invented at Step 2 and committed into checkpoint 1 leaves a
228
+ perfectly clean tree. Inspect checkpoint 1's diff
229
+ (`git show --stat {hash}`, with status — **not path names alone**): for a
230
+ host that declared itself no-BC that commit must **not touch, in any way**
231
+ — add, modify, delete or rename — any `dflow/specs/domain/{context}/…`
232
+ document. A deletion is a BC-layer change like any other, and reading only
233
+ the path list would accept one as if nothing had happened. The documents:
234
+ `rules.md`, `behavior.md`, `events.md`, `models.md`, `analysis.md` — and
235
+ no `context-map.md`. Any of them **blocks**
236
+ (`modify-existing-flow.md` Step 2's no-BC guard is where this should have
237
+ been caught first).
238
+ **Do not over-reach:** this rejects only Domain documents that commit
239
+ *added or changed* — pre-existing Domain files it never touched are
240
+ irrelevant, and the **global** documents (`glossary.md`,
241
+ `domain/analysis.md`, `architecture/tech-debt.md`) belong to no bounded
242
+ context and stay legitimate for a no-BC host, exactly as that check's
243
+ allow-list says.
244
+ **What this check cannot decide — stated, not asserted:** ⚠ **the rule it
245
+ enforces is not minimal-host-only; only this proof is.** *No no-BC host of
246
+ any shape may commit BC-scoped Domain material* — and what this reads is
247
+ **checkpoint 1**, one commit. It is not a branch-range proof: a second
248
+ commit beside checkpoint 1 carrying a `domain/{context}/…` document
249
+ survives it, and a **phase-bearing** no-BC host has no single checkpoint to
250
+ inspect at all, so it never runs this check in the first place. Closeout
251
+ cannot widen it — the range needs a base branch and Dflow deliberately does
252
+ not know yours (the same limit that working-tree check states).
253
+ **The branch-range assertion is confirmed by
254
+ `references/pr-review-checklist.md`'s "A no-BC host committed no BC-scoped
255
+ Domain material" item**, in that file's *Delegated to review by
256
+ `finish-feature-flow.md`* block, which applies to **every** no-BC host.
257
+ Keep this check anyway: it blocks earlier and more cheaply than review.
258
+ - [ ] **Minimal host (zero-phase), follow-up only** — **the reverse link was
259
+ opened, not only closed.** Step 1.6 requires the original feature's
260
+ Follow-up Tracking row for this host to be created as `in-progress` and to
261
+ ride checkpoint 1; `references/finish-feature-flow.md` Step 6 flips it to
262
+ `completed` afterwards. Verify the
263
+ opening half here, from committed state: for **every** SPEC-ID this host's
264
+ `follow-up-of` names — it may be a YAML array, so check each one —
265
+ `git show {checkpoint-1-hash}:dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md`
266
+ must already carry this host's row with Status `in-progress`. A row absent
267
+ there **blocks** closeout: the Step 6 flip would then create it directly as
268
+ `completed`, and the `absent → in-progress → completed` history the
269
+ follow-up contract requires never happened.
270
+ **What this check cannot decide — stated, not asserted:** ⚠ **only this
271
+ *proof* is minimal-host-only.** `references/finish-feature-flow.md`'s
272
+ Step 5 → Step 6 post-Local-closeout confirmation carries the requirement
273
+ itself and names who confirms it for a phase-bearing follow-up host; do
274
+ not read this check's scope as the requirement's scope. The evidence is what stops here: that host has no
275
+ single commit required to carry the row, so there is no committed blob for
276
+ this check to read and it never runs there.
277
+ - [ ] **Minimal host, hotfix post-hoc only** — the reconciliation record is
278
+ complete, **within a stated boundary**. This check proves **plausibility,
279
+ not identity**: that `{merged-hotfix-hash}` is a credible candidate, and
280
+ that the developer has said on the record which fix it is and how they
281
+ know. Whether it is *the* merged hotfix is **not decidable from inside
282
+ this flow** — the repository holds no independent record of which commit
283
+ that was; only the developer and the issue tracker do. Do not read a pass
284
+ here as identity confirmed. Identity is
285
+ **asserted** at `modify-existing-flow.md` Step 1.8 and **confirmed** by
286
+ `references/pr-review-checklist.md` — the same assignment
287
+ `references/finish-feature-flow.md` Step 1 gives the whole-history
288
+ assertion.
289
+ The plausibility conditions, all required: the
290
+ `reconciled ({merged-hotfix-hash})` value passes hash evidence — (a) and
291
+ (b) as usual, and for **(c)** its diff touches **at least one** of the
292
+ implementation paths the T2 lightweight-spec or the T3 row **declares**
293
+ (Step 1.7 requires that declaration; an artifact naming none leaves (c)
294
+ nothing to compare and **blocks** rather than passing vacuously). It
295
+ must also **differ**
296
+ from the Lightweight Changes row's documentation-commit hash (different
297
+ provenance; see Step 1.8). The per-tier trace must exist too: a **T2**
298
+ carries `hotfix-branch:` in its lightweight-spec frontmatter, a **T3** has
299
+ its Lightweight Changes row Description marked as a hotfix. Finally the
300
+ developer's identity assertion must be **present and cited** — Step 1.8
301
+ requires the source it rests on (PR / incident / tracker reference), and
302
+ it lives with the per-tier trace, so look for it there: beside
303
+ `hotfix-branch:` in a **T2**'s lightweight-spec, in the row Description
304
+ for a **T3**. An uncited hash **blocks** closeout: it leaves pr-review
305
+ nothing to confirm against, and this gate is not a substitute for that
306
+ confirmation.
307
+ **When (b) fails for the `reconciled (...)` hash, do not report only
308
+ "not an ancestor".** Open `references/modify-existing-post-hoc-hotfix.md`
309
+ item 6: it names the causes and the repair for each; report the one that
310
+ is true.
311
+
312
+ > **Zero-phase minimal host (`modify-existing-flow.md` Step 1.7 / the Step 1.6
313
+ > minimal variant / Step 1.8's post-hoc hotfix, whose linkage resolves to one of
314
+ > those two).** A standalone or follow-up minimal host closes out with
315
+ > an **empty Phase Specs table** — that is valid, not a failure: the "every
316
+ > Phase Specs row is completed" check passes vacuously and there is no
317
+ > `phase-spec-*` file to look for. A no-BR / T3 host also has an intentionally
318
+ > empty Current BR Snapshot — `references/finish-feature-flow.md` Step 1's
319
+ > **Current BR Snapshot** check decides that from the host's own record, not
320
+ > from a declaration. Do **not**
321
+ > manufacture a phase-spec or a BR row to make a check "pass".
322
+
323
+ ## Step 3 — sync input
324
+
325
+ **Minimal host — sync input.** A minimal host has no phase-spec: read the
326
+ "phase-spec" references in `references/finish-feature-flow.md` Step 3's sync
327
+ instructions (events "introduced by phase-specs", "each phase-spec's Delta") as
328
+ the host's **lightweight-spec** recorded delta
329
+ plus its Current BR Snapshot. A no-BR family that changed an event field or a
330
+ documented behaviour still syncs `events.md` / `behavior.md` from that
331
+ lightweight-spec's delta.
332
+ ⚠ What is minimal-host-only here is the **input binding** — the instruction to
333
+ read "phase-spec" as "lightweight-spec", which a host with no phase-spec needs
334
+ and a phase-bearing one must not apply. It is **not** that step's
335
+ **Every host — lightweight-spec deltas are a sync input too** paragraph, which
336
+ every host shape needs.
337
+
338
+ ## Step 4 — post-commit verification, additionally
339
+
340
+ Add this to `references/finish-feature-flow.md` Step 4's post-commit
341
+ verification, inside its archived-host-directory item:
342
+
343
+ **Minimal host (zero-phase) additionally**: the **first** checkpoint row
344
+ still carries the hash this file's Step 1 checks validated —
345
+ `implementation` with `committed ({hash})` or
346
+ `reconciled ({merged-hotfix-hash})`.
347
+
348
+ ## Step 5 — Integration Summary, exact fields
349
+
350
+ **Zero-phase minimal host — exact fields** (these must match the
351
+ `references/finish-feature-flow.md` Step 3 branch — do not require a field that
352
+ step left empty). A standalone or follow-up
353
+ minimal host has `Phase Count: 0`, an empty Phase List, and at least one row in
354
+ Lightweight Changes.
355
+
356
+ - a **no-BC host** (that step's case ii) sets the fields that report a **sync** to
357
+ none — `BC: none`, `Aggregates affected: none`, `Domain Events Changes:
358
+ none` (nothing was synced). **`Related BR-IDs` is not one of them**: it
359
+ reports what this change's own record carries, not what was synced, so it
360
+ takes the same values a BC-bearing host would — **empty**, or the
361
+ **per-family no-BR marker** when the T2 carries one. A T3-only no-BC host has
362
+ neither and leaves it empty.
363
+ - a **BC-bearing host** (that step's case i) sets `BC:` to the context and fills
364
+ each Domain field with **what it actually touched**: `Related BR-IDs:` a real
365
+ set, the per-family no-BR marker, or empty for a no-BR host; `Aggregates
366
+ affected:` and `Domain Events Changes:` the ones it changed, or `none` for
367
+ those it did not.
368
+
369
+ **What is scoped here and what is not.** This block fixes the *whole* field set
370
+ for a zero-phase host — `Phase Count: 0`, the empty Phase List, and which fields
371
+ each Step 3 branch leaves empty — and that part is genuinely zero-phase-only.
372
+ The `none`-for-unchanged rule on the last bullet is **not**: every BC-bearing
373
+ host needs it, and it is now stated where every one of them reads it, in
374
+ **`references/finish-feature-flow.md` Step 3 case (i)**. The two say the same
375
+ thing on purpose; if you change one, change the other.
376
+
377
+ ⚠ **No proof obligation is delegated from this block, and that is not an
378
+ omission.** These are field-filling instructions — they order values, they do
379
+ not test anything — so there is no evidence duty here for another host shape to
380
+ discharge or for review to take over. **N/A, stated rather than left blank**:
381
+ elsewhere in this file a scoped check that cannot reach another host shape hands
382
+ that shape to `references/pr-review-checklist.md` by name, and a reader who
383
+ finds no such hand-off here should not conclude one went missing.
@@ -0,0 +1,95 @@
1
+ # Post-Hoc Hotfix Reconciliation — Greenfield Clean Architecture
2
+
3
+ Branch file of `references/finish-feature-flow.md`. It **adds** the
4
+ reconciliation rules; it does not restate or override anything in that flow.
5
+
6
+ **Two different places in `references/finish-feature-flow.md` send you here, at
7
+ two different times. Read only the section that matches the one that sent you.**
8
+
9
+ - **Step 1's pre-checklist callout** — the branches met while this host was
10
+ still open → § Before closeout.
11
+ - **Step 5** — Step 4 has already archived and committed this host → § After
12
+ closeout.
13
+
14
+ ## Before closeout
15
+
16
+ **You are here when** `references/finish-feature-flow.md` Step 1's hotfix
17
+ callout sent you — it states the condition; this file does not restate it.
18
+
19
+ **What you classify here is the merge-resolution delta, not the hotfix.** The
20
+ hotfix records itself in its **own** minimal host through Step 1.8 — follow-up
21
+ or standalone, never an in-flight feature — and that host is where
22
+ `reconciled ({merged-hotfix-hash})`, the identity citation and the per-tier
23
+ trace live. If the hotfix has not been documented yet, run Step 1.8 for it
24
+ first and come back; do **not** absorb it into this feature, whose ordinary
25
+ checkpoints would record none of that. What is left for this host is only what
26
+ *choosing between the two versions* changed. **Classify that by the cascade,
27
+ then record what the classification calls for:**
28
+
29
+ - **No tracked delta** — the cascade's **below workflow** level. It stays in
30
+ the integration commit message; do **not** manufacture a row or a document.
31
+ Nothing to validate, so nothing changes below. This is the common case.
32
+ - **A tracked delta (T3 or above), phase-bearing host** — record it in this
33
+ host and let it ride the normal checkpoints, then run
34
+ `references/finish-feature-flow.md` Step 1's checklist against the result. A
35
+ phase-bearing host has no fixed commit count, so an extra checkpoint is
36
+ ordinary.
37
+ - **A tracked delta (T3 or above), minimal (zero-phase) host** — it does
38
+ **not** go into this host: the two-commit lifecycle has one implementation
39
+ checkpoint and one closeout, and every Lightweight Changes row must belong
40
+ to that first commit. This host closes on what it already carries, and the
41
+ delta is routed **after** Step 4 archives it — by the **A tracked delta (T3
42
+ or above)** bullet of § After closeout, the same route every post-closeout
43
+ leftover takes. Do **not** route it now:
44
+ you are mid-closeout, and routing would open a second host before this one
45
+ is sealed. Note it, finish the closeout, then take § After closeout's route —
46
+ back through `/dflow:modify-existing`, which picks the host the way it
47
+ always does. Do not decide that here: by then this feature is *completed*,
48
+ so the normal completed-feature disambiguation applies and the answer may be
49
+ a follow-up or a standalone host.
50
+
51
+ Classification decides, never "is it worth writing down". After closeout the
52
+ host is frozen — § After closeout says what is left over, and applies the same
53
+ cascade.
54
+
55
+ ## After closeout
56
+
57
+ **You are here when** `references/finish-feature-flow.md` Step 5 sent you.
58
+
59
+ **A mainline hotfix that overlapped this feature.** A T2 / T3 post-hoc hotfix
60
+ (`modify-existing-flow.md` Step 1.8) records itself in its own host, so when
61
+ this feature's branch finally meets the mainline both may have touched the same
62
+ code, and whoever merges picks between two existing versions. By the time you
63
+ read this, **Step 4 has already archived and committed this feature — its host
64
+ is frozen.** Classify whatever is left by the cascade (`AI-AGENT-GUIDE.md`
65
+ § Ceremony Scaling), never by "is it worth writing down":
66
+
67
+ - **No conflict, or a resolution with no tracked delta** — it stays in the
68
+ integration commit message. That is the cascade's **below workflow** level:
69
+ do not manufacture a document, and do not reopen this feature.
70
+ - **A tracked delta (T3 or above)** — completed features are frozen, so it goes
71
+ where every post-completion change goes: back through
72
+ `/dflow:modify-existing`, which opens a follow-up or standalone host for it.
73
+ Do **not** edit the archived `_index.md`.
74
+ - **The resolution moves system state** — if choosing between the two versions
75
+ changes a business rule, a documented behaviour, an event, or the domain
76
+ model, the owning document (`rules.md` / `behavior.md` / `events.md` /
77
+ `models.md`) **must** be updated. That update is itself a tracked change and
78
+ takes the route above; system-state truth is never below workflow.
79
+ - **It is bigger than a merge** — if resolving it means *new or changed*
80
+ behaviour rather than choosing between two that already exist, it is not a
81
+ merge question at all: run it through the cascade and open the flow its tier
82
+ calls for.
83
+
84
+ **Reconciling before closeout is simpler.** If the branches meet while this
85
+ feature is still in flight — a rebase onto the mainline, say — handle it then
86
+ as ordinary in-flow work — but **which host takes it depends on this host's
87
+ shape**. A **phase-bearing** host absorbs a tracked delta (T3 or above) and
88
+ rides the normal checkpoints; a **minimal (zero-phase)** host **cannot** once
89
+ checkpoint 1 has landed, because every Lightweight Changes row must belong to
90
+ that commit — it closes on what it carries and the delta is routed afterwards.
91
+ No tracked delta stays below workflow, in the integration commit message.
92
+ § Before closeout states that whole side in full, minimal-host branch
93
+ included. The four bullets above decide it whichever side of closeout you are on —
94
+ they are principles, not a checklist; the situation is rare and varied, so use
95
+ judgement.
@@ -0,0 +1,45 @@
1
+ # Correcting Checkpoint 1's Own Record — Greenfield Clean Architecture
2
+
3
+ Branch file of `references/finish-feature-minimal-host.md`. It **adds** the
4
+ repair for one case that file's working-tree check blocks; it does not restate
5
+ or override anything in that file.
6
+
7
+ **You are here because** that file's `nothing that constitutes the change
8
+ itself is still uncommitted` check blocked on a correction to checkpoint 1's
9
+ own record — it owns that judgement — or because
10
+ `references/modify-existing-post-hoc-hotfix.md` item 6 found that a post-hoc
11
+ record names a different fix.
12
+
13
+ The correction belongs in checkpoint 1 itself, and whether it can go there
14
+ depends on where checkpoint 1 stands now. Report the case that is true and give
15
+ the developer its repair:
16
+
17
+ - **Not pushed, and checkpoint 1 is `HEAD`** (`git rev-parse HEAD` prints
18
+ checkpoint 1's hash) — first set every entry that holds checkpoint 1's hash
19
+ back to what checkpoint 1 has (`git show HEAD:{path}`); the refill below
20
+ writes them again. Then stage the correction alone (in `_index.md`, `git add
21
+ -p` only its hunk: the Resume Pointer rides the closeout commit), check that
22
+ `git diff --cached` shows nothing else, and `git commit --amend`. Then write
23
+ the new hash into every entry that names checkpoint 1 — the Checkpoint Log
24
+ `committed (...)` and each row's `Commit` cell. An entry left on the old hash
25
+ fails hash evidence (b).
26
+ - **Not pushed, but a later commit sits on top of checkpoint 1** — stop:
27
+ rewriting an earlier commit is the developer's to do.
28
+ - **Already pushed** — stop and leave it to the developer. Rewriting a pushed
29
+ commit is the team's call (refill the entries as above if they do). The other
30
+ way is to commit the correction on its own: add no Checkpoint Log row for it
31
+ (a second row blocks), and ask for it to be named in the PR description — it
32
+ departs from the two-commit lifecycle, and
33
+ `references/pr-review-checklist.md`'s whole-history item sees it only when it
34
+ touches this host's directory.
35
+
36
+ **A post-hoc host's `reconciled (...)`** names the hotfix, not checkpoint 1, so
37
+ refilling after an amend leaves it as it is — **unless the correction changes
38
+ which fix the record names** (`references/modify-existing-post-hoc-hotfix.md`
39
+ item 6, "The record names a different fix"). Then `reconciled (...)` names the
40
+ wrong fix too. Item 3 wrote it before checkpoint 1, so checkpoint 1 carries it:
41
+ correct it to the right fix's commit — the one item 3 says to record — as part
42
+ of the same correction, whichever way that lands (the amend, the developer's
43
+ rewrite, or the correction's own commit). Put that commit through item 6's test
44
+ before closeout continues; that item gives the repair if (b) fails for it as
45
+ well.