dflow-sdd-ddd 0.15.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.
- package/CHANGELOG.md +156 -0
- package/CONTRIBUTING.md +1 -0
- package/README.en.md +7 -4
- package/README.md +7 -4
- package/bin/dflow.js +75 -0
- package/docs/closeout-check.en.md +204 -0
- package/docs/closeout-check.md +204 -0
- package/docs/commands.en.md +4 -2
- package/docs/commands.md +4 -2
- package/docs/release-versioning-policy.md +1 -0
- package/lib/closeout-check.js +690 -0
- package/lib/doc-shapes.json +198 -0
- package/lib/init.js +17 -2
- package/package.json +2 -2
- package/templates/brownfield/references/finish-feature-flow.md +29 -26
- package/templates/brownfield/references/finish-feature-minimal-host.md +38 -17
- package/templates/brownfield/references/finish-feature-record-correction.md +45 -0
- package/templates/brownfield/references/git-integration.md +62 -28
- package/templates/brownfield/references/modify-existing-flow.md +55 -29
- package/templates/brownfield/references/modify-existing-follow-up.md +2 -1
- package/templates/brownfield/references/modify-existing-post-hoc-hotfix.md +121 -3
- package/templates/brownfield/references/new-feature-flow.md +49 -31
- package/templates/brownfield/references/new-phase-flow.md +2 -2
- package/templates/brownfield/references/pr-review-checklist.md +29 -4
- package/templates/brownfield/scaffolding/Git-principles-gitflow.md +13 -5
- package/templates/brownfield/scaffolding/Git-principles-trunk.md +8 -4
- package/templates/brownfield/templates/_index.md +17 -13
- package/templates/common/references/flow-rationale-registry.md +20 -4
- package/templates/greenfield/references/finish-feature-flow.md +29 -26
- package/templates/greenfield/references/finish-feature-minimal-host.md +36 -16
- package/templates/greenfield/references/finish-feature-record-correction.md +45 -0
- package/templates/greenfield/references/git-integration.md +63 -29
- package/templates/greenfield/references/modify-existing-flow.md +42 -27
- package/templates/greenfield/references/modify-existing-follow-up.md +2 -1
- package/templates/greenfield/references/modify-existing-post-hoc-hotfix.md +121 -3
- package/templates/greenfield/references/new-feature-flow.md +49 -31
- package/templates/greenfield/references/new-phase-flow.md +2 -2
- package/templates/greenfield/references/pr-review-checklist.md +28 -4
- package/templates/greenfield/scaffolding/Git-principles-gitflow.md +13 -5
- package/templates/greenfield/scaffolding/Git-principles-trunk.md +8 -4
- package/templates/greenfield/templates/_index.md +18 -13
package/lib/doc-shapes.json
CHANGED
|
@@ -53,6 +53,105 @@
|
|
|
53
53
|
["note","Resume Pointer","","6282e389a109b5f3"],
|
|
54
54
|
["comment","Resume Pointer","","5b3dcd00f70f0239"]
|
|
55
55
|
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"number": 2,
|
|
59
|
+
"digest": "d0d9702bc58d71fb69e8faae01b209fdcca194ae83df02842e660dde035477fc",
|
|
60
|
+
"changes": [
|
|
61
|
+
{"kind":"reworded","from":["note","Checkpoint Log","","7ba7cd7e457fce40"],"to":["note","Checkpoint Log","","f0076376f5650ae1"]}
|
|
62
|
+
],
|
|
63
|
+
"skeleton": [
|
|
64
|
+
["field","spec-id"],
|
|
65
|
+
["field","slug"],
|
|
66
|
+
["field","status"],
|
|
67
|
+
["field","created"],
|
|
68
|
+
["field","branch"],
|
|
69
|
+
["field","follow-up-of","optional"],
|
|
70
|
+
["h2","Goals & Scope"],
|
|
71
|
+
["h2","Phase Specs"],
|
|
72
|
+
["column","Phase Specs","",1,1,"Phase"],
|
|
73
|
+
["column","Phase Specs","",1,2,"Date"],
|
|
74
|
+
["column","Phase Specs","",1,3,"Slug"],
|
|
75
|
+
["column","Phase Specs","",1,4,"Status"],
|
|
76
|
+
["column","Phase Specs","",1,5,"File Link"],
|
|
77
|
+
["h2","Current BR Snapshot"],
|
|
78
|
+
["column","Current BR Snapshot","",1,1,"BR-ID"],
|
|
79
|
+
["column","Current BR Snapshot","",1,2,"Current Rule"],
|
|
80
|
+
["column","Current BR Snapshot","",1,3,"First Seen (phase)"],
|
|
81
|
+
["column","Current BR Snapshot","",1,4,"Last Updated (phase)"],
|
|
82
|
+
["column","Current BR Snapshot","",1,5,"Status"],
|
|
83
|
+
["h2","Lightweight Changes"],
|
|
84
|
+
["column","Lightweight Changes","",1,1,"Date"],
|
|
85
|
+
["column","Lightweight Changes","",1,2,"Tier"],
|
|
86
|
+
["column","Lightweight Changes","",1,3,"Description"],
|
|
87
|
+
["column","Lightweight Changes","",1,4,"Commit"],
|
|
88
|
+
["h2","Checkpoint Log"],
|
|
89
|
+
["column","Checkpoint Log","",1,1,"Timestamp"],
|
|
90
|
+
["column","Checkpoint Log","",1,2,"Checkpoint"],
|
|
91
|
+
["column","Checkpoint Log","",1,3,"Result"],
|
|
92
|
+
["h2","Resume Pointer"],
|
|
93
|
+
["comment","","","43746d19844776ca"],
|
|
94
|
+
["note","Goals & Scope","","6bf4aa3e408ea8bc"],
|
|
95
|
+
["note","Phase Specs","","5dff0b02b2fefdac"],
|
|
96
|
+
["comment","Phase Specs","","60305a8c385cd40f"],
|
|
97
|
+
["note","Current BR Snapshot","","6a432bf9bd86ac85"],
|
|
98
|
+
["comment","Current BR Snapshot","","44a797a7db5f5224"],
|
|
99
|
+
["note","Lightweight Changes","","673f6f4bda4182b3"],
|
|
100
|
+
["comment","Lightweight Changes","","013165e8c56f2b73"],
|
|
101
|
+
["note","Checkpoint Log","","f0076376f5650ae1"],
|
|
102
|
+
["note","Resume Pointer","","6282e389a109b5f3"],
|
|
103
|
+
["comment","Resume Pointer","","5b3dcd00f70f0239"]
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"number": 3,
|
|
108
|
+
"digest": "b8531afb23e1244c53e31d41a8566adfa53e68057165426b8252285aab4a1833",
|
|
109
|
+
"changes": [
|
|
110
|
+
{"kind":"reworded","from":["note","Lightweight Changes","","673f6f4bda4182b3"],"to":["note","Lightweight Changes","","3f9caac2c8fb4600"]},
|
|
111
|
+
{"kind":"reworded","from":["note","Checkpoint Log","","f0076376f5650ae1"],"to":["note","Checkpoint Log","","006cc4257a5c13f2"]}
|
|
112
|
+
],
|
|
113
|
+
"skeleton": [
|
|
114
|
+
["field","spec-id"],
|
|
115
|
+
["field","slug"],
|
|
116
|
+
["field","status"],
|
|
117
|
+
["field","created"],
|
|
118
|
+
["field","branch"],
|
|
119
|
+
["field","follow-up-of","optional"],
|
|
120
|
+
["h2","Goals & Scope"],
|
|
121
|
+
["h2","Phase Specs"],
|
|
122
|
+
["column","Phase Specs","",1,1,"Phase"],
|
|
123
|
+
["column","Phase Specs","",1,2,"Date"],
|
|
124
|
+
["column","Phase Specs","",1,3,"Slug"],
|
|
125
|
+
["column","Phase Specs","",1,4,"Status"],
|
|
126
|
+
["column","Phase Specs","",1,5,"File Link"],
|
|
127
|
+
["h2","Current BR Snapshot"],
|
|
128
|
+
["column","Current BR Snapshot","",1,1,"BR-ID"],
|
|
129
|
+
["column","Current BR Snapshot","",1,2,"Current Rule"],
|
|
130
|
+
["column","Current BR Snapshot","",1,3,"First Seen (phase)"],
|
|
131
|
+
["column","Current BR Snapshot","",1,4,"Last Updated (phase)"],
|
|
132
|
+
["column","Current BR Snapshot","",1,5,"Status"],
|
|
133
|
+
["h2","Lightweight Changes"],
|
|
134
|
+
["column","Lightweight Changes","",1,1,"Date"],
|
|
135
|
+
["column","Lightweight Changes","",1,2,"Tier"],
|
|
136
|
+
["column","Lightweight Changes","",1,3,"Description"],
|
|
137
|
+
["column","Lightweight Changes","",1,4,"Commit"],
|
|
138
|
+
["h2","Checkpoint Log"],
|
|
139
|
+
["column","Checkpoint Log","",1,1,"Timestamp"],
|
|
140
|
+
["column","Checkpoint Log","",1,2,"Checkpoint"],
|
|
141
|
+
["column","Checkpoint Log","",1,3,"Result"],
|
|
142
|
+
["h2","Resume Pointer"],
|
|
143
|
+
["comment","","","43746d19844776ca"],
|
|
144
|
+
["note","Goals & Scope","","6bf4aa3e408ea8bc"],
|
|
145
|
+
["note","Phase Specs","","5dff0b02b2fefdac"],
|
|
146
|
+
["comment","Phase Specs","","60305a8c385cd40f"],
|
|
147
|
+
["note","Current BR Snapshot","","6a432bf9bd86ac85"],
|
|
148
|
+
["comment","Current BR Snapshot","","44a797a7db5f5224"],
|
|
149
|
+
["note","Lightweight Changes","","3f9caac2c8fb4600"],
|
|
150
|
+
["comment","Lightweight Changes","","013165e8c56f2b73"],
|
|
151
|
+
["note","Checkpoint Log","","006cc4257a5c13f2"],
|
|
152
|
+
["note","Resume Pointer","","6282e389a109b5f3"],
|
|
153
|
+
["comment","Resume Pointer","","5b3dcd00f70f0239"]
|
|
154
|
+
]
|
|
56
155
|
}
|
|
57
156
|
]
|
|
58
157
|
},
|
|
@@ -599,6 +698,105 @@
|
|
|
599
698
|
["note","Resume Pointer","","6282e389a109b5f3"],
|
|
600
699
|
["comment","Resume Pointer","","5b3dcd00f70f0239"]
|
|
601
700
|
]
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
"number": 2,
|
|
704
|
+
"digest": "7d4a5014ba47bb069f170d5a1db2b96c9f4292bf2d87e00b104b7f6e47ad0970",
|
|
705
|
+
"changes": [
|
|
706
|
+
{"kind":"reworded","from":["note","Checkpoint Log","","359aef25b21362ca"],"to":["note","Checkpoint Log","","87725d2856e7692d"]}
|
|
707
|
+
],
|
|
708
|
+
"skeleton": [
|
|
709
|
+
["field","spec-id"],
|
|
710
|
+
["field","slug"],
|
|
711
|
+
["field","status"],
|
|
712
|
+
["field","created"],
|
|
713
|
+
["field","branch"],
|
|
714
|
+
["field","follow-up-of","optional"],
|
|
715
|
+
["h2","Goals & Scope"],
|
|
716
|
+
["h2","Phase Specs"],
|
|
717
|
+
["column","Phase Specs","",1,1,"Phase"],
|
|
718
|
+
["column","Phase Specs","",1,2,"Date"],
|
|
719
|
+
["column","Phase Specs","",1,3,"Slug"],
|
|
720
|
+
["column","Phase Specs","",1,4,"Status"],
|
|
721
|
+
["column","Phase Specs","",1,5,"File Link"],
|
|
722
|
+
["h2","Current BR Snapshot"],
|
|
723
|
+
["column","Current BR Snapshot","",1,1,"BR-ID"],
|
|
724
|
+
["column","Current BR Snapshot","",1,2,"Current Rule"],
|
|
725
|
+
["column","Current BR Snapshot","",1,3,"First Seen (phase)"],
|
|
726
|
+
["column","Current BR Snapshot","",1,4,"Last Updated (phase)"],
|
|
727
|
+
["column","Current BR Snapshot","",1,5,"Status"],
|
|
728
|
+
["h2","Lightweight Changes"],
|
|
729
|
+
["column","Lightweight Changes","",1,1,"Date"],
|
|
730
|
+
["column","Lightweight Changes","",1,2,"Tier"],
|
|
731
|
+
["column","Lightweight Changes","",1,3,"Description"],
|
|
732
|
+
["column","Lightweight Changes","",1,4,"Commit"],
|
|
733
|
+
["h2","Checkpoint Log"],
|
|
734
|
+
["column","Checkpoint Log","",1,1,"Timestamp"],
|
|
735
|
+
["column","Checkpoint Log","",1,2,"Checkpoint"],
|
|
736
|
+
["column","Checkpoint Log","",1,3,"Result"],
|
|
737
|
+
["h2","Resume Pointer"],
|
|
738
|
+
["comment","","","ebf6a0dffec4e89d"],
|
|
739
|
+
["note","Goals & Scope","","47f7d220a44ffc70"],
|
|
740
|
+
["note","Phase Specs","","5dff0b02b2fefdac"],
|
|
741
|
+
["comment","Phase Specs","","60305a8c385cd40f"],
|
|
742
|
+
["note","Current BR Snapshot","","bb237977c8b6a9c8"],
|
|
743
|
+
["comment","Current BR Snapshot","","44a797a7db5f5224"],
|
|
744
|
+
["note","Lightweight Changes","","5194f717a8955b59"],
|
|
745
|
+
["comment","Lightweight Changes","","013165e8c56f2b73"],
|
|
746
|
+
["note","Checkpoint Log","","87725d2856e7692d"],
|
|
747
|
+
["note","Resume Pointer","","6282e389a109b5f3"],
|
|
748
|
+
["comment","Resume Pointer","","5b3dcd00f70f0239"]
|
|
749
|
+
]
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
"number": 3,
|
|
753
|
+
"digest": "6a45d40b5f5cdefa1afcdca62cb8f5b320dc6da9aacd6ff42e34d059c5683319",
|
|
754
|
+
"changes": [
|
|
755
|
+
{"kind":"reworded","from":["note","Lightweight Changes","","5194f717a8955b59"],"to":["note","Lightweight Changes","","5d6225b2a04687b3"]},
|
|
756
|
+
{"kind":"reworded","from":["note","Checkpoint Log","","87725d2856e7692d"],"to":["note","Checkpoint Log","","f3336d6c95603aa2"]}
|
|
757
|
+
],
|
|
758
|
+
"skeleton": [
|
|
759
|
+
["field","spec-id"],
|
|
760
|
+
["field","slug"],
|
|
761
|
+
["field","status"],
|
|
762
|
+
["field","created"],
|
|
763
|
+
["field","branch"],
|
|
764
|
+
["field","follow-up-of","optional"],
|
|
765
|
+
["h2","Goals & Scope"],
|
|
766
|
+
["h2","Phase Specs"],
|
|
767
|
+
["column","Phase Specs","",1,1,"Phase"],
|
|
768
|
+
["column","Phase Specs","",1,2,"Date"],
|
|
769
|
+
["column","Phase Specs","",1,3,"Slug"],
|
|
770
|
+
["column","Phase Specs","",1,4,"Status"],
|
|
771
|
+
["column","Phase Specs","",1,5,"File Link"],
|
|
772
|
+
["h2","Current BR Snapshot"],
|
|
773
|
+
["column","Current BR Snapshot","",1,1,"BR-ID"],
|
|
774
|
+
["column","Current BR Snapshot","",1,2,"Current Rule"],
|
|
775
|
+
["column","Current BR Snapshot","",1,3,"First Seen (phase)"],
|
|
776
|
+
["column","Current BR Snapshot","",1,4,"Last Updated (phase)"],
|
|
777
|
+
["column","Current BR Snapshot","",1,5,"Status"],
|
|
778
|
+
["h2","Lightweight Changes"],
|
|
779
|
+
["column","Lightweight Changes","",1,1,"Date"],
|
|
780
|
+
["column","Lightweight Changes","",1,2,"Tier"],
|
|
781
|
+
["column","Lightweight Changes","",1,3,"Description"],
|
|
782
|
+
["column","Lightweight Changes","",1,4,"Commit"],
|
|
783
|
+
["h2","Checkpoint Log"],
|
|
784
|
+
["column","Checkpoint Log","",1,1,"Timestamp"],
|
|
785
|
+
["column","Checkpoint Log","",1,2,"Checkpoint"],
|
|
786
|
+
["column","Checkpoint Log","",1,3,"Result"],
|
|
787
|
+
["h2","Resume Pointer"],
|
|
788
|
+
["comment","","","ebf6a0dffec4e89d"],
|
|
789
|
+
["note","Goals & Scope","","47f7d220a44ffc70"],
|
|
790
|
+
["note","Phase Specs","","5dff0b02b2fefdac"],
|
|
791
|
+
["comment","Phase Specs","","60305a8c385cd40f"],
|
|
792
|
+
["note","Current BR Snapshot","","bb237977c8b6a9c8"],
|
|
793
|
+
["comment","Current BR Snapshot","","44a797a7db5f5224"],
|
|
794
|
+
["note","Lightweight Changes","","5d6225b2a04687b3"],
|
|
795
|
+
["comment","Lightweight Changes","","013165e8c56f2b73"],
|
|
796
|
+
["note","Checkpoint Log","","f3336d6c95603aa2"],
|
|
797
|
+
["note","Resume Pointer","","6282e389a109b5f3"],
|
|
798
|
+
["comment","Resume Pointer","","5b3dcd00f70f0239"]
|
|
799
|
+
]
|
|
602
800
|
}
|
|
603
801
|
]
|
|
604
802
|
},
|
package/lib/init.js
CHANGED
|
@@ -5765,7 +5765,12 @@ async function listShapeScopeDocuments(specsRoot) {
|
|
|
5765
5765
|
return { docs: docs.sort(), unreadable };
|
|
5766
5766
|
}
|
|
5767
5767
|
|
|
5768
|
-
|
|
5768
|
+
// The registry, and whether this package can trust it: the entries' own shape,
|
|
5769
|
+
// and coverage of every template the shape check covers. Shared with
|
|
5770
|
+
// `dflow check-closeout` (PROPOSAL-105), which derives its spec set from the same
|
|
5771
|
+
// registry and has to stop, not skip, when the package is damaged — a registry
|
|
5772
|
+
// missing one template's entry still reads as valid JSON.
|
|
5773
|
+
async function readDocShapesRegistry() {
|
|
5769
5774
|
const packageDamage = [];
|
|
5770
5775
|
let registry = null;
|
|
5771
5776
|
try {
|
|
@@ -5818,6 +5823,11 @@ async function checkDocumentShapes(cwd, findings) {
|
|
|
5818
5823
|
registry = null;
|
|
5819
5824
|
}
|
|
5820
5825
|
}
|
|
5826
|
+
return { registry, packageDamage };
|
|
5827
|
+
}
|
|
5828
|
+
|
|
5829
|
+
async function checkDocumentShapes(cwd, findings) {
|
|
5830
|
+
const { registry, packageDamage } = await readDocShapesRegistry();
|
|
5821
5831
|
|
|
5822
5832
|
// The current number of every template: its own marker, in THIS package.
|
|
5823
5833
|
const current = new Map();
|
|
@@ -6809,5 +6819,10 @@ module.exports = {
|
|
|
6809
6819
|
// fixture removed one of the three structural signals and stayed on the
|
|
6810
6820
|
// single-candidate path while claiming to test the other, so the test asserts
|
|
6811
6821
|
// the precondition directly instead of assuming it.
|
|
6812
|
-
inferProjectBundleEdition
|
|
6822
|
+
inferProjectBundleEdition,
|
|
6823
|
+
// Shared with `dflow check-closeout` (PROPOSAL-105): the registry it derives its
|
|
6824
|
+
// spec set from, read and trusted by the same rules doctor uses, and the line a
|
|
6825
|
+
// document copied whole from a projected template starts with.
|
|
6826
|
+
readDocShapesRegistry,
|
|
6827
|
+
WORKFLOW_BUNDLE_GENERATED_MARKER
|
|
6813
6828
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dflow-sdd-ddd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Spec-first SDD/DDD workflow kit for AI-assisted development",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"homepage": "https://github.com/weilung/dflow-sdd-ddd#readme",
|
|
41
41
|
"scripts": {
|
|
42
|
-
"test": "node test/smoke.mjs && node test/skill-default.mjs && node test/registry-parity.mjs && node test/agent-inject.mjs && node test/upgrade-drift.mjs && node test/doc-shapes.mjs && node test/bundle-guards.mjs && node test/lightweight-families.mjs && node test/render.mjs"
|
|
42
|
+
"test": "node test/smoke.mjs && node test/skill-default.mjs && node test/registry-parity.mjs && node test/agent-inject.mjs && node test/upgrade-drift.mjs && node test/doc-shapes.mjs && node test/bundle-guards.mjs && node test/lightweight-families.mjs && node test/render.mjs && node test/closeout-check.mjs"
|
|
43
43
|
},
|
|
44
44
|
"license": "AGPL-3.0-or-later",
|
|
45
45
|
"publishConfig": {
|
|
@@ -26,9 +26,10 @@ state, archives the feature directory, and emits a Git-strategy-neutral
|
|
|
26
26
|
stance — the AI helps at natural checkpoints, you keep the final say.
|
|
27
27
|
- The BC-layer sync in Step 3 **reuses the existing documentation-sync
|
|
28
28
|
mechanism** from `new-feature-flow` (§ 8.3) and `modify-existing-flow`
|
|
29
|
-
(Step 6.3) — it does not introduce a new sync flow.
|
|
30
|
-
|
|
31
|
-
closeout, with the `_index.md` Current BR Snapshot as
|
|
29
|
+
(Step 6.3) — it does not introduce a new sync flow. § 8.3 and Step 6.3
|
|
30
|
+
sync when the work they record completes; Step 3 runs the same mechanism
|
|
31
|
+
once more at feature closeout, with the `_index.md` Current BR Snapshot as
|
|
32
|
+
input.
|
|
32
33
|
|
|
33
34
|
**Step Gates** in this flow (stop-and-confirm before proceeding):
|
|
34
35
|
- Step 1 → Step 2 (validation passed → flip status)
|
|
@@ -160,8 +161,9 @@ Step 4's post-commit verification, and to Step 5's Integration Summary fields.
|
|
|
160
161
|
carries none. Decide from the artifact, not from a
|
|
161
162
|
declaration: "the feature is intentionally no-BR" is a claim, and the
|
|
162
163
|
record is what settles it. A classic BR-delta spec carrying ADDED /
|
|
163
|
-
MODIFIED / RENAMED entries **and** an empty Snapshot means
|
|
164
|
-
never refreshed it (`modify-existing-flow.md`
|
|
164
|
+
MODIFIED / RENAMED entries **and** an empty Snapshot means the
|
|
165
|
+
completion checklist never refreshed it (`modify-existing-flow.md`
|
|
166
|
+
Step 6.3, before checkpoint 1) and **blocks**.
|
|
165
167
|
|
|
166
168
|
If any check fails:
|
|
167
169
|
> "Cannot finish feature `{SPEC-ID}-{slug}` yet — {N} validation issues
|
|
@@ -376,10 +378,10 @@ Deltas are the audit trail. **Cross-reference each hosted lightweight-spec's
|
|
|
376
378
|
recorded delta the same way** — on any host shape, for the reason above.
|
|
377
379
|
|
|
378
380
|
> Note: this step does NOT read individual phase-specs to re-derive the BR
|
|
379
|
-
> set
|
|
380
|
-
>
|
|
381
|
-
> feature-level truth here. If the developer finds drift
|
|
382
|
-
> and the phase-specs, fix `_index.md` first, then re-run
|
|
381
|
+
> set. `/dflow:new-feature` § 8.4 and `/dflow:new-phase` Step 7 reconcile the
|
|
382
|
+
> Snapshot when they complete a phase, and we trust `_index.md` Current BR
|
|
383
|
+
> Snapshot as the feature-level truth here. If the developer finds drift
|
|
384
|
+
> between Snapshot and the phase-specs, fix `_index.md` first, then re-run
|
|
383
385
|
> `/dflow:finish-feature`.
|
|
384
386
|
|
|
385
387
|
Also update `migration/tech-debt.md` / `models.md` / `glossary.md` /
|
|
@@ -486,13 +488,13 @@ Then, in this order:
|
|
|
486
488
|
|
|
487
489
|
1. **Record the checkpoint row first.** Write one row in the moved
|
|
488
490
|
`_index.md` Checkpoint Log — `closeout | committed` for Y, `closeout |
|
|
489
|
-
skipped` for N. The closeout row carries **no commit hash**:
|
|
490
|
-
commit
|
|
491
|
+
skipped` for N. The closeout row carries **no commit hash**: no later
|
|
492
|
+
commit of this host carries it. Trace it later via
|
|
491
493
|
`git log -1 -- dflow/specs/features/completed/{SPEC-ID}-{slug}` (or the
|
|
492
|
-
optional `Dflow-Checkpoint` trailer).
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
Branch Gate & AI Commits).
|
|
494
|
+
optional `Dflow-Checkpoint` trailer). On any other checkpoint row, a
|
|
495
|
+
`committed ({hash})` Result is written after its commit and carried by the
|
|
496
|
+
host's next commit (see `references/git-integration.md` § Commit
|
|
497
|
+
Checkpoints, Branch Gate & AI Commits).
|
|
496
498
|
**Backfill any unfilled hosted `Commit` cell in the same edit** — a hosted row
|
|
497
499
|
waits for the host's *next* commit and this is it. **Unfilled means empty *or*
|
|
498
500
|
holding a placeholder** — `{hash}`, `{pending}`, `(待 commit)`, anything that
|
|
@@ -526,10 +528,11 @@ Then, in this order:
|
|
|
526
528
|
`migration/tech-debt.md`) — Step 3 is **skipped entirely for a no-BC host**
|
|
527
529
|
(and for a baseline host), so this half is empty there; **and**
|
|
528
530
|
**(b)** the **documentation-sweep step of the flow that produced *this
|
|
529
|
-
change*** — take the paths from that step, not from a list kept here.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
531
|
+
change*** — take the paths from that step, not from a list kept here. A
|
|
532
|
+
commit may already have carried them — `modify-existing-flow.md`'s
|
|
533
|
+
checkpoint 1 carries its own sweep, and a later phase's checkpoint may have
|
|
534
|
+
carried a `new-feature-flow.md` sweep — and staging an already-committed path
|
|
535
|
+
is a no-op, so stage them either way.
|
|
533
536
|
Those sweeps reach
|
|
534
537
|
Domain-layer documents under `dflow/specs/domain/`, plus the **global**
|
|
535
538
|
documents `glossary.md`, `domain/analysis.md` and `migration/tech-debt.md`,
|
|
@@ -571,7 +574,8 @@ Then, in this order:
|
|
|
571
574
|
admitted. On a **phase-bearing** host there is **no allow-list at all** —
|
|
572
575
|
that check is minimal-host-only and lives in that branch file — so read the
|
|
573
576
|
sweep directly and **do not go looking for a list that host never produced.**
|
|
574
|
-
Read each delta (`git diff -- {path}
|
|
577
|
+
Read each delta (`git diff HEAD -- {path}`, which includes what is already
|
|
578
|
+
staged) and scope every one to *this change*;
|
|
575
579
|
staging only "what Step 3 wrote" leaves a no-BC host's global delta dirty and
|
|
576
580
|
the post-commit clean-tree check fails.
|
|
577
581
|
3. **Commit (Y) or stop (N).** For Y the AI commits. If a pre-commit hook
|
|
@@ -621,10 +625,9 @@ every item:
|
|
|
621
625
|
only when the baseline became unreadable *during* closeout.
|
|
622
626
|
Step 1 blocks unless every
|
|
623
627
|
spec in the host already reads `status: completed`, so those flips are
|
|
624
|
-
already **in** the baseline whichever step made them: a
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
host runs Step 1.7, whichever flow opened it. Either way the
|
|
628
|
+
already **in** the baseline whichever step made them: a lightweight-spec's
|
|
629
|
+
comes from `modify-existing-flow.md` Step 6.3, a phase-spec's from its
|
|
630
|
+
phase completing. Either way the
|
|
628
631
|
flips are not differences this check admits; they are part of what it
|
|
629
632
|
compares against. (They are differences only from the *pre-flip* record,
|
|
630
633
|
which is not the baseline.)
|
|
@@ -756,8 +759,8 @@ itself, state in the conversation *how* Step 4's post-commit verification
|
|
|
756
759
|
reached its result — not that it passed, but how it was computed:
|
|
757
760
|
|
|
758
761
|
1. **The baseline** — the tree Step 1 read, and which step put each spec's
|
|
759
|
-
`status: completed` flip into it (Step
|
|
760
|
-
the
|
|
762
|
+
`status: completed` flip into it (`modify-existing-flow.md` Step 6.3 for a
|
|
763
|
+
lightweight-spec; the phase completing for a phase-spec).
|
|
761
764
|
2. **The differences you derived, each with the step that ordered it** —
|
|
762
765
|
Step 2, Step 4's terminal Resume Pointer write, or Step 4 instruction 1. This
|
|
763
766
|
is the set the check *derives* instead of listing, so printing it is what
|
|
@@ -185,15 +185,17 @@ A `✗` here stops closeout there, on the same terms.
|
|
|
185
185
|
`Commit` must still name the **same single documentation commit**.
|
|
186
186
|
- [ ] **Minimal host (zero-phase) only** — **nothing that constitutes the change
|
|
187
187
|
itself is still uncommitted.** This is deliberately not "the host
|
|
188
|
-
directory is clean": **checkpoint 1 carries the change
|
|
189
|
-
commit carries
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
for a **
|
|
193
|
-
**
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
188
|
+
directory is clean": **checkpoint 1 carries the change and the record
|
|
189
|
+
Step 6 writes; the closeout commit carries what the flow writes after
|
|
190
|
+
checkpoint 1.** Checkpoint 1 is offered at the end of
|
|
191
|
+
`modify-existing-flow.md`'s Step 6 (§ 6.5) and holds the change itself —
|
|
192
|
+
for a **T2** its lightweight-spec plus the implementation source, for a
|
|
193
|
+
**T3** its `_index.md` row plus the implementation source, and for a
|
|
194
|
+
**baseline** host the capture itself, which *is* that host's change —
|
|
195
|
+
together with Step 6's completion checklist. What the flow writes *after*
|
|
196
|
+
checkpoint 1 — Step 1.7's "Finalize + close" — is derived record and
|
|
197
|
+
rides into the closeout commit, and so may a correction to Step 6's
|
|
198
|
+
record made after checkpoint 1.
|
|
197
199
|
**A post-hoc host (Step 1.8) inverts the source half, and this is where
|
|
198
200
|
the reconciliation contract is enforced.** Its change is the *already
|
|
199
201
|
merged* hotfix; checkpoint 1 is the **documentation** commit. So that
|
|
@@ -236,8 +238,9 @@ A `✗` here stops closeout there, on the same terms.
|
|
|
236
238
|
to both phase-spec and lightweight-spec"): ticking the tasks this change
|
|
237
239
|
completed and labelling each unchecked one as follow-up (6.1), and — when
|
|
238
240
|
the developer accepted the offer — collapsing or removing the section
|
|
239
|
-
(6.2).
|
|
240
|
-
|
|
241
|
+
(6.2). That checklist runs before checkpoint 1, so these edits are
|
|
242
|
+
normally committed already; this admits a correction to them made after
|
|
243
|
+
checkpoint 1;
|
|
241
244
|
(iii) the Domain-layer documents **this change's Step 6.3 sweep** updates
|
|
242
245
|
— under `dflow/specs/domain/`, plus
|
|
243
246
|
`dflow/specs/migration/tech-debt.md` — scoped to *this change's* delta.
|
|
@@ -251,11 +254,24 @@ A `✗` here stops closeout there, on the same terms.
|
|
|
251
254
|
and therefore still qualify under (iii). **(iii) never covers a baseline
|
|
252
255
|
host** either — its capture *is* the change, and is blocked
|
|
253
256
|
above.
|
|
254
|
-
Read each delta
|
|
255
|
-
|
|
257
|
+
Read each delta with `git diff HEAD -- {path}` — plain `git diff` hides
|
|
258
|
+
what is already staged — and do not infer it from the filename.
|
|
259
|
+
**The list is closed** — if a later change adds another
|
|
256
260
|
finalization field, add it here explicitly; "a host file is dirty" is never
|
|
257
261
|
on its own a reason to pass. (Unrelated work in progress elsewhere is
|
|
258
262
|
fine; say which files you judged unrelated.)
|
|
263
|
+
**Checkpoint 1's own record, corrected after checkpoint 1, is outside the
|
|
264
|
+
list** — the spec's content beyond (ii)'s edits, a row's own text, a
|
|
265
|
+
document a baseline capture wrote, or the reverse-link row a follow-up
|
|
266
|
+
wrote into its original's `_index.md`. It blocks: the closeout commit
|
|
267
|
+
does not carry checkpoint 1's content. The dispatch right after this
|
|
268
|
+
item gives the repair.
|
|
269
|
+
|
|
270
|
+
**Open `references/finish-feature-record-correction.md` and follow it there.**
|
|
271
|
+
Do this only when the check above blocked on a correction to checkpoint 1's own
|
|
272
|
+
record: the repair depends on where checkpoint 1 stands now, and that file gives
|
|
273
|
+
it for each case. Otherwise go on to the next check.
|
|
274
|
+
|
|
259
275
|
- [ ] **Minimal host (zero-phase), no-BC only** — **the host did not commit a
|
|
260
276
|
bounded context it does not have.** This file's `nothing that constitutes
|
|
261
277
|
the change itself is still uncommitted` check reads the *working
|
|
@@ -330,10 +346,11 @@ A `✗` here stops closeout there, on the same terms.
|
|
|
330
346
|
assertion.
|
|
331
347
|
The plausibility conditions, all required: the
|
|
332
348
|
`reconciled ({merged-hotfix-hash})` value passes hash evidence — (a) and
|
|
333
|
-
(b) as usual, and for **(c)** its diff touches
|
|
334
|
-
the T2 lightweight-spec or the T3 row **declares**
|
|
335
|
-
declaration; an artifact naming none leaves (c)
|
|
336
|
-
**blocks** rather than passing vacuously). It
|
|
349
|
+
(b) as usual, and for **(c)** its diff touches **at least one** of the
|
|
350
|
+
implementation paths the T2 lightweight-spec or the T3 row **declares**
|
|
351
|
+
(Step 1.7 requires that declaration; an artifact naming none leaves (c)
|
|
352
|
+
nothing to compare and **blocks** rather than passing vacuously). It
|
|
353
|
+
must also **differ**
|
|
337
354
|
from the Lightweight Changes row's documentation-commit hash (different
|
|
338
355
|
provenance; see Step 1.8). The per-tier trace must exist too: a **T2**
|
|
339
356
|
carries `hotfix-branch:` in its lightweight-spec frontmatter, a **T3** has
|
|
@@ -345,6 +362,10 @@ A `✗` here stops closeout there, on the same terms.
|
|
|
345
362
|
for a **T3**. An uncited hash **blocks** closeout: it leaves pr-review
|
|
346
363
|
nothing to confirm against, and this gate is not a substitute for that
|
|
347
364
|
confirmation.
|
|
365
|
+
**When (b) fails for the `reconciled (...)` hash, do not report only
|
|
366
|
+
"not an ancestor".** Open `references/modify-existing-post-hoc-hotfix.md`
|
|
367
|
+
item 6: it names the causes and the repair for each; report the one that
|
|
368
|
+
is true.
|
|
348
369
|
|
|
349
370
|
> **Zero-phase minimal host (`modify-existing-flow.md` Step 1.7 / the Step 1.6
|
|
350
371
|
> minimal variant / Step 1.8's post-hoc hotfix, whose linkage resolves to one of
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Correcting Checkpoint 1's Own Record — Brownfield Progressive Extraction
|
|
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.
|