@pmelab/gtd 52.0.0 → 52.1.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/.claude-plugin/plugin.json +1 -1
- package/README.md +5 -2
- package/dist/chunks/{reserved-D0MKVFFa.mjs → reserved-DxB5CROj.mjs} +46 -5
- package/dist/chunks/{review-ZzUQH1KZ.mjs → review-CKMSdvgW.mjs} +2 -2
- package/dist/chunks/{tail-I1-vVq0P.mjs → tail-QZc7Uz2U.mjs} +1 -1
- package/dist/workflows/cleanup.mjs +2 -2
- package/dist/workflows/feature.mjs +51 -4
- package/dist/workflows/fix.mjs +2 -2
- package/dist/workflows/review.mjs +3 -3
- package/dist/workflows/rollout.mjs +1 -1
- package/dist/workflows.mjs +93 -5
- package/package.json +5 -4
- package/src/testkit/steps.ts +13 -0
- package/src/workflows/feature/acceptance-criteria.feature +159 -3
- package/src/workflows/feature/continuation-cap.feature +4 -0
- package/src/workflows/feature/continuation-rebuild.feature +4 -0
- package/src/workflows/feature/continuation-slices.feature +4 -0
- package/src/workflows/feature/continuation.feature +4 -0
- package/src/workflows/feature/criteria.test.ts +22 -1
- package/src/workflows/feature/criteria.ts +66 -1
- package/src/workflows/feature/fast-path.feature +4 -0
- package/src/workflows/feature/feature.test.ts +6 -5
- package/src/workflows/feature/flag-mode.feature +4 -0
- package/src/workflows/feature/hands-on-skip.feature +40 -0
- package/src/workflows/feature/lens-models.feature +4 -0
- package/src/workflows/feature/lens-review.feature +4 -0
- package/src/workflows/feature/naive-acceptance.feature +4 -0
- package/src/workflows/feature/one-step-land.feature +4 -0
- package/src/workflows/feature/planning.ts +2 -1
- package/src/workflows/feature/prototype-rounds.feature +4 -0
- package/src/workflows/feature/prototype.feature +8 -0
- package/src/workflows/feature/refactor-absorbs.feature +4 -0
- package/src/workflows/feature/refactor-first.feature +4 -0
- package/src/workflows/feature/refactor-lens-models.feature +4 -0
- package/src/workflows/feature/refactor-rebuild.feature +4 -0
- package/src/workflows/feature/refactor-review.feature +20 -0
- package/src/workflows/feature/review-answers.feature +4 -0
- package/src/workflows/feature/review-gate.feature +12 -0
- package/src/workflows/feature/reviewer-walkthrough.feature +4 -0
- package/src/workflows/feature/risk-tier.feature +32 -0
- package/src/workflows/feature/seam-rejection.feature +8 -0
- package/src/workflows/feature/seam.feature +8 -0
- package/src/workflows/feature/seam.test.ts +4 -2
- package/src/workflows/feature/severity-budget.feature +4 -0
- package/src/workflows/feature/severity-sorted-review.feature +4 -0
- package/src/workflows/feature/slice-findings.feature +4 -0
- package/src/workflows/feature/slicing.feature +32 -0
- package/src/workflows/feature/standards.feature +4 -0
- package/src/workflows/feature/tier-pin.feature +4 -0
- package/src/workflows/shared/text.test.ts +40 -0
- package/src/workflows/shared/text.ts +50 -4
|
@@ -30,6 +30,10 @@ Feature: every observable criterion is tested by hand before the quality lap
|
|
|
30
30
|
"""
|
|
31
31
|
# Requirements
|
|
32
32
|
|
|
33
|
+
## Impact
|
|
34
|
+
|
|
35
|
+
- the greeting module
|
|
36
|
+
|
|
33
37
|
## Acceptance Criteria
|
|
34
38
|
|
|
35
39
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -236,6 +240,10 @@ Feature: every observable criterion is tested by hand before the quality lap
|
|
|
236
240
|
"""
|
|
237
241
|
# Requirements
|
|
238
242
|
|
|
243
|
+
## Impact
|
|
244
|
+
|
|
245
|
+
- the greeting module
|
|
246
|
+
|
|
239
247
|
## Acceptance Criteria
|
|
240
248
|
|
|
241
249
|
- AC-2: add is unchanged.
|
|
@@ -48,6 +48,10 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
48
48
|
|
|
49
49
|
- `subtract(a, b)` returns `a - b`.
|
|
50
50
|
|
|
51
|
+
## Impact
|
|
52
|
+
|
|
53
|
+
- the greeting module
|
|
54
|
+
|
|
51
55
|
## Acceptance Criteria
|
|
52
56
|
|
|
53
57
|
- AC-1: the change behaves as described.
|
|
@@ -146,6 +150,10 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
146
150
|
|
|
147
151
|
- `subtract(a, b)` returns `a - b`.
|
|
148
152
|
|
|
153
|
+
## Impact
|
|
154
|
+
|
|
155
|
+
- the greeting module
|
|
156
|
+
|
|
149
157
|
## Acceptance Criteria
|
|
150
158
|
|
|
151
159
|
- AC-1: the change behaves as described.
|
|
@@ -245,6 +253,10 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
245
253
|
|
|
246
254
|
- `subtract(a, b)` returns `a - b`.
|
|
247
255
|
|
|
256
|
+
## Impact
|
|
257
|
+
|
|
258
|
+
- the greeting module
|
|
259
|
+
|
|
248
260
|
## Acceptance Criteria
|
|
249
261
|
|
|
250
262
|
- AC-1: the change behaves as described.
|
|
@@ -1210,6 +1222,10 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
1210
1222
|
|
|
1211
1223
|
- `subtract(a, b)` returns `a - b`.
|
|
1212
1224
|
|
|
1225
|
+
## Impact
|
|
1226
|
+
|
|
1227
|
+
- the greeting module
|
|
1228
|
+
|
|
1213
1229
|
## Acceptance Criteria
|
|
1214
1230
|
|
|
1215
1231
|
- AC-1: the change behaves as described.
|
|
@@ -1337,6 +1353,10 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
1337
1353
|
|
|
1338
1354
|
- `subtract(a, b)` returns `a - b`.
|
|
1339
1355
|
|
|
1356
|
+
## Impact
|
|
1357
|
+
|
|
1358
|
+
- the greeting module
|
|
1359
|
+
|
|
1340
1360
|
## Acceptance Criteria
|
|
1341
1361
|
|
|
1342
1362
|
- AC-1: the change behaves as described.
|
|
@@ -36,6 +36,10 @@ Feature: a feature process ends at the human review
|
|
|
36
36
|
|
|
37
37
|
- `subtract(a, b)` returns `a - b`.
|
|
38
38
|
|
|
39
|
+
## Impact
|
|
40
|
+
|
|
41
|
+
- the greeting module
|
|
42
|
+
|
|
39
43
|
## Acceptance Criteria
|
|
40
44
|
|
|
41
45
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -192,6 +196,10 @@ Feature: a feature process ends at the human review
|
|
|
192
196
|
|
|
193
197
|
- `multiply(a, b)` returns `a * b`.
|
|
194
198
|
|
|
199
|
+
## Impact
|
|
200
|
+
|
|
201
|
+
- the greeting module
|
|
202
|
+
|
|
195
203
|
## Acceptance Criteria
|
|
196
204
|
|
|
197
205
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -238,6 +246,10 @@ Feature: a feature process ends at the human review
|
|
|
238
246
|
|
|
239
247
|
- `multiply(a, b)` returns `a * b`.
|
|
240
248
|
|
|
249
|
+
## Impact
|
|
250
|
+
|
|
251
|
+
- the greeting module
|
|
252
|
+
|
|
241
253
|
## Acceptance Criteria
|
|
242
254
|
|
|
243
255
|
- AC-0: multiply(a, b) returns a * b.
|
|
@@ -50,6 +50,10 @@ Feature: the risk tier is proposed at triage and recorded behind GTD_FLAG_RISK_T
|
|
|
50
50
|
|
|
51
51
|
low — trivial copy change
|
|
52
52
|
|
|
53
|
+
## Impact
|
|
54
|
+
|
|
55
|
+
- the greeting module
|
|
56
|
+
|
|
53
57
|
## Acceptance Criteria
|
|
54
58
|
|
|
55
59
|
- AC-1: the change behaves as described.
|
|
@@ -69,6 +73,10 @@ Feature: the risk tier is proposed at triage and recorded behind GTD_FLAG_RISK_T
|
|
|
69
73
|
|
|
70
74
|
high — touches payments
|
|
71
75
|
|
|
76
|
+
## Impact
|
|
77
|
+
|
|
78
|
+
- the greeting module
|
|
79
|
+
|
|
72
80
|
## Acceptance Criteria
|
|
73
81
|
|
|
74
82
|
- AC-1: the change behaves as described.
|
|
@@ -89,6 +97,10 @@ Feature: the risk tier is proposed at triage and recorded behind GTD_FLAG_RISK_T
|
|
|
89
97
|
|
|
90
98
|
### Subtract
|
|
91
99
|
|
|
100
|
+
## Impact
|
|
101
|
+
|
|
102
|
+
- the greeting module
|
|
103
|
+
|
|
92
104
|
## Acceptance Criteria
|
|
93
105
|
|
|
94
106
|
- AC-1: the change behaves as described.
|
|
@@ -118,6 +130,10 @@ Feature: the risk tier is proposed at triage and recorded behind GTD_FLAG_RISK_T
|
|
|
118
130
|
- error rate on /subtract stays flat
|
|
119
131
|
- p95 latency
|
|
120
132
|
|
|
133
|
+
## Impact
|
|
134
|
+
|
|
135
|
+
- the greeting module
|
|
136
|
+
|
|
121
137
|
## Acceptance Criteria
|
|
122
138
|
|
|
123
139
|
- AC-1: the change behaves as described.
|
|
@@ -142,6 +158,10 @@ Feature: the risk tier is proposed at triage and recorded behind GTD_FLAG_RISK_T
|
|
|
142
158
|
|
|
143
159
|
low — trivial copy change
|
|
144
160
|
|
|
161
|
+
## Impact
|
|
162
|
+
|
|
163
|
+
- the greeting module
|
|
164
|
+
|
|
145
165
|
## Acceptance Criteria
|
|
146
166
|
|
|
147
167
|
- AC-1: the change behaves as described.
|
|
@@ -187,6 +207,10 @@ Feature: the risk tier is proposed at triage and recorded behind GTD_FLAG_RISK_T
|
|
|
187
207
|
|
|
188
208
|
### Subtract
|
|
189
209
|
|
|
210
|
+
## Impact
|
|
211
|
+
|
|
212
|
+
- the greeting module
|
|
213
|
+
|
|
190
214
|
## Acceptance Criteria
|
|
191
215
|
|
|
192
216
|
- AC-1: the change behaves as described.
|
|
@@ -233,6 +257,10 @@ Feature: the risk tier is proposed at triage and recorded behind GTD_FLAG_RISK_T
|
|
|
233
257
|
|
|
234
258
|
- error rate stays flat
|
|
235
259
|
|
|
260
|
+
## Impact
|
|
261
|
+
|
|
262
|
+
- the greeting module
|
|
263
|
+
|
|
236
264
|
## Acceptance Criteria
|
|
237
265
|
|
|
238
266
|
- AC-1: the change behaves as described.
|
|
@@ -258,6 +286,10 @@ Feature: the risk tier is proposed at triage and recorded behind GTD_FLAG_RISK_T
|
|
|
258
286
|
|
|
259
287
|
low — trivial
|
|
260
288
|
|
|
289
|
+
## Impact
|
|
290
|
+
|
|
291
|
+
- the greeting module
|
|
292
|
+
|
|
261
293
|
## Acceptance Criteria
|
|
262
294
|
|
|
263
295
|
- AC-1: the change behaves as described.
|
|
@@ -35,6 +35,10 @@ Feature: rejected naive passes walk one fixed path through the steer gate to the
|
|
|
35
35
|
|
|
36
36
|
- `subtract(a, b)` returns `a - b`.
|
|
37
37
|
|
|
38
|
+
## Impact
|
|
39
|
+
|
|
40
|
+
- the greeting module
|
|
41
|
+
|
|
38
42
|
## Acceptance Criteria
|
|
39
43
|
|
|
40
44
|
- AC-1: the change behaves as described.
|
|
@@ -76,6 +80,10 @@ Feature: rejected naive passes walk one fixed path through the steer gate to the
|
|
|
76
80
|
|
|
77
81
|
- `subtract(a, b)` returns `a - b`, in the calculator module.
|
|
78
82
|
|
|
83
|
+
## Impact
|
|
84
|
+
|
|
85
|
+
- the greeting module
|
|
86
|
+
|
|
79
87
|
## Acceptance Criteria
|
|
80
88
|
|
|
81
89
|
- AC-1: the change behaves as described.
|
|
@@ -45,6 +45,10 @@ Feature: the naive pass and seam judge decide how a feature is built
|
|
|
45
45
|
|
|
46
46
|
- `subtract(a, b)` returns `a - b`.
|
|
47
47
|
|
|
48
|
+
## Impact
|
|
49
|
+
|
|
50
|
+
- the greeting module
|
|
51
|
+
|
|
48
52
|
## Acceptance Criteria
|
|
49
53
|
|
|
50
54
|
- AC-1: the change behaves as described.
|
|
@@ -234,6 +238,10 @@ Feature: the naive pass and seam judge decide how a feature is built
|
|
|
234
238
|
|
|
235
239
|
- `subtract(a, b)` returns `a - b`, in a new module.
|
|
236
240
|
|
|
241
|
+
## Impact
|
|
242
|
+
|
|
243
|
+
- the greeting module
|
|
244
|
+
|
|
237
245
|
## Acceptance Criteria
|
|
238
246
|
|
|
239
247
|
- AC-1: the change behaves as described.
|
|
@@ -109,7 +109,8 @@ describe("naivePass", () => {
|
|
|
109
109
|
})
|
|
110
110
|
|
|
111
111
|
describe("naiveAcceptance and requireAcceptance", () => {
|
|
112
|
-
const requirements =
|
|
112
|
+
const requirements =
|
|
113
|
+
"# R\n\n## Impact\n\n- the module\n\n## Acceptance Criteria\n\n- AC-1: adds.\n- AC-2: subtracts.\n"
|
|
113
114
|
const file = (path: string, before: string | undefined, after: string): Change => ({
|
|
114
115
|
path,
|
|
115
116
|
status: before === undefined ? "added" : "modified",
|
|
@@ -170,7 +171,8 @@ describe("naiveAcceptance and requireAcceptance", () => {
|
|
|
170
171
|
})
|
|
171
172
|
|
|
172
173
|
describe("acceptanceFault", () => {
|
|
173
|
-
const requirements =
|
|
174
|
+
const requirements =
|
|
175
|
+
"# R\n\n## Impact\n\n- the module\n\n## Acceptance Criteria\n\n- AC-1: adds.\n- AC-2: subtracts.\n"
|
|
174
176
|
const file = (path: string, status: Change["status"], after: string): Change => ({
|
|
175
177
|
path,
|
|
176
178
|
status,
|
|
@@ -36,6 +36,10 @@ Feature: a change with more criteria than the cap is built in coarse slices
|
|
|
36
36
|
"""
|
|
37
37
|
# Requirements
|
|
38
38
|
|
|
39
|
+
## Impact
|
|
40
|
+
|
|
41
|
+
- the greeting module
|
|
42
|
+
|
|
39
43
|
## Acceptance Criteria
|
|
40
44
|
|
|
41
45
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -70,6 +74,10 @@ Feature: a change with more criteria than the cap is built in coarse slices
|
|
|
70
74
|
"""
|
|
71
75
|
# Requirements
|
|
72
76
|
|
|
77
|
+
## Impact
|
|
78
|
+
|
|
79
|
+
- the greeting module
|
|
80
|
+
|
|
73
81
|
## Acceptance Criteria
|
|
74
82
|
|
|
75
83
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -133,6 +141,10 @@ Feature: a change with more criteria than the cap is built in coarse slices
|
|
|
133
141
|
"""
|
|
134
142
|
# Requirements
|
|
135
143
|
|
|
144
|
+
## Impact
|
|
145
|
+
|
|
146
|
+
- the greeting module
|
|
147
|
+
|
|
136
148
|
## Acceptance Criteria
|
|
137
149
|
|
|
138
150
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -156,6 +168,10 @@ Feature: a change with more criteria than the cap is built in coarse slices
|
|
|
156
168
|
"""
|
|
157
169
|
# Requirements
|
|
158
170
|
|
|
171
|
+
## Impact
|
|
172
|
+
|
|
173
|
+
- the greeting module
|
|
174
|
+
|
|
159
175
|
## Acceptance Criteria
|
|
160
176
|
|
|
161
177
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -181,6 +197,10 @@ Feature: a change with more criteria than the cap is built in coarse slices
|
|
|
181
197
|
"""
|
|
182
198
|
# Requirements
|
|
183
199
|
|
|
200
|
+
## Impact
|
|
201
|
+
|
|
202
|
+
- the greeting module
|
|
203
|
+
|
|
184
204
|
## Acceptance Criteria
|
|
185
205
|
|
|
186
206
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -191,6 +211,10 @@ Feature: a change with more criteria than the cap is built in coarse slices
|
|
|
191
211
|
"""
|
|
192
212
|
# Requirements
|
|
193
213
|
|
|
214
|
+
## Impact
|
|
215
|
+
|
|
216
|
+
- the greeting module
|
|
217
|
+
|
|
194
218
|
## Acceptance Criteria
|
|
195
219
|
|
|
196
220
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -215,6 +239,10 @@ Feature: a change with more criteria than the cap is built in coarse slices
|
|
|
215
239
|
"""
|
|
216
240
|
# Requirements
|
|
217
241
|
|
|
242
|
+
## Impact
|
|
243
|
+
|
|
244
|
+
- the greeting module
|
|
245
|
+
|
|
218
246
|
## Acceptance Criteria
|
|
219
247
|
|
|
220
248
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -244,6 +272,10 @@ Feature: a change with more criteria than the cap is built in coarse slices
|
|
|
244
272
|
"""
|
|
245
273
|
# Requirements
|
|
246
274
|
|
|
275
|
+
## Impact
|
|
276
|
+
|
|
277
|
+
- the greeting module
|
|
278
|
+
|
|
247
279
|
## Acceptance Criteria
|
|
248
280
|
|
|
249
281
|
- AC-1: subtract(a, b) returns a - b.
|
|
@@ -4,6 +4,8 @@ import { tmpdir } from "node:os"
|
|
|
4
4
|
import { join } from "node:path"
|
|
5
5
|
import { afterEach, describe, expect, it } from "vitest"
|
|
6
6
|
import {
|
|
7
|
+
designImpactPrompt,
|
|
8
|
+
prototypeFixingPrompt,
|
|
7
9
|
buildReviewTriageMessage,
|
|
8
10
|
buildReviewReviewingPrompt,
|
|
9
11
|
agentWithSkills,
|
|
@@ -24,6 +26,7 @@ import {
|
|
|
24
26
|
implementBuildingPrompt,
|
|
25
27
|
implementFixPrompt,
|
|
26
28
|
naivePassPrompt,
|
|
29
|
+
slicingPrompt,
|
|
27
30
|
refactorBuildingPrompt,
|
|
28
31
|
refactorDroppedRefusal,
|
|
29
32
|
refactorFixPrompt,
|
|
@@ -922,6 +925,29 @@ describe("buildReviewReviewingPrompt scenarios", () => {
|
|
|
922
925
|
})
|
|
923
926
|
})
|
|
924
927
|
|
|
928
|
+
describe("Impact in prompts", () => {
|
|
929
|
+
it("[AC-4] the slicing prompt slices along the units Impact names", () => {
|
|
930
|
+
const prompt = renderText(() => slicingPrompt(8))
|
|
931
|
+
expect(prompt).toContain("## Impact")
|
|
932
|
+
expect(prompt).toMatch(/slice\s+along\s+the\s+units\s+it\s+names/)
|
|
933
|
+
})
|
|
934
|
+
|
|
935
|
+
it.each([
|
|
936
|
+
["naive", () => naivePassPrompt()],
|
|
937
|
+
["implement", () => implementBuildingPrompt(undefined)],
|
|
938
|
+
["prototype fixing", () => prototypeFixingPrompt(undefined)],
|
|
939
|
+
])("[AC-5] [AC-7] the %s prompt gives Impact as hints, not allowed files", (_n, prompt) => {
|
|
940
|
+
const p = renderText(prompt).replace(/\s+/g, " ")
|
|
941
|
+
expect(p).toContain("`## Impact`")
|
|
942
|
+
expect(p).toContain("not a list of allowed files")
|
|
943
|
+
})
|
|
944
|
+
|
|
945
|
+
it("the prototype testing prompt, which changes no code, carries no Impact hints", () => {
|
|
946
|
+
const p = renderText(() => prototypeTestingPrompt(undefined, [], false))
|
|
947
|
+
expect(p).not.toContain("not a list of allowed files")
|
|
948
|
+
})
|
|
949
|
+
})
|
|
950
|
+
|
|
925
951
|
describe("the seam phase's texts", () => {
|
|
926
952
|
const rejection = { strays: ["src/flows/helpers.ts", "src/flows/runtime.ts"], p: 0.85 }
|
|
927
953
|
|
|
@@ -1641,3 +1667,17 @@ describe("rankedReview", () => {
|
|
|
1641
1667
|
expect(unranked(unranked(review))).toBe(unranked(review))
|
|
1642
1668
|
})
|
|
1643
1669
|
})
|
|
1670
|
+
|
|
1671
|
+
describe("impact prompts", () => {
|
|
1672
|
+
it.each([
|
|
1673
|
+
["triage", () => renderText(() => designTriagePrompt("abc123"))],
|
|
1674
|
+
["design.impact", () => renderText(() => designImpactPrompt())],
|
|
1675
|
+
])("[AC-2] the %s prompt asks for a `## Impact` section", (_n, prompt) => {
|
|
1676
|
+
expect(prompt()).toContain("`## Impact`")
|
|
1677
|
+
})
|
|
1678
|
+
|
|
1679
|
+
it("[AC-3] the triage prompt names where a return lap reads the human's Impact edit", () => {
|
|
1680
|
+
const p = renderText(() => designTriagePrompt("abc123")).replace(/\s+/g, " ")
|
|
1681
|
+
expect(p).toContain("`git log -1 -p -- .gtd/REQUIREMENTS.md`")
|
|
1682
|
+
})
|
|
1683
|
+
})
|
|
@@ -515,6 +515,20 @@ Leave the tag off whatever a person can see by running the change. A
|
|
|
515
515
|
tag the human added or removed at the gate stays as they left it.
|
|
516
516
|
`
|
|
517
517
|
|
|
518
|
+
const impactBlock = `
|
|
519
|
+
## Impact
|
|
520
|
+
|
|
521
|
+
\`.gtd/REQUIREMENTS.md\` carries a \`## Impact\` section: explore the
|
|
522
|
+
codebase (not just the start diff) and name the units and boundaries
|
|
523
|
+
this change touches, the public surfaces it affects (CLI commands and
|
|
524
|
+
flags, config keys, driver protocol, exported API), and anything
|
|
525
|
+
surprising. Name the project's own declared units first —
|
|
526
|
+
dependency-cruiser rules, workspace packages, module boundaries named
|
|
527
|
+
in its docs or agent instructions (\`AGENTS.md\`, \`CLAUDE.md\`). When
|
|
528
|
+
none is declared, fall back to directories and packages. Landing is
|
|
529
|
+
refused while the section is missing.
|
|
530
|
+
`
|
|
531
|
+
|
|
518
532
|
const riskTierBlock = `
|
|
519
533
|
## Risk tier and production signals
|
|
520
534
|
|
|
@@ -556,7 +570,14 @@ ${footnoteFoldIn}${codeThreadReplies()}
|
|
|
556
570
|
or both
|
|
557
571
|
- Whichever lap this is, leave \`.gtd/REQUIREMENTS.md\`
|
|
558
572
|
uncommitted and finish once it reflects this lap's own work
|
|
559
|
-
${acceptanceCriteriaBlock}
|
|
573
|
+
${acceptanceCriteriaBlock}${impactBlock}
|
|
574
|
+
Every lap re-explores and leaves \`## Impact\` present. On a return
|
|
575
|
+
lap or review loop-back the human may have edited \`## Impact\` (or
|
|
576
|
+
footnoted it): read that edit from history (\`git log -1 -p --
|
|
577
|
+
.gtd/REQUIREMENTS.md\`), keep the human's correction, and
|
|
578
|
+
re-explore from it. A surprise the human must settle becomes an
|
|
579
|
+
entry under \`## Open Questions\`.
|
|
580
|
+
|
|
560
581
|
## First lap
|
|
561
582
|
|
|
562
583
|
\`.gtd/REQUIREMENTS.md\` does not exist yet (or holds whatever the
|
|
@@ -612,6 +633,23 @@ ${questionBarReturn}
|
|
|
612
633
|
everything else — the build assumes the suite started green
|
|
613
634
|
${riskTier ? riskTierBlock : ""}`
|
|
614
635
|
|
|
636
|
+
export const designImpactPrompt = (): string =>
|
|
637
|
+
`${styleBlock}
|
|
638
|
+
|
|
639
|
+
${styleFormatContract}
|
|
640
|
+
|
|
641
|
+
${stateFileRules}
|
|
642
|
+
- The only state file this turn touches is \`.gtd/REQUIREMENTS.md\`
|
|
643
|
+
— no other files for notes or output
|
|
644
|
+
- \`.gtd/REQUIREMENTS.md\` already holds the settled acceptance
|
|
645
|
+
criteria. Add a \`## Impact\` section and change nothing else — a
|
|
646
|
+
turn that touches anything outside it is refused
|
|
647
|
+
- No human reviews this before the build: put any surprise in the
|
|
648
|
+
Impact prose, never as a question
|
|
649
|
+
${impactBlock}
|
|
650
|
+
- Leave \`.gtd/REQUIREMENTS.md\` uncommitted and finish once it holds \`## Impact\`
|
|
651
|
+
`
|
|
652
|
+
|
|
615
653
|
export const clearCriteriaQuestion: JudgeQuestion = {
|
|
616
654
|
id: "clear",
|
|
617
655
|
primitive: "noul",
|
|
@@ -665,9 +703,9 @@ export const slicingPrompt = (cap: number): string =>
|
|
|
665
703
|
- Read \`.gtd/REQUIREMENTS.md\`: its \`## Acceptance Criteria\` are settled
|
|
666
704
|
and more than ${cap}, too many to build in one slice
|
|
667
705
|
- Group them into slices in \`.gtd/SLICES.md\`, one \`## <title>\` heading per
|
|
668
|
-
slice over a \`- AC-<n>\` list item per criterion it builds.
|
|
669
|
-
|
|
670
|
-
at most ${cap} per slice
|
|
706
|
+
slice over a \`- AC-<n>\` list item per criterion it builds. Read the
|
|
707
|
+
\`## Impact\` section of \`.gtd/REQUIREMENTS.md\` and slice along the units it
|
|
708
|
+
names; every criterion in exactly one slice, at most ${cap} per slice
|
|
671
709
|
- Keep it coarse: as few slices as the cap allows, never one per criterion
|
|
672
710
|
- Order the slices so each builds on the ones before: they run in that order,
|
|
673
711
|
each from where the previous one landed
|
|
@@ -1620,6 +1658,11 @@ const isFault = (retry: NaiveRetry): retry is NaiveFault => "fault" in retry
|
|
|
1620
1658
|
const pickUp = (hash: string, exclude?: string): string =>
|
|
1621
1659
|
`Pick it up — \`git diff --binary --no-color --no-ext-diff --no-textconv ${hash}^ ${hash}${exclude === undefined ? "" : ` -- ${quote(":(top)")} ${quote(`:(top,exclude)${exclude}`)}`} | git apply\``
|
|
1622
1660
|
|
|
1661
|
+
// Agent-written without a gate on the stated-criteria path, so never claim a human signed it off.
|
|
1662
|
+
const impactHints = `- Its \`## Impact\` section maps where the change lands — reviewed at the design
|
|
1663
|
+
gate when design ran. A starting point and hints, not a list of allowed files
|
|
1664
|
+
— change whatever the work needs`
|
|
1665
|
+
|
|
1623
1666
|
const criteriaBinding = (refused: boolean): string =>
|
|
1624
1667
|
`- Its \`## Acceptance Criteria\` (\`AC-<n>\`) bind this turn: re-read them from
|
|
1625
1668
|
the file, never from memory, and stop only when each one holds. They are
|
|
@@ -1714,6 +1757,7 @@ export const naivePassPrompt = (
|
|
|
1714
1757
|
): string =>
|
|
1715
1758
|
`${stateFileRules}
|
|
1716
1759
|
- Read \`.gtd/REQUIREMENTS.md\`: the settled requirements for this change
|
|
1760
|
+
${impactHints}
|
|
1717
1761
|
${sliceLine(slice)}${criteriaBinding(false)}
|
|
1718
1762
|
- Implement them the quickest way that works — the naive version. Do not
|
|
1719
1763
|
restructure, abstract or refactor around the change; it may land exactly as
|
|
@@ -1853,6 +1897,7 @@ export const implementBuildingPrompt = (
|
|
|
1853
1897
|
): string =>
|
|
1854
1898
|
`${stateFileRules}
|
|
1855
1899
|
- Read \`.gtd/REQUIREMENTS.md\`: the settled requirements for this change
|
|
1900
|
+
${impactHints}
|
|
1856
1901
|
${sliceLine(slice)}${criteriaBinding(true)}
|
|
1857
1902
|
${afterRefactor === true ? afterRefactorLine(rebuild) : ""}${
|
|
1858
1903
|
amend === true
|
|
@@ -2045,6 +2090,7 @@ ${
|
|
|
2045
2090
|
export const prototypeFixingPrompt = (slice: readonly string[] | undefined): string =>
|
|
2046
2091
|
`${stateFileRules}
|
|
2047
2092
|
- Read \`.gtd/REQUIREMENTS.md\`: the settled requirements for this change
|
|
2093
|
+
${impactHints}
|
|
2048
2094
|
${sliceLine(slice)}${criteriaBinding(true)}
|
|
2049
2095
|
- Read \`.gtd/PROTOTYPE.md\`: a hands-on test of the change. Fix every
|
|
2050
2096
|
\`fail\` chunk of this change's criteria${slice === undefined ? "" : " (this slice's only)"} or a problem found
|