dflow-sdd-ddd 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +824 -1
- package/CONTRIBUTING.md +16 -10
- package/README.en.md +156 -200
- package/README.md +89 -144
- package/TEMPLATE-COVERAGE.md +15 -8
- package/TEMPLATE-LANGUAGE-GLOSSARY.md +15 -1
- package/bin/dflow.js +36 -4
- package/docs/commands.en.md +110 -0
- package/docs/commands.md +101 -0
- package/docs/doctor-uncertainty.en.md +212 -0
- package/docs/doctor-uncertainty.md +212 -0
- package/docs/evaluating-dflow.en.md +29 -11
- package/docs/evaluating-dflow.md +8 -6
- package/docs/npm-publish-checklist.md +3 -1
- package/docs/release-versioning-policy.md +8 -2
- package/docs/upgrading.en.md +196 -0
- package/docs/upgrading.md +197 -0
- package/docs/using-with-claude-code.en.md +25 -10
- package/docs/using-with-claude-code.md +20 -7
- package/docs/using-with-codex.en.md +18 -6
- package/docs/using-with-codex.md +16 -5
- package/docs/using-with-github-copilot.en.md +25 -10
- package/docs/using-with-github-copilot.md +21 -8
- package/lib/doc-shapes.json +997 -0
- package/lib/doctor-checks.js +2654 -0
- package/lib/init.js +3583 -107
- package/lib/render-diagrams.js +1474 -0
- package/lib/render.js +865 -49
- package/package.json +2 -2
- package/templates/brownfield/references/drift-verification.md +4 -0
- package/templates/brownfield/references/finish-feature-flow.md +635 -88
- package/templates/brownfield/references/finish-feature-follow-up.md +60 -0
- package/templates/brownfield/references/finish-feature-minimal-host.md +406 -0
- package/templates/brownfield/references/finish-feature-post-hoc-hotfix.md +95 -0
- package/templates/brownfield/references/git-integration.md +160 -15
- package/templates/brownfield/references/init-project-flow.md +26 -4
- package/templates/brownfield/references/modify-existing-flow.md +412 -87
- package/templates/brownfield/references/modify-existing-follow-up.md +121 -0
- package/templates/brownfield/references/modify-existing-post-hoc-hotfix.md +82 -0
- package/templates/brownfield/references/new-feature-flow.md +61 -6
- package/templates/brownfield/references/new-phase-flow.md +57 -7
- package/templates/brownfield/references/pr-review-checklist.md +303 -10
- package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +158 -34
- package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +1 -1
- package/templates/brownfield/scaffolding/Git-principles-gitflow.md +75 -6
- package/templates/brownfield/scaffolding/Git-principles-trunk.md +82 -8
- package/templates/brownfield/scaffolding/_conventions.md +50 -28
- package/templates/brownfield/scaffolding/_overview.md +1 -0
- package/templates/brownfield/templates/_index.md +151 -7
- package/templates/brownfield/templates/analysis.md +79 -0
- package/templates/brownfield/templates/behavior.md +1 -0
- package/templates/brownfield/templates/context-definition.md +1 -0
- package/templates/brownfield/templates/context-map.md +2 -1
- package/templates/brownfield/templates/glossary.md +1 -0
- package/templates/brownfield/templates/lightweight-spec.md +154 -11
- package/templates/brownfield/templates/models.md +1 -0
- package/templates/brownfield/templates/phase-spec.md +9 -1
- package/templates/brownfield/templates/rules.md +1 -0
- package/templates/brownfield/templates/tech-debt.md +1 -0
- package/templates/common/references/ddd-modeling-guide.md +33 -16
- package/templates/{greenfield → common}/references/dflow-feedback-flow.md +2 -1
- package/templates/common/references/flow-rationale-registry.md +130 -0
- package/templates/common/skill/SKILL.md +13 -11
- package/templates/greenfield/references/drift-verification.md +4 -0
- package/templates/greenfield/references/finish-feature-flow.md +625 -89
- package/templates/greenfield/references/finish-feature-follow-up.md +60 -0
- package/templates/greenfield/references/finish-feature-minimal-host.md +363 -0
- package/templates/greenfield/references/finish-feature-post-hoc-hotfix.md +95 -0
- package/templates/greenfield/references/git-integration.md +148 -15
- package/templates/greenfield/references/init-project-flow.md +28 -8
- package/templates/greenfield/references/modify-existing-flow.md +378 -85
- package/templates/greenfield/references/modify-existing-follow-up.md +103 -0
- package/templates/greenfield/references/modify-existing-post-hoc-hotfix.md +82 -0
- package/templates/greenfield/references/new-feature-flow.md +67 -4
- package/templates/greenfield/references/new-phase-flow.md +56 -7
- package/templates/greenfield/references/pr-review-checklist.md +287 -8
- package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +153 -32
- package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +5 -2
- package/templates/greenfield/scaffolding/Git-principles-gitflow.md +74 -6
- package/templates/greenfield/scaffolding/Git-principles-trunk.md +88 -12
- package/templates/greenfield/scaffolding/_conventions.md +50 -28
- package/templates/greenfield/scaffolding/_overview.md +6 -2
- package/templates/greenfield/templates/_index.md +137 -7
- package/templates/greenfield/templates/aggregate-design.md +1 -0
- package/templates/greenfield/templates/analysis.md +79 -0
- package/templates/greenfield/templates/behavior.md +1 -0
- package/templates/greenfield/templates/context-definition.md +1 -0
- package/templates/greenfield/templates/context-map.md +2 -1
- package/templates/greenfield/templates/events.md +4 -1
- package/templates/greenfield/templates/glossary.md +1 -0
- package/templates/greenfield/templates/lightweight-spec.md +154 -11
- package/templates/greenfield/templates/models.md +1 -0
- package/templates/greenfield/templates/phase-spec.md +9 -1
- package/templates/greenfield/templates/rules.md +1 -0
- package/templates/greenfield/templates/tech-debt.md +1 -0
- package/templates/brownfield/references/dflow-feedback-flow.md +0 -251
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Step 1.6: Create Follow-up Feature — Brownfield Progressive Extraction
|
|
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
|
|
17
|
+
takes the full new-feature machinery below; a **T2 / T3** follow-up — or a
|
|
18
|
+
**baseline capture**, which is **tier-exempt** (observation-only, no cascade
|
|
19
|
+
tier, and reaches here via Part A's observation-only routing rather than the
|
|
20
|
+
Step 1.5 A/B/C prompt) — takes the **minimal (zero-phase) variant** described
|
|
21
|
+
after the reverse-link step, which does **not** delegate new-feature Step 4's
|
|
22
|
+
unconditional first phase-spec. A **post-hoc hotfix** whose host linkage
|
|
23
|
+
Step 1.8 resolved to *follow-up* also arrives here (likewise without the
|
|
24
|
+
Step 1.5 prompt, and always T2 / T3, so always the minimal variant); its
|
|
25
|
+
first checkpoint keeps the `implementation` name but carries Result
|
|
26
|
+
`reconciled (...)` per Step 1.8.
|
|
27
|
+
|
|
28
|
+
- **New SPEC-ID** (today's date sequence — do NOT reuse the original
|
|
29
|
+
SPEC-ID): e.g. original `SPEC-20260201-003-訂單折扣` → follow-up
|
|
30
|
+
`SPEC-20260424-002-訂單折扣-匯率擴充` (or any new slug)
|
|
31
|
+
- **New slug**: not required to equal the original slug; pick whatever
|
|
32
|
+
best describes the follow-up scope
|
|
33
|
+
- **`_index.md` Metadata**: `follow-up-of: {原 SPEC-ID}` is REQUIRED
|
|
34
|
+
(uncomment the optional line in the template; can be a YAML array if
|
|
35
|
+
the follow-up spans multiple originals)
|
|
36
|
+
- **`_index.md` Goals & Scope** auto-prepended note:
|
|
37
|
+
```
|
|
38
|
+
> 本 feature 為 `{原 SPEC-ID}-{原 slug}` 的 follow-up,原 feature
|
|
39
|
+
> 完成於 `{date}`,詳見 `completed/{原 SPEC-ID}-{原 slug}/_index.md`。
|
|
40
|
+
```
|
|
41
|
+
- **`_index.md` Current BR Snapshot baseline** (**BC-bearing follow-up only**):
|
|
42
|
+
if the follow-up touches a bounded context, AI reads the BC's
|
|
43
|
+
`dflow/specs/domain/{context}/rules.md` and inherits the BRs that are
|
|
44
|
+
in-scope for this follow-up. Mark each inherited row with First Seen
|
|
45
|
+
= `inherited from rules.md` and Last Updated = (empty until the new
|
|
46
|
+
feature's first phase Delta — or, for a minimal follow-up, its
|
|
47
|
+
lightweight-spec's delta — touches it). For a **no-BC follow-up** (the
|
|
48
|
+
minimal variant on a completed no-BC host), leave the Current BR Snapshot
|
|
49
|
+
**empty** — do not read or fabricate a BC's `rules.md`.
|
|
50
|
+
**A baseline capture is the other exception**, and it names a real bounded
|
|
51
|
+
context, so state it rather than leaving it to the BC-bearing rule: a
|
|
52
|
+
completed-only baseline host is tier-exempt and observation-only — it carries
|
|
53
|
+
no BR delta, and the capture may be the very thing that creates that BC's
|
|
54
|
+
`rules.md`. Leave its Current BR Snapshot **empty**, exactly as the
|
|
55
|
+
no-feature baseline route does (Step 1.7 step 3, "fill it only if the change
|
|
56
|
+
carries a BR delta"). The capture writes the BC layer directly, so the host's
|
|
57
|
+
snapshot is not its record and closeout has nothing to sync. **Both baseline
|
|
58
|
+
routes behave identically here** — lineage decides the host shape, never the
|
|
59
|
+
snapshot policy.
|
|
60
|
+
|
|
61
|
+
**Reverse-link into the old `_index.md`**: AI also updates
|
|
62
|
+
`dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md` —
|
|
63
|
+
uncomment the Follow-up Tracking section (if not already present) and
|
|
64
|
+
add a row. When `follow-up-of` names **more than one** original (it may be a
|
|
65
|
+
YAML array), do this in **every** one of them; a parent left without its row
|
|
66
|
+
never gets the `absent → in-progress → completed` transition the contract
|
|
67
|
+
requires, and on a **minimal** follow-up host finish-feature Step 1 blocks
|
|
68
|
+
closeout on it (that check is scoped "Minimal host (zero-phase), follow-up
|
|
69
|
+
only" and proves the *opening* half; on a phase-bearing follow-up Step 6 still
|
|
70
|
+
flips and verifies the closing half, but nothing checks that the row was ever
|
|
71
|
+
opened as `in-progress`):
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
| {新 SPEC-ID} | {新 slug} | {today} | in-progress |
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This update is **part of the same change set** as opening the host. For a
|
|
78
|
+
**T1** follow-up the AI may offer to commit the new host and this initial
|
|
79
|
+
`absent → in-progress` reverse-link together (commit message should mention
|
|
80
|
+
"Add follow-up reference to `{新 SPEC-ID}`"). For the **minimal (T2 / T3, or
|
|
81
|
+
baseline) variant** the AI does **not** offer a separate host-open commit — the
|
|
82
|
+
initial reverse-link edit rides along in the first host checkpoint
|
|
83
|
+
(implementation, or `spec-baseline` for a baseline follow-up; see the variant
|
|
84
|
+
paragraph below), keeping the follow-up at exactly two host checkpoints. The reverse link is a derived index — the new feature's
|
|
85
|
+
`follow-up-of` field is the authoritative source.
|
|
86
|
+
|
|
87
|
+
After a **T1** follow-up feature is set up, this flow hands off to the
|
|
88
|
+
`/dflow:new-phase` flow (or stays in this flow at Step 2 for the first
|
|
89
|
+
phase's content).
|
|
90
|
+
|
|
91
|
+
**Minimal (zero-phase) follow-up variant (T2 / T3 / baseline).** When the
|
|
92
|
+
follow-up change is itself lightweight — or is an observation-only **baseline
|
|
93
|
+
capture**, which is tier-exempt rather than lightweight and reaches this
|
|
94
|
+
variant from Step 1.6's opening paragraph — do **not** delegate new-feature
|
|
95
|
+
Step 4 (which would create an unconditional first phase-spec). Instead treat
|
|
96
|
+
the follow-up host exactly like a standalone minimal host — open it via
|
|
97
|
+
**Step 1.7's
|
|
98
|
+
mechanics, steps 2–4 only** (assign identifiers + collision check, create the
|
|
99
|
+
minimal `_index.md` with an empty Phase Specs table, branch gate **by change
|
|
100
|
+
class**: `bugfix/BUG-{NUMBER}-{slug}` for a functional bug,
|
|
101
|
+
`feature/{SPEC-ID}-{slug}` otherwise — this **overrides** new-feature's
|
|
102
|
+
hardcoded `feature/` branch). Step 1.7's **step 1 does not apply**: it is the
|
|
103
|
+
standalone-classification gate, and this caller has already been classified as
|
|
104
|
+
a follow-up. Everything Step 1.7 states **after** step 4 *does* apply
|
|
105
|
+
unchanged — every artifact's row written before checkpoint 1, the
|
|
106
|
+
implementation-path declaration, tier-aware "Finalize + close", and the two
|
|
107
|
+
commit-evidence surfaces — because finish-feature reads for all of it on a
|
|
108
|
+
follow-up host exactly as on a standalone one. Then record the change's
|
|
109
|
+
artifacts — a T2 lightweight-spec, one
|
|
110
|
+
or more T3 inline rows, or both for a compound follow-up (Step 1.7's "minimal
|
|
111
|
+
means zero-phase, not one-artifact") — or, for a **completed-only baseline
|
|
112
|
+
capture**, record it per Step 1.7's baseline mechanics (the `spec-baseline`
|
|
113
|
+
checkpoint and a `Tier = baseline` row) — and close with
|
|
114
|
+
`/dflow:finish-feature`. The lifecycle is **two host checkpoints**
|
|
115
|
+
(implementation — or `spec-baseline` for a baseline follow-up — then closeout)
|
|
116
|
+
**plus one post-closeout reverse-link flip tracking commit** — the flip (the original feature's Follow-up Tracking row
|
|
117
|
+
`in-progress → completed`, done by `/dflow:finish-feature` Step 6) is a
|
|
118
|
+
**sanctioned post-completion mutation, not a host checkpoint**, and is
|
|
119
|
+
recorded in **neither** the follow-up host's Checkpoint Log **nor** the
|
|
120
|
+
original feature's. Option C of Step 1.5 ("a follow-up containing only one
|
|
121
|
+
T3 row") lands here.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Step 1.8: Hotfix T2 / T3 Post-Hoc — Brownfield Progressive Extraction
|
|
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
|
+
Do not skip this choice. If a feature that was in flight turns out to have
|
|
36
|
+
touched the same code, that is a **merge** question, settled when the
|
|
37
|
+
branches actually meet — see `finish-feature-flow.md` Step 5.
|
|
38
|
+
2. **Reconcile, do not re-run.** The implementation already happened on the
|
|
39
|
+
(now often deleted) hotfix branch. Do **not** reopen an implementation
|
|
40
|
+
branch for it or redo the work. The documentation is recorded on **this
|
|
41
|
+
host's own branch**, cut by change class at Step 1.7 step 4 (or at Step
|
|
42
|
+
1.6's delegation to it) like any other minimal host — that branch *is* the
|
|
43
|
+
**post-hoc branch** the rest of this step names, and the value `_index.md`
|
|
44
|
+
`branch:` records.
|
|
45
|
+
3. **Implementation checkpoint Result = `reconciled ({merged-hotfix-hash})`.**
|
|
46
|
+
In the host's Checkpoint Log the implementation row's Result is
|
|
47
|
+
`reconciled (...)` — the value meaning "this checkpoint documents an
|
|
48
|
+
already-merged change" — carrying the merged hotfix commit's hash. It sits
|
|
49
|
+
alongside the usual `committed` / `skipped` / `failed` Results (see
|
|
50
|
+
`references/git-integration.md` § Commit Checkpoints, Branch Gate & AI
|
|
51
|
+
Commits). That hash belongs to the **hotfix**, so it is **not** evidence
|
|
52
|
+
that this host's own first commit landed — the documentation work still owes
|
|
53
|
+
checkpoint 1 a real commit of its own (item 4), made **before** closeout.
|
|
54
|
+
Committing the documentation together with closeout collapses the host to
|
|
55
|
+
one commit and fails finish-feature Step 1.
|
|
56
|
+
|
|
57
|
+
**You are asserting this hash, not deriving it.** Nothing in the repository
|
|
58
|
+
records which commit was the hotfix, so no check in this flow can confirm
|
|
59
|
+
it — finish-feature's reconciliation gate is explicit that it tests
|
|
60
|
+
plausibility only. So state the identity
|
|
61
|
+
and **cite what it rests on**: the PR, incident, or tracker reference that
|
|
62
|
+
identifies this fix. Record the citation alongside the per-tier trace
|
|
63
|
+
(item 4). An **uncited** hash blocks closeout —
|
|
64
|
+
`references/pr-review-checklist.md` is what confirms the identity, and it
|
|
65
|
+
needs something to confirm against.
|
|
66
|
+
4. **Per-tier trace.** A **T2** records the merged-hotfix branch in its
|
|
67
|
+
lightweight-spec `hotfix-branch:` field; a **T3** marks its `_index.md`
|
|
68
|
+
Lightweight Changes row Description as a hotfix (no new field, no T3 spec
|
|
69
|
+
file). Item 3's identity citation goes in the same place — beside
|
|
70
|
+
`hotfix-branch:` for a T2, in the row Description for a T3 — so the trace
|
|
71
|
+
and the thing it rests on stay together. In **both** tiers the host's
|
|
72
|
+
Lightweight Changes row carries a `Commit` value, and that value is the
|
|
73
|
+
**post-hoc documentation commit**
|
|
74
|
+
hash (the row is produced by the documentation work) — **not** the
|
|
75
|
+
merged hotfix hash, which already lives in the `reconciled (...)` checkpoint
|
|
76
|
+
above; the two have different provenance and must not be conflated. This
|
|
77
|
+
row hash is what finish-feature Step 1 reads to prove the documentation
|
|
78
|
+
commit exists separately from closeout, so fill it in as soon as that
|
|
79
|
+
commit lands.
|
|
80
|
+
5. **Branch equality** for the host is asserted against the **post-hoc
|
|
81
|
+
documentation branch** (the `_index.md` `branch:` value), never the deleted
|
|
82
|
+
hotfix branch.
|
|
@@ -12,7 +12,7 @@ Crossing any step gate above also updates the host feature's `_index.md` Resume
|
|
|
12
12
|
|
|
13
13
|
All other step transitions are **step-internal**: announce "Step N complete, entering Step N+1" and proceed without waiting. See AI-AGENT-GUIDE.md § Workflow Transparency for the full transparency protocol and confirmation signals.
|
|
14
14
|
|
|
15
|
-
**Ceremony**: this flow always defaults to **T1 Heavy** — the first phase of a brand-new feature is by definition a full SDD cycle. Tier judgement (T1 / T2 / T3)
|
|
15
|
+
**Ceremony**: this flow always defaults to **T1 Heavy** — the first phase of a brand-new feature is by definition a full SDD cycle. Tier judgement (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.
|
|
16
16
|
|
|
17
17
|
## Step 1: Intake — Understand the Request
|
|
18
18
|
|
|
@@ -25,7 +25,26 @@ Ask these questions (naturally, not as a checklist dump):
|
|
|
25
25
|
|
|
26
26
|
1. **What's the feature?** Get a plain-language description.
|
|
27
27
|
2. **Who needs it?** Identify the stakeholder or user role.
|
|
28
|
-
3. **Why now?** Understand priority and urgency
|
|
28
|
+
3. **Why now?** Understand priority and urgency.
|
|
29
|
+
|
|
30
|
+
> **`/dflow:new-feature` is always T1 — it does not re-run the cascade.**
|
|
31
|
+
> Entering here declares "genuinely new work" (a new capability, page, or
|
|
32
|
+
> navigable surface). If the request is really a **modification** of existing
|
|
33
|
+
> behaviour — a tweak, a bug fix, an appearance change, or anything that would
|
|
34
|
+
> land at T2 / T3 / below-workflow — it belongs in `/dflow:modify-existing`,
|
|
35
|
+
> whose Step 1 cascade (step 0) is the only place a misroute is caught. So
|
|
36
|
+
> sanity-check at intake: if this looks like a small change to something that
|
|
37
|
+
> already exists, redirect to `/dflow:modify-existing` rather than minting a T1
|
|
38
|
+
> feature. ⚠ **Do not redirect a request that already came from there.** A
|
|
39
|
+
> `/dflow:modify-existing` or `/dflow:bug-fix` request the cascade landed at T1
|
|
40
|
+
> — including one a project convention escalated to T1, which the overlay may
|
|
41
|
+
> only ever raise — is routed here **by** step 0 and has already been caught;
|
|
42
|
+
> sending it back is a loop, because step 0 provably returns the same answer.
|
|
43
|
+
> `AI-AGENT-GUIDE.md` § Ceremony Scaling's T1 row says so directly. The guard
|
|
44
|
+
> is for a request that arrived at `/dflow:new-feature` **without** passing the
|
|
45
|
+
> cascade. (A follow-up to a *completed* feature is the one new-feature-shaped
|
|
46
|
+
> case that may still be lightweight — it arrives through `modify-existing`
|
|
47
|
+
> Step 1.6's minimal variant, not here.)
|
|
29
48
|
|
|
30
49
|
Then check existing assets:
|
|
31
50
|
- Search `dflow/specs/domain/` for related concepts
|
|
@@ -99,8 +118,11 @@ Walk through these questions:
|
|
|
99
118
|
- **What are the key nouns?** → Potential Entities or Value Objects
|
|
100
119
|
- **What are the key verbs?** → Potential Domain Services or Entity behaviors
|
|
101
120
|
- **What are the rules/constraints?** → Business Rules to document
|
|
102
|
-
- **What are the states/statuses?** → State machines to model
|
|
121
|
+
- **What are the states/statuses?** → State machines to model, recorded in `analysis.md`
|
|
103
122
|
- **What external data is needed?** → Interfaces to define
|
|
123
|
+
- **What crosses a bounded context, and what does each step hand to the next?** → An ordered cross-context flow (always the domain-root copy)
|
|
124
|
+
- **Which figures are derived rather than stored?** → A read model definition
|
|
125
|
+
- **Who reaches this feature, and what data scope does each role see?** → A role × function entry (always the domain-root copy)
|
|
104
126
|
|
|
105
127
|
If one concept gathers rules / invariants that must hold together — **a state
|
|
106
128
|
machine over its lifecycle, or invariants spanning several of its fields /
|
|
@@ -128,6 +150,8 @@ For each new concept:
|
|
|
128
150
|
2. Check if it already exists in models.md — extend if needed
|
|
129
151
|
3. If entirely new, add to the appropriate context's models.md
|
|
130
152
|
|
|
153
|
+
For each of the system-level answers above — the state machines included: record it 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.
|
|
154
|
+
|
|
131
155
|
If foundational domain docs are missing, create them from templates before writing content:
|
|
132
156
|
- `dflow/specs/domain/glossary.md` → `templates/glossary.md`
|
|
133
157
|
- `dflow/specs/domain/{context}/models.md` → `templates/models.md`
|
|
@@ -137,7 +161,7 @@ If foundational domain docs are missing, create them from templates before writi
|
|
|
137
161
|
**→ Step Gate: Step 3 → Step 3.5**
|
|
138
162
|
|
|
139
163
|
Announce to developer:
|
|
140
|
-
> "Domain concepts captured. Before I create
|
|
164
|
+
> "Domain concepts captured. 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."
|
|
141
165
|
|
|
142
166
|
Wait for confirmation before entering Step 3.5.
|
|
143
167
|
|
|
@@ -186,7 +210,31 @@ If the developer asks to change the slug, re-propose and re-confirm.
|
|
|
186
210
|
|
|
187
211
|
## Step 4: Write the Spec
|
|
188
212
|
|
|
189
|
-
|
|
213
|
+
> **Minimal hosts do not come here (defensive guard).** Step 4 creates a first
|
|
214
|
+
> phase-spec, which only a genuinely **T1** new feature has. A **minimal host**
|
|
215
|
+
> is zero-phase and is recorded through its own path in `modify-existing-flow.md`,
|
|
216
|
+
> **not here**: Step 1.6 explicitly does **not** delegate to this step. If you
|
|
217
|
+
> reached Step 4 while handling a minimal / zero-phase host, **stop and re-enter
|
|
218
|
+
> `modify-existing-flow.md` at Step 1** — *not* at Step 1.6, 1.7 or 1.8.
|
|
219
|
+
>
|
|
220
|
+
> Those steps each assume work Step 1 has already done: Part A has decided the
|
|
221
|
+
> tier (or routed an observation-only **baseline capture**, which is tier-exempt
|
|
222
|
+
> and has its own two routes), and Part B has done the host linkage. An entry
|
|
223
|
+
> that arrived *here* ran neither, so recovering into one of them skips the
|
|
224
|
+
> authoritative cascade and the completed-feature scan — which is how a change
|
|
225
|
+
> that should have been a follow-up gets archived as an unlinked standalone.
|
|
226
|
+
> Step 1 routes it from there, and its Part B hotfix callout is what sends a
|
|
227
|
+
> **T2 / T3 post-hoc** to Step 1.8 — the only route that attaches `reconciled
|
|
228
|
+
> ({merged-hotfix-hash})`, the identity citation, and the per-tier hotfix
|
|
229
|
+
> trace, all of which a host recovered straight into 1.6 / 1.7 would silently
|
|
230
|
+
> lack. (A **T1** post-hoc is not a minimal host and is not this guard's
|
|
231
|
+
> business.)
|
|
232
|
+
>
|
|
233
|
+
> Either way, do not create a phase-spec, and do not treat this step as a
|
|
234
|
+
> zero-phase execution path.
|
|
235
|
+
|
|
236
|
+
Create the **feature directory** + **`_index.md`** + **first phase-spec** (T1
|
|
237
|
+
new feature):
|
|
190
238
|
|
|
191
239
|
```
|
|
192
240
|
dflow/specs/features/active/{SPEC-ID}-{slug}/
|
|
@@ -194,6 +242,8 @@ dflow/specs/features/active/{SPEC-ID}-{slug}/
|
|
|
194
242
|
└── phase-spec-{YYYY-MM-DD}-{slug}.md
|
|
195
243
|
```
|
|
196
244
|
|
|
245
|
+
> **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).
|
|
246
|
+
|
|
197
247
|
1. **Create the directory**: `dflow/specs/features/active/{SPEC-ID}-{slug}/`
|
|
198
248
|
2. **Create `_index.md`** using `templates/_index.md`:
|
|
199
249
|
- Metadata: fill `spec-id`, `slug`, `status: in-progress`, `created`, `branch`
|
|
@@ -386,7 +436,7 @@ AI reports `✓` / `✗` for every item before touching docs. Items marked *(pos
|
|
|
386
436
|
- [ ] Every `EC-*` edge case is handled
|
|
387
437
|
- [ ] Domain layer has **no** delivery-framework references (grep `src/Domain/`)
|
|
388
438
|
- [ ] *(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`)
|
|
389
|
-
- [ ] *(post-8.3)* `dflow/specs/domain/{context}/rules.md` `
|
|
439
|
+
- [ ] *(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.
|
|
390
440
|
|
|
391
441
|
If any item fails, report the gap and pause — don't proceed to 8.2.
|
|
392
442
|
|
|
@@ -404,13 +454,18 @@ Ask these one-by-one; do not dump all five at once.
|
|
|
404
454
|
|
|
405
455
|
### 8.3 Documentation updates
|
|
406
456
|
|
|
457
|
+
> **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).
|
|
458
|
+
|
|
407
459
|
- [ ] `dflow/specs/domain/glossary.md` — new terms added
|
|
460
|
+
- [ ] `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)
|
|
408
461
|
- [ ] `dflow/specs/domain/{context}/models.md` — model definitions updated
|
|
462
|
+
- [ ] `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)
|
|
409
463
|
- [ ] `dflow/specs/domain/{context}/rules.md` — business rules updated
|
|
410
464
|
- [ ] `dflow/specs/domain/{context}/behavior.md` — merge completed spec's Given/When/Then scenarios into consolidated behavior. Sub-steps:
|
|
411
465
|
- Promote any Activity 3 (Spec Writing) draft sections (from B3 mid-sync) to formal sections
|
|
412
466
|
- Update the corresponding `rules.md` anchor's `last-updated` date (B4)
|
|
413
467
|
- [ ] `behavior.md` draft cleanup — if the spec was abandoned mid-way, keep the `## 提案中變更` section's history or explicitly REMOVE it
|
|
468
|
+
- [ ] `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.
|
|
414
469
|
- [ ] `dflow/specs/migration/tech-debt.md` — tech debt discovered during implementation recorded
|
|
415
470
|
|
|
416
471
|
### 8.4 Archival
|
|
@@ -59,7 +59,32 @@ AI must locate the target feature and load its current state:
|
|
|
59
59
|
completed = frozen-history semantic and produces confusing dir-rename
|
|
60
60
|
history. The follow-up path is the only correct route.
|
|
61
61
|
|
|
62
|
-
3. **
|
|
62
|
+
3. **Refuse if the target is a minimal (zero-phase) host**
|
|
63
|
+
|
|
64
|
+
Decide this from the **persisted shape** — the same selector closeout
|
|
65
|
+
uses: an **empty Phase Specs table and no `phase-spec-*` file** in the host
|
|
66
|
+
directory. Such a host records a small standalone or follow-up change and
|
|
67
|
+
is *defined* by carrying no phase. Adding one does not extend it; it turns
|
|
68
|
+
the host into a phase-bearing feature, and closeout will then check it as
|
|
69
|
+
one. Refuse with:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
"`{SPEC-ID}-{slug}` is a minimal (zero-phase) host — it records a
|
|
73
|
+
lightweight change and carries no phase-specs, so a phase cannot be
|
|
74
|
+
added to it.
|
|
75
|
+
|
|
76
|
+
If this is genuinely new T1 work, run /dflow:new-feature. If it is
|
|
77
|
+
another small change, run /dflow:modify-existing — its Step 1 decides
|
|
78
|
+
the tier and finds or opens the right host for it."
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Do NOT create a first phase-spec here to "make the host usable", and do
|
|
82
|
+
not jump into `modify-existing-flow.md` Step 1.6, 1.7 or 1.8 from here:
|
|
83
|
+
each of those assumes Step 1's tier decision and host-linkage scan have
|
|
84
|
+
already run, and entering one directly skips both. Send the developer to
|
|
85
|
+
Step 1, exactly as `new-feature-flow.md` Step 4's guard does.
|
|
86
|
+
|
|
87
|
+
4. **Load context for the new phase**
|
|
63
88
|
- Read the feature's `_index.md` — Metadata, Goals & Scope, Phase Specs,
|
|
64
89
|
Current BR Snapshot, Resume Pointer
|
|
65
90
|
- Read the most recent phase-spec to understand where the prior phase
|
|
@@ -71,7 +96,7 @@ AI must locate the target feature and load its current state:
|
|
|
71
96
|
not visible on this branch — if the incoming phase scope overlaps one
|
|
72
97
|
of them, surface it before writing the phase-spec.
|
|
73
98
|
|
|
74
|
-
|
|
99
|
+
5. **Branch gate — ensure you are on this feature's branch (before any commit)**
|
|
75
100
|
|
|
76
101
|
This phase's commits must land on the active feature's
|
|
77
102
|
`feature/{SPEC-ID}-{slug}` branch. If you are not already on it (you
|
|
@@ -111,8 +136,19 @@ Walk the developer through what the new phase covers:
|
|
|
111
136
|
re-read from `references/ddd-modeling-guide.md` § "Revising an Established
|
|
112
137
|
Model" (match recorded re-evaluation conditions; record proceed / split /
|
|
113
138
|
rename in the phase-spec).
|
|
114
|
-
4. **
|
|
115
|
-
|
|
139
|
+
4. **System-level knowledge?** Does this phase add, change, or uncover an
|
|
140
|
+
ordered cross-context flow (always the domain-root copy), the lifecycle a
|
|
141
|
+
status field moves through, a figure computed rather than stored, a
|
|
142
|
+
mechanism no single rule explains, or which roles reach a function (always
|
|
143
|
+
the domain-root copy) — or work around a spot in one of them that only a
|
|
144
|
+
domain decision will settle (in the copy that holds the knowledge it is
|
|
145
|
+
stuck on)? If yes, record it in
|
|
146
|
+
`dflow/specs/domain/{context}/analysis.md` when one context owns what it
|
|
147
|
+
describes and in `dflow/specs/domain/analysis.md` when no one context does,
|
|
148
|
+
creating the file from `templates/analysis.md` the first time there is
|
|
149
|
+
something to record.
|
|
150
|
+
5. **Data structure impact?** New tables, columns, indices?
|
|
151
|
+
6. **Why now?** Priority — informs sequencing relative to other phases.
|
|
116
152
|
|
|
117
153
|
This is also the moment to ask: "Should this be its own follow-up feature
|
|
118
154
|
instead of a phase here?" — useful when the scope drift suggests a
|
|
@@ -123,7 +159,7 @@ separate concern.
|
|
|
123
159
|
## Step 3: Phase Slug Confirmation
|
|
124
160
|
|
|
125
161
|
AI proposes the new phase-spec filename and asks the developer to confirm
|
|
126
|
-
before
|
|
162
|
+
before the phase-spec is written.
|
|
127
163
|
|
|
128
164
|
> "Proposed phase-spec for `{SPEC-ID}-{slug}`:
|
|
129
165
|
>
|
|
@@ -165,6 +201,8 @@ frontmatter `status` to `in-progress`. Phase-2-onward specs **must** fill
|
|
|
165
201
|
in the **Delta from prior phases** section (the first phase typically has
|
|
166
202
|
just "首 phase,無前置 Delta"; this is phase 2+, so the section is required).
|
|
167
203
|
|
|
204
|
+
> **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).
|
|
205
|
+
|
|
168
206
|
Walk the developer through each section, in the same way `new-feature-flow`
|
|
169
207
|
Step 4 does — Behavior / Business Rules / Delta / Edge Cases — but only
|
|
170
208
|
list NEW or MODIFIED BRs in Business Rules; UNCHANGED BRs from prior phases stay
|
|
@@ -195,6 +233,8 @@ Wait for confirmation before entering Step 5.
|
|
|
195
233
|
|
|
196
234
|
Update the feature's `_index.md`:
|
|
197
235
|
|
|
236
|
+
> **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).
|
|
237
|
+
|
|
198
238
|
1. **Phase Specs table** — add a new row for this phase:
|
|
199
239
|
```
|
|
200
240
|
| {N+1} | {YYYY-MM-DD} | {phase-slug} | in-progress | [phase-spec-{date}-{phase-slug}.md](./phase-spec-{date}-{phase-slug}.md) |
|
|
@@ -247,6 +287,14 @@ During implementation, continuously verify:
|
|
|
247
287
|
- [ ] Domain code has no delivery-framework dependency
|
|
248
288
|
- [ ] Data access changes do not introduce business rules into infrastructure
|
|
249
289
|
- [ ] Test failures have been resolved or explicitly recorded as follow-up
|
|
290
|
+
- [ ] Every entry Step 2 recorded in `analysis.md`, at either of its two
|
|
291
|
+
paths, still holds. An entry for what this phase was to add or change
|
|
292
|
+
matches what it built — corrected where the build differs, removed
|
|
293
|
+
where nothing was built for it. An entry for something Step 2
|
|
294
|
+
uncovered in the existing system matches the system as it now stands —
|
|
295
|
+
corrected where this phase changed it, never removed because this
|
|
296
|
+
phase built nothing for it. Read the entries in the file, not in a
|
|
297
|
+
diff: a checkpoint may already have committed them.
|
|
250
298
|
|
|
251
299
|
If implementation changes the agreed Delta, update the phase-spec before
|
|
252
300
|
continuing. Do not let code and spec diverge silently.
|
|
@@ -283,8 +331,10 @@ Update the feature artifacts:
|
|
|
283
331
|
feature is ready to wrap up"
|
|
284
332
|
|
|
285
333
|
System-level domain docs, migration debt sync, and the feature directory move
|
|
286
|
-
to `completed/` remain `/dflow:finish-feature` responsibilities
|
|
287
|
-
|
|
334
|
+
to `completed/` remain `/dflow:finish-feature` responsibilities; Step 2 records
|
|
335
|
+
into `analysis.md` directly, at whichever of its two paths the entry belongs
|
|
336
|
+
to. Do not sync any other system-level current state or archive the whole
|
|
337
|
+
feature from `/dflow:new-phase`.
|
|
288
338
|
|
|
289
339
|
After completion, summarize for the developer:
|
|
290
340
|
> "Phase {N+1} is implemented and marked completed. `_index.md` is refreshed.
|