@pmelab/gtd 40.0.0 → 42.0.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 +41 -30
- package/dist/chunks/{reserved-Qt5FM6Ia.mjs → reserved-D7MNY9QJ.mjs} +66 -18
- package/dist/chunks/{steering-DVILanVf.mjs → steering-oCDdQlpP.mjs} +1 -1
- package/dist/chunks/tail-D2o2h5cc.mjs +246 -0
- package/dist/flows.mjs +11 -1
- package/dist/gtd.bundle.mjs +12 -2
- package/dist/steering.mjs +1 -1
- package/dist/testkit.mjs +15 -3
- package/dist/web/main.js +1 -1
- package/dist/workflow-kit.mjs +30 -12
- package/dist/workflows/cleanup.mjs +2 -2
- package/dist/workflows/feature.mjs +44 -24
- package/dist/workflows/fix.mjs +3 -3
- package/dist/workflows/review.mjs +2 -2
- package/dist/workflows/rollout.mjs +1 -1
- package/dist/workflows.mjs +282 -51
- package/package.json +1 -1
- package/src/flows/scripts.ts +15 -0
- package/src/steering/review.test.ts +2 -20
- package/src/steering/review.ts +2 -1
- package/src/testkit/FlowScripts.test.ts +17 -0
- package/src/testkit/FlowScripts.ts +15 -0
- package/src/testkit/steps.ts +27 -0
- package/src/workflow-kit/health.ts +42 -13
- package/src/workflows/feature/coverage.feature +3 -3
- package/src/workflows/feature/fast-path.feature +2 -2
- package/src/workflows/feature/feature.test.ts +2 -37
- package/src/workflows/feature/feature.ts +12 -14
- package/src/workflows/feature/flag-mode.feature +2 -2
- package/src/workflows/feature/lens-review.feature +234 -0
- package/src/workflows/feature/one-step-land.feature +2 -2
- package/src/workflows/feature/quality-unresolved.feature +47 -32
- package/src/workflows/feature/refactor-absorbs.feature +3 -3
- package/src/workflows/feature/refactor-first.feature +5 -5
- package/src/workflows/feature/refactor-rebuild.feature +7 -7
- package/src/workflows/feature/refactor-review.feature +19 -100
- package/src/workflows/feature/refactor.test.ts +12 -27
- package/src/workflows/feature/refactor.ts +0 -1
- package/src/workflows/feature/review-gate.feature +6 -6
- package/src/workflows/feature/review.test.ts +29 -25
- package/src/workflows/feature/review.ts +53 -10
- package/src/workflows/feature/seam-rejection.feature +2 -2
- package/src/workflows/feature/seam.feature +2 -2
- package/src/workflows/feature/seam.test.ts +1 -1
- package/src/workflows/feature/slicing.feature +6 -6
- package/src/workflows/index.ts +1 -0
- package/src/workflows/shared/health.test.ts +30 -0
- package/src/workflows/shared/health.ts +12 -9
- package/src/workflows/shared/lenses.test.ts +39 -0
- package/src/workflows/shared/lenses.ts +176 -0
- package/src/workflows/shared/options.ts +1 -0
- package/src/workflows/shared/progress.feature +124 -0
- package/src/workflows/shared/tail.ts +19 -4
- package/src/workflows/shared/text.test.ts +68 -1
- package/src/workflows/shared/text.ts +126 -13
- package/src/workflows/shared/vars.ts +1 -0
- package/dist/chunks/tail-tAHx_AHe.mjs +0 -112
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
@inmem
|
|
2
|
-
Feature: quality findings left unresolved
|
|
2
|
+
Feature: quality findings left unresolved between slices hold the next slice back
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
Between slices no review reads the quality lap's leftovers, so when the fix
|
|
5
|
+
cap leaves `.gtd/QUALITY.md` behind the process rests for a person before
|
|
6
|
+
the next slice. The last slice's leftovers become review notes instead (see
|
|
7
|
+
`lens-review.feature`).
|
|
7
8
|
|
|
8
9
|
Background:
|
|
9
10
|
Given the shipped workflows, as gtd install scaffolds them
|
|
10
11
|
And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
|
|
11
12
|
And an environment variable "GTD_FLAGMODE" set to "false"
|
|
13
|
+
And an environment variable "GTD_SLICEMAXCRITERIA" set to "1"
|
|
12
14
|
And a file "src/calc.ts" with:
|
|
13
15
|
"""
|
|
14
16
|
export const add = (a: number, b: number) => a + b
|
|
@@ -16,9 +18,9 @@ Feature: quality findings left unresolved hold a feature process short of its re
|
|
|
16
18
|
And the working tree is committed as "feat: add calculator"
|
|
17
19
|
And a file "TODO.md" with:
|
|
18
20
|
"""
|
|
19
|
-
#
|
|
21
|
+
# More arithmetic
|
|
20
22
|
|
|
21
|
-
subtract
|
|
23
|
+
subtract and multiply.
|
|
22
24
|
"""
|
|
23
25
|
And step "unwind" changes nothing
|
|
24
26
|
And step "start-gate.check" changes nothing
|
|
@@ -26,41 +28,53 @@ Feature: quality findings left unresolved hold a feature process short of its re
|
|
|
26
28
|
"""
|
|
27
29
|
# Requirements
|
|
28
30
|
|
|
29
|
-
## Concerns
|
|
30
|
-
|
|
31
|
-
### Subtract
|
|
32
|
-
|
|
33
|
-
- `subtract(a, b)` returns `a - b`.
|
|
34
|
-
|
|
35
31
|
## Acceptance Criteria
|
|
36
32
|
|
|
37
33
|
- AC-1: subtract(a, b) returns a - b.
|
|
34
|
+
- AC-2: multiply(a, b) returns a * b.
|
|
38
35
|
"""
|
|
39
36
|
And step "design.gate.answer" changes nothing
|
|
40
|
-
And step "
|
|
37
|
+
And step "design.slicing" writes ".gtd/SLICES.md" with:
|
|
38
|
+
"""
|
|
39
|
+
# Slices
|
|
40
|
+
|
|
41
|
+
## Subtract
|
|
42
|
+
|
|
43
|
+
- AC-1
|
|
44
|
+
|
|
45
|
+
## Multiply
|
|
46
|
+
|
|
47
|
+
- AC-2
|
|
48
|
+
"""
|
|
49
|
+
And step "seam.naive", when prompted with "This slice builds AC-1 only", writes "src/sub.test.ts" with:
|
|
41
50
|
"""
|
|
42
51
|
it("[AC-1] subtracts", () => {})
|
|
43
52
|
"""
|
|
44
|
-
And step "seam.naive" writes "src/
|
|
53
|
+
And step "seam.naive", when prompted with "This slice builds AC-2 only", writes "src/mul.test.ts" with:
|
|
45
54
|
"""
|
|
46
|
-
|
|
47
|
-
export const subtract = (a: number, b: number) => a - b
|
|
55
|
+
it("[AC-2] multiplies", () => {})
|
|
48
56
|
"""
|
|
49
57
|
And step "seam.check" changes nothing
|
|
50
58
|
And step "implement.applying" runs its script
|
|
51
59
|
And step "implement.health.check" changes nothing
|
|
52
60
|
And step "implement.closing" runs its script
|
|
53
|
-
And judge step "implement.coverage" answers:
|
|
61
|
+
And judge step "implement.coverage", when its questions contain "AC-1", answers:
|
|
54
62
|
"""
|
|
55
63
|
[{"id":"AC-1","answer":"yes","p":0.9}]
|
|
56
64
|
"""
|
|
65
|
+
And judge step "implement.coverage", when its questions contain "AC-2", answers:
|
|
66
|
+
"""
|
|
67
|
+
[{"id":"AC-2","answer":"yes","p":0.9}]
|
|
68
|
+
"""
|
|
57
69
|
|
|
58
|
-
Scenario: findings the fix cap left
|
|
70
|
+
Scenario: findings the fix cap left after a slice rest at build.quality-unresolved
|
|
59
71
|
Given step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
|
|
60
72
|
"""
|
|
61
73
|
# Quality
|
|
62
74
|
|
|
63
|
-
|
|
75
|
+
## subtract has no negative test
|
|
76
|
+
|
|
77
|
+
Add a test subtracting a larger number.
|
|
64
78
|
"""
|
|
65
79
|
And step "build.fix.quality.fixing" from now on changes nothing
|
|
66
80
|
And step "build.health.describe" writes ".gtd/ESCALATION.md" with:
|
|
@@ -74,33 +88,34 @@ Feature: quality findings left unresolved hold a feature process short of its re
|
|
|
74
88
|
Given step "build.fix" writes "src/calc.ts" with:
|
|
75
89
|
"""
|
|
76
90
|
export const add = (a: number, b: number) => a + b
|
|
77
|
-
export const subtract = (a: number, b: number) => a - b
|
|
78
91
|
// checked
|
|
79
92
|
"""
|
|
80
93
|
And step "build.health.check" changes nothing
|
|
81
94
|
When gtd lands
|
|
82
95
|
And the process is driven
|
|
83
96
|
Then the process rests at "build.quality-unresolved"
|
|
84
|
-
And ".gtd/QUALITY.md" contains "subtract has no test"
|
|
97
|
+
And ".gtd/QUALITY.md" contains "subtract has no negative test"
|
|
85
98
|
|
|
86
99
|
When gtd lands
|
|
87
100
|
And the process is driven
|
|
88
101
|
Then the process rests at "build.quality-unresolved"
|
|
89
102
|
|
|
90
|
-
Given
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
export const subtract = (a: number, b: number) => a - b
|
|
94
|
-
// checked by hand
|
|
95
|
-
"""
|
|
96
|
-
And the file ".gtd/QUALITY.md" is deleted
|
|
97
|
-
And step "build.health.check" changes nothing
|
|
103
|
+
Given the file ".gtd/QUALITY.md" is deleted
|
|
104
|
+
And step "build.quality.correctness.reviewing" from now on changes nothing
|
|
105
|
+
And step "build.review.composing" runs its script
|
|
98
106
|
When gtd lands
|
|
99
107
|
And the process is driven
|
|
100
|
-
Then the process rests at "build.review.
|
|
108
|
+
Then the process rests at "build.review.await-review"
|
|
101
109
|
And the commit subjects end with:
|
|
102
110
|
"""
|
|
103
|
-
gtd(check): build.health.check → build.quality-unresolved
|
|
104
111
|
gtd(human): build.quality-unresolved → build.health.check
|
|
105
|
-
gtd(check): build.health.check →
|
|
112
|
+
gtd(check): build.health.check → seam.naive
|
|
113
|
+
gtd(agent): seam.naive → seam.check
|
|
114
|
+
gtd(check): seam.check → implement.applying
|
|
115
|
+
gtd(check): implement.applying → implement.health.check
|
|
116
|
+
gtd(check): implement.health.check → implement.coverage
|
|
117
|
+
gtd(judge): implement.coverage → implement.closing
|
|
118
|
+
gtd(check): implement.closing → build.quality.correctness.reviewing
|
|
119
|
+
gtd(agent): build.quality.correctness.reviewing → build.review.composing
|
|
120
|
+
gtd(check): build.review.composing → build.review.await-review
|
|
106
121
|
"""
|
|
@@ -69,7 +69,7 @@ Feature: a refactor that carried the whole feature still gets a quality lap over
|
|
|
69
69
|
"""
|
|
70
70
|
And step "refactor.health.check" changes nothing
|
|
71
71
|
And step "refactor.closing" runs its script
|
|
72
|
-
And step "refactor.build.review.
|
|
72
|
+
And step "refactor.build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
73
73
|
"""
|
|
74
74
|
# Review: abc1234
|
|
75
75
|
|
|
@@ -113,7 +113,7 @@ Feature: a refactor that carried the whole feature still gets a quality lap over
|
|
|
113
113
|
|
|
114
114
|
Given step "build.quality.correctness.reviewing" changes nothing
|
|
115
115
|
When the process is driven
|
|
116
|
-
Then the process rests at "build.review.
|
|
116
|
+
Then the process rests at "build.review.composing"
|
|
117
117
|
And "src/calc.ts" contains "subtract"
|
|
118
118
|
And the commit subjects end with:
|
|
119
119
|
"""
|
|
@@ -123,7 +123,7 @@ Feature: a refactor that carried the whole feature still gets a quality lap over
|
|
|
123
123
|
gtd(check): implement.health.check → implement.coverage
|
|
124
124
|
gtd(judge): implement.coverage → implement.closing
|
|
125
125
|
gtd(check): implement.closing → build.quality.correctness.reviewing
|
|
126
|
-
gtd(agent): build.quality.correctness.reviewing → build.review.
|
|
126
|
+
gtd(agent): build.quality.correctness.reviewing → build.review.composing
|
|
127
127
|
"""
|
|
128
128
|
And the output lines of gtd "slices" start with:
|
|
129
129
|
"""
|
|
@@ -72,7 +72,7 @@ Feature: a refactor-first judgment walks one fixed path to the review gate
|
|
|
72
72
|
"""
|
|
73
73
|
And step "refactor.health.check" changes nothing
|
|
74
74
|
And step "refactor.closing" runs its script
|
|
75
|
-
And step "refactor.build.review.
|
|
75
|
+
And step "refactor.build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
76
76
|
"""
|
|
77
77
|
# Review: abc1234
|
|
78
78
|
|
|
@@ -121,7 +121,7 @@ Feature: a refactor-first judgment walks one fixed path to the review gate
|
|
|
121
121
|
[{"id":"AC-1","answer":"yes","p":0.9}]
|
|
122
122
|
"""
|
|
123
123
|
When the process is driven
|
|
124
|
-
Then the process rests at "build.review.
|
|
124
|
+
Then the process rests at "build.review.composing"
|
|
125
125
|
And "src/calc.ts" contains "op(a, b, 1)"
|
|
126
126
|
And "src/calc.ts" contains "subtract"
|
|
127
127
|
And the commit subjects end with:
|
|
@@ -138,14 +138,14 @@ Feature: a refactor-first judgment walks one fixed path to the review gate
|
|
|
138
138
|
gtd(check): refactor.deriving → refactor.building
|
|
139
139
|
gtd(agent): refactor.building → refactor.health.check
|
|
140
140
|
gtd(check): refactor.health.check → refactor.closing
|
|
141
|
-
gtd(check): refactor.closing → refactor.build.review.
|
|
142
|
-
gtd(
|
|
141
|
+
gtd(check): refactor.closing → refactor.build.review.composing
|
|
142
|
+
gtd(check): refactor.build.review.composing → refactor.build.review.await-review
|
|
143
143
|
gtd(human): refactor.build.review.await-review → refactor.build.review.closing
|
|
144
144
|
gtd(check): refactor.build.review.closing → implement.building
|
|
145
145
|
gtd(agent): implement.building → implement.health.check
|
|
146
146
|
gtd(check): implement.health.check → implement.coverage
|
|
147
147
|
gtd(judge): implement.coverage → implement.closing
|
|
148
|
-
gtd(check): implement.closing → build.review.
|
|
148
|
+
gtd(check): implement.closing → build.review.composing
|
|
149
149
|
"""
|
|
150
150
|
And the commit "gtd(human): idle → unwind" has a body containing "Gtd-Var: flag_risk_tier=0"
|
|
151
151
|
And the commit "gtd(agent): seam.naive → seam.check" has a body containing "Gtd-Kept:"
|
|
@@ -83,7 +83,7 @@ Feature: refactor-first writes a refactor note, refactors on its own, then rebui
|
|
|
83
83
|
"""
|
|
84
84
|
And step "refactor.health.check" changes nothing
|
|
85
85
|
And step "refactor.closing" runs its script
|
|
86
|
-
And step "refactor.build.review.
|
|
86
|
+
And step "refactor.build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
87
87
|
"""
|
|
88
88
|
# Review: abc1234
|
|
89
89
|
|
|
@@ -147,7 +147,7 @@ Feature: refactor-first writes a refactor note, refactors on its own, then rebui
|
|
|
147
147
|
"""
|
|
148
148
|
And step "refactor.health.check" changes nothing
|
|
149
149
|
And step "refactor.closing" runs its script
|
|
150
|
-
And step "refactor.build.review.
|
|
150
|
+
And step "refactor.build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
151
151
|
"""
|
|
152
152
|
# Review: abc1234
|
|
153
153
|
|
|
@@ -193,7 +193,7 @@ Feature: refactor-first writes a refactor note, refactors on its own, then rebui
|
|
|
193
193
|
"""
|
|
194
194
|
And step "refactor.health.check" changes nothing
|
|
195
195
|
And step "refactor.closing" runs its script
|
|
196
|
-
And step "refactor.build.review.
|
|
196
|
+
And step "refactor.build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
197
197
|
"""
|
|
198
198
|
# Review: abc1234
|
|
199
199
|
|
|
@@ -242,7 +242,7 @@ Feature: refactor-first writes a refactor note, refactors on its own, then rebui
|
|
|
242
242
|
[{"id":"AC-1","answer":"yes","p":0.9}]
|
|
243
243
|
"""
|
|
244
244
|
When the process is driven
|
|
245
|
-
Then the process rests at "build.review.
|
|
245
|
+
Then the process rests at "build.review.composing"
|
|
246
246
|
And "src/calc.ts" contains "op(a, b, -1)"
|
|
247
247
|
And "src/acceptance.test.ts" contains "[AC-1]"
|
|
248
248
|
And ".gtd/REFACTOR-NOTE.md" does not exist
|
|
@@ -253,14 +253,14 @@ Feature: refactor-first writes a refactor note, refactors on its own, then rebui
|
|
|
253
253
|
gtd(check): refactor.deriving → refactor.building
|
|
254
254
|
gtd(agent): refactor.building → refactor.health.check
|
|
255
255
|
gtd(check): refactor.health.check → refactor.closing
|
|
256
|
-
gtd(check): refactor.closing → refactor.build.review.
|
|
257
|
-
gtd(
|
|
256
|
+
gtd(check): refactor.closing → refactor.build.review.composing
|
|
257
|
+
gtd(check): refactor.build.review.composing → refactor.build.review.await-review
|
|
258
258
|
gtd(human): refactor.build.review.await-review → refactor.build.review.closing
|
|
259
259
|
gtd(check): refactor.build.review.closing → implement.building
|
|
260
260
|
gtd(agent): implement.building → implement.health.check
|
|
261
261
|
gtd(check): implement.health.check → implement.coverage
|
|
262
262
|
gtd(judge): implement.coverage → implement.closing
|
|
263
|
-
gtd(check): implement.closing → build.review.
|
|
263
|
+
gtd(check): implement.closing → build.review.composing
|
|
264
264
|
"""
|
|
265
265
|
And the output lines of gtd "slices" start with:
|
|
266
266
|
"""
|
|
@@ -78,7 +78,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
78
78
|
"""
|
|
79
79
|
And step "refactor.health.check" changes nothing
|
|
80
80
|
And step "refactor.closing" runs its script
|
|
81
|
-
And step "refactor.build.review.
|
|
81
|
+
And step "refactor.build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
82
82
|
"""
|
|
83
83
|
# Review: abc1234
|
|
84
84
|
|
|
@@ -171,7 +171,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
171
171
|
"""
|
|
172
172
|
And step "refactor.health.check" changes nothing
|
|
173
173
|
And step "refactor.closing" runs its script
|
|
174
|
-
And step "refactor.build.review.
|
|
174
|
+
And step "refactor.build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
175
175
|
"""
|
|
176
176
|
# Review: abc1234
|
|
177
177
|
|
|
@@ -191,8 +191,8 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
191
191
|
And the commit subjects end with:
|
|
192
192
|
"""
|
|
193
193
|
gtd(check): refactor.closing → refactor.build.quality.correctness.reviewing
|
|
194
|
-
gtd(agent): refactor.build.quality.correctness.reviewing → refactor.build.review.
|
|
195
|
-
gtd(
|
|
194
|
+
gtd(agent): refactor.build.quality.correctness.reviewing → refactor.build.review.composing
|
|
195
|
+
gtd(check): refactor.build.review.composing → refactor.build.review.await-review
|
|
196
196
|
"""
|
|
197
197
|
|
|
198
198
|
|
|
@@ -263,7 +263,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
263
263
|
"""
|
|
264
264
|
And step "refactor.health.check" changes nothing
|
|
265
265
|
And step "refactor.closing" runs its script
|
|
266
|
-
And step "refactor.build.review.
|
|
266
|
+
And step "refactor.build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
267
267
|
"""
|
|
268
268
|
# Review: abc1234
|
|
269
269
|
|
|
@@ -345,91 +345,10 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
345
345
|
gtd(check): refactor.deriving → refactor.building
|
|
346
346
|
gtd(agent): refactor.building → refactor.health.check
|
|
347
347
|
gtd(check): refactor.health.check → refactor.closing
|
|
348
|
-
gtd(check): refactor.closing → refactor.build.review.
|
|
349
|
-
gtd(
|
|
348
|
+
gtd(check): refactor.closing → refactor.build.review.composing
|
|
349
|
+
gtd(check): refactor.build.review.composing → refactor.build.review.await-review
|
|
350
350
|
"""
|
|
351
351
|
|
|
352
|
-
Scenario: the refactor review says the whole refactor on its second round
|
|
353
|
-
Given step "refactor.build.review.reviewing" is prompted with "it covers the whole refactor since it started, on every round"
|
|
354
|
-
And step "implement.building" writes "src/calc.ts" with:
|
|
355
|
-
"""
|
|
356
|
-
export const op = (a: number, b: number, sign: number) => a + sign * b
|
|
357
|
-
export const add = (a: number, b: number) => op(a, b, 1)
|
|
358
|
-
export const subtract = (a: number, b: number) => op(a, b, -1)
|
|
359
|
-
"""
|
|
360
|
-
And step "implement.building" writes "src/acceptance.test.ts" with:
|
|
361
|
-
"""
|
|
362
|
-
it("[AC-1] holds", () => {})
|
|
363
|
-
"""
|
|
364
|
-
And step "implement.health.check" changes nothing
|
|
365
|
-
And step "implement.closing" runs its script
|
|
366
|
-
And judge step "implement.coverage" answers:
|
|
367
|
-
"""
|
|
368
|
-
[{"id":"AC-1","answer":"yes","p":0.9}]
|
|
369
|
-
"""
|
|
370
|
-
When the process is driven
|
|
371
|
-
Then the process rests at "refactor.build.review.await-review"
|
|
372
|
-
Given a file ".gtd/REVIEW.md" with:
|
|
373
|
-
"""
|
|
374
|
-
# Review: abc1234
|
|
375
|
-
|
|
376
|
-
<!-- base: 0000000 -->
|
|
377
|
-
|
|
378
|
-
## calc
|
|
379
|
-
|
|
380
|
-
- [ ] ./src/calc.ts#1-2
|
|
381
|
-
add built on the shared op[^why]
|
|
382
|
-
|
|
383
|
-
[^why]:
|
|
384
|
-
- H: name the helper `combine`
|
|
385
|
-
"""
|
|
386
|
-
And step "refactor.build.review.collecting" writes ".gtd/REFACTOR.md" with:
|
|
387
|
-
"""
|
|
388
|
-
Name the shared helper `combine`.
|
|
389
|
-
"""
|
|
390
|
-
And step "refactor.build.review.collecting" writes ".gtd/REVIEW.md" with:
|
|
391
|
-
"""
|
|
392
|
-
# Review: abc1234
|
|
393
|
-
|
|
394
|
-
<!-- base: 0000000 -->
|
|
395
|
-
|
|
396
|
-
## calc
|
|
397
|
-
|
|
398
|
-
- [ ] ./src/calc.ts#1-2
|
|
399
|
-
add built on the shared op[^why]
|
|
400
|
-
|
|
401
|
-
[^why]:
|
|
402
|
-
- H: name the helper `combine`
|
|
403
|
-
- A: noted in the refactor package.
|
|
404
|
-
"""
|
|
405
|
-
When gtd lands
|
|
406
|
-
And the process is driven
|
|
407
|
-
Then the process rests at "refactor.build.review.await-review"
|
|
408
|
-
Given a file ".gtd/REVIEW.md" with:
|
|
409
|
-
"""
|
|
410
|
-
# Review: abc1234
|
|
411
|
-
|
|
412
|
-
<!-- base: 0000000 -->
|
|
413
|
-
|
|
414
|
-
## calc
|
|
415
|
-
|
|
416
|
-
- [ ] ./src/calc.ts#1-2
|
|
417
|
-
add built on the shared op
|
|
418
|
-
"""
|
|
419
|
-
And step "refactor.re-unwind" runs its script
|
|
420
|
-
And step "refactor.deriving" runs its script
|
|
421
|
-
And step "refactor.building" writes "src/calc.ts" with:
|
|
422
|
-
"""
|
|
423
|
-
export const combine = (a: number, b: number, sign: number) => a + sign * b
|
|
424
|
-
export const add = (a: number, b: number) => combine(a, b, 1)
|
|
425
|
-
"""
|
|
426
|
-
When gtd lands
|
|
427
|
-
And the process is driven
|
|
428
|
-
Then the process rests at "refactor.build.review.await-review"
|
|
429
|
-
When gtd lands
|
|
430
|
-
And the process is driven
|
|
431
|
-
Then the process rests at "build.review.reviewing"
|
|
432
|
-
|
|
433
352
|
Scenario: a question answered at the refactor review reaches the re-derived package as ### Answered Questions
|
|
434
353
|
When the process is driven
|
|
435
354
|
Then the process rests at "refactor.build.review.await-review"
|
|
@@ -515,8 +434,8 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
515
434
|
gtd(check): refactor.deriving → refactor.building
|
|
516
435
|
gtd(agent): refactor.building → refactor.health.check
|
|
517
436
|
gtd(check): refactor.health.check → refactor.closing
|
|
518
|
-
gtd(check): refactor.closing → refactor.build.review.
|
|
519
|
-
gtd(
|
|
437
|
+
gtd(check): refactor.closing → refactor.build.review.composing
|
|
438
|
+
gtd(check): refactor.build.review.composing → refactor.build.review.await-review
|
|
520
439
|
"""
|
|
521
440
|
|
|
522
441
|
Scenario: an edit note the collecting turn leaves out refuses the landing and never signs off
|
|
@@ -727,7 +646,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
727
646
|
"""
|
|
728
647
|
When gtd lands
|
|
729
648
|
And the process is driven
|
|
730
|
-
Then the process rests at "build.review.
|
|
649
|
+
Then the process rests at "build.review.composing"
|
|
731
650
|
And "src/calc.ts" contains "subtract"
|
|
732
651
|
|
|
733
652
|
Scenario: a praise-only one-shot footnote signs off and the feature slice follows
|
|
@@ -769,7 +688,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
769
688
|
"""
|
|
770
689
|
When gtd lands
|
|
771
690
|
And the process is driven
|
|
772
|
-
Then the process rests at "build.review.
|
|
691
|
+
Then the process rests at "build.review.composing"
|
|
773
692
|
And "src/calc.ts" contains "subtract"
|
|
774
693
|
|
|
775
694
|
Scenario: a one-shot footnote judged edit that collecting leaves out refuses naming its anchor
|
|
@@ -1084,7 +1003,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
1084
1003
|
"""
|
|
1085
1004
|
When gtd lands
|
|
1086
1005
|
And the process is driven
|
|
1087
|
-
Then the process rests at "build.review.
|
|
1006
|
+
Then the process rests at "build.review.composing"
|
|
1088
1007
|
And "src/calc.ts" contains "subtract"
|
|
1089
1008
|
|
|
1090
1009
|
Scenario: a praise-only refactor review still signs off and the feature slice follows
|
|
@@ -1119,7 +1038,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
1119
1038
|
"""
|
|
1120
1039
|
When gtd lands
|
|
1121
1040
|
And the process is driven
|
|
1122
|
-
Then the process rests at "build.review.
|
|
1041
|
+
Then the process rests at "build.review.composing"
|
|
1123
1042
|
And "src/calc.ts" contains "subtract"
|
|
1124
1043
|
|
|
1125
1044
|
Scenario: a nit fix in the refactor slice that changes a non-stray is refused, though a glob stray widens the write access
|
|
@@ -1184,8 +1103,8 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
1184
1103
|
Then the process rests at "refactor.build.review.await-review"
|
|
1185
1104
|
And the commit subjects end with:
|
|
1186
1105
|
"""
|
|
1187
|
-
gtd(check): refactor.closing → refactor.build.review.
|
|
1188
|
-
gtd(
|
|
1106
|
+
gtd(check): refactor.closing → refactor.build.review.composing
|
|
1107
|
+
gtd(check): refactor.build.review.composing → refactor.build.review.await-review
|
|
1189
1108
|
"""
|
|
1190
1109
|
|
|
1191
1110
|
Rule: with a quality lens on both slices
|
|
@@ -1256,7 +1175,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
1256
1175
|
"""
|
|
1257
1176
|
And step "refactor.health.check" changes nothing
|
|
1258
1177
|
And step "refactor.closing" runs its script
|
|
1259
|
-
And step "refactor.build.review.
|
|
1178
|
+
And step "refactor.build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
1260
1179
|
"""
|
|
1261
1180
|
# Review: abc1234
|
|
1262
1181
|
|
|
@@ -1309,11 +1228,11 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
1309
1228
|
And the resting step's content contains the hash of the commit "gtd(check): refactor.build.review.closing → implement.building"
|
|
1310
1229
|
Given step "build.quality.correctness.reviewing" changes nothing
|
|
1311
1230
|
When the process is driven
|
|
1312
|
-
Then the process rests at "build.review.
|
|
1231
|
+
Then the process rests at "build.review.composing"
|
|
1313
1232
|
And the commit subjects end with:
|
|
1314
1233
|
"""
|
|
1315
1234
|
gtd(check): implement.closing → build.quality.correctness.reviewing
|
|
1316
|
-
gtd(agent): build.quality.correctness.reviewing → build.review.
|
|
1235
|
+
gtd(agent): build.quality.correctness.reviewing → build.review.composing
|
|
1317
1236
|
"""
|
|
1318
1237
|
|
|
1319
1238
|
Rule: a refactor package never carries a test file, and demoted headings stop at ######
|
|
@@ -1463,7 +1382,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
|
|
|
1463
1382
|
"""
|
|
1464
1383
|
And step "refactor.health.check" changes nothing
|
|
1465
1384
|
And step "refactor.closing" runs its script
|
|
1466
|
-
And step "refactor.build.review.
|
|
1385
|
+
And step "refactor.build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
1467
1386
|
"""
|
|
1468
1387
|
# Review: abc1234
|
|
1469
1388
|
|
|
@@ -781,8 +781,6 @@ interface ReviewedScript {
|
|
|
781
781
|
/** The collecting turn writes no package. */
|
|
782
782
|
readonly silentCollect?: boolean
|
|
783
783
|
readonly collected?: string
|
|
784
|
-
/** The note the first `review.reviewing` turn writes; later ones write `add`. */
|
|
785
|
-
readonly firstReviewNote?: string
|
|
786
784
|
}
|
|
787
785
|
|
|
788
786
|
/** Runs `reviewedRefactor` against a scripted context; a third await-review stops the run. */
|
|
@@ -797,7 +795,6 @@ const driveReviewed = async (
|
|
|
797
795
|
const files = new Map<string, string>()
|
|
798
796
|
let last = ""
|
|
799
797
|
let awaits = 0
|
|
800
|
-
let reviews = 0
|
|
801
798
|
let reds = script.reds ?? 0
|
|
802
799
|
let checking = false
|
|
803
800
|
let pending: boolean | Error = false
|
|
@@ -823,9 +820,7 @@ const driveReviewed = async (
|
|
|
823
820
|
...Object.fromEntries(lensEffects),
|
|
824
821
|
deriving: () => void files.set(REFACTOR_PACKAGE, "package"),
|
|
825
822
|
closing: () => void files.delete(REFACTOR_PACKAGE),
|
|
826
|
-
"review.
|
|
827
|
-
files.set(REVIEW, reviewDoc(reviews++ === 0 ? (script.firstReviewNote ?? "add") : "add"))
|
|
828
|
-
},
|
|
823
|
+
"review.composing": () => void files.set(REVIEW, reviewDoc("add")),
|
|
829
824
|
"review.closing": () => void files.delete(REVIEW),
|
|
830
825
|
"review.collecting": () => {
|
|
831
826
|
if (!script.silentCollect)
|
|
@@ -846,6 +841,14 @@ const driveReviewed = async (
|
|
|
846
841
|
if (request.kind === "restart") return Promise.resolve()
|
|
847
842
|
record(request)
|
|
848
843
|
effects[request.name]?.()
|
|
844
|
+
// Every lens finding is mechanical, so the fix turn runs.
|
|
845
|
+
if (request.kind === "judge" && request.name === "quality.triage")
|
|
846
|
+
return Promise.resolve({
|
|
847
|
+
answers: Object.fromEntries(
|
|
848
|
+
request.questions.map((q) => [q.id, { answer: "mechanical", p: 0.9 }]),
|
|
849
|
+
),
|
|
850
|
+
truncated: [],
|
|
851
|
+
})
|
|
849
852
|
return Promise.resolve(
|
|
850
853
|
request.kind === "judge" ? { answers: script.answers ?? {}, truncated: [] } : undefined,
|
|
851
854
|
)
|
|
@@ -926,7 +929,7 @@ describe("reviewedRefactor", () => {
|
|
|
926
929
|
"refactor.build.quality.correctness.reviewing",
|
|
927
930
|
"refactor.build.quality.ponytail-review.reviewing",
|
|
928
931
|
"refactor.build.quality.conventions.reviewing",
|
|
929
|
-
"refactor.build.review.
|
|
932
|
+
"refactor.build.review.composing",
|
|
930
933
|
"refactor.build.review.await-review",
|
|
931
934
|
"refactor.build.review.closing",
|
|
932
935
|
])
|
|
@@ -934,8 +937,8 @@ describe("reviewedRefactor", () => {
|
|
|
934
937
|
|
|
935
938
|
it("reviews from HEAD at scope entry", async () => {
|
|
936
939
|
const h = await driveReviewed(shape())
|
|
937
|
-
const
|
|
938
|
-
expect(
|
|
940
|
+
const composing = h.steps.find((s) => s.kind === "run" && s.name === "review.composing")
|
|
941
|
+
expect(composing?.kind === "run" ? composing.body : "").toContain("<!-- base: c0 -->")
|
|
939
942
|
})
|
|
940
943
|
|
|
941
944
|
it("names the entry commit in every lens prompt, on the first lap and after a feedback lap", async () => {
|
|
@@ -1192,10 +1195,6 @@ describe("reviewedRefactor's tail prompts", () => {
|
|
|
1192
1195
|
it.each([
|
|
1193
1196
|
["refactor.build.fix", { findings: true, reds: 2 }],
|
|
1194
1197
|
["refactor.build.fix.quality.fixing", { findings: true }],
|
|
1195
|
-
[
|
|
1196
|
-
"refactor.build.review.fix.risks.fixing",
|
|
1197
|
-
{ firstReviewNote: "Risk: drops the carry", notes: [undefined] },
|
|
1198
|
-
],
|
|
1199
1198
|
[
|
|
1200
1199
|
"refactor.build.review.fix.nits.fixing",
|
|
1201
1200
|
{ notes: ["nit"], answers: { "note-1": { answer: "nit", p: 0.9 } } },
|
|
@@ -1211,17 +1210,3 @@ describe("reviewedRefactor's tail prompts", () => {
|
|
|
1211
1210
|
},
|
|
1212
1211
|
)
|
|
1213
1212
|
})
|
|
1214
|
-
|
|
1215
|
-
describe("reviewedRefactor's review lap wording", () => {
|
|
1216
|
-
it("says the whole refactor since it started on the first and the second round", async () => {
|
|
1217
|
-
const h = await driveReviewed(shape(), { notes: ["add — rename it", undefined] })
|
|
1218
|
-
const prompts = h.steps.flatMap((s) =>
|
|
1219
|
-
s.kind === "agent" && s.name === "review.reviewing" ? [s.prompt] : [],
|
|
1220
|
-
)
|
|
1221
|
-
expect(prompts).toHaveLength(2)
|
|
1222
|
-
for (const prompt of prompts) {
|
|
1223
|
-
expect(prompt).toContain("it covers the whole refactor since it started, on every round")
|
|
1224
|
-
expect(prompt).not.toContain("only what is new since the previous review")
|
|
1225
|
-
}
|
|
1226
|
-
})
|
|
1227
|
-
})
|
|
@@ -389,7 +389,6 @@ export const reviewedRefactor = async (
|
|
|
389
389
|
fixAccess: strayAccess(p.strays),
|
|
390
390
|
lensBase: entry,
|
|
391
391
|
rules: t.refactorRules(p.strays, p.pattern),
|
|
392
|
-
lap: "refactor",
|
|
393
392
|
})
|
|
394
393
|
if (outcome.verdict === "signoff") return true
|
|
395
394
|
await reUnwind(outcome)
|
|
@@ -57,7 +57,7 @@ Feature: a feature process ends at the human review
|
|
|
57
57
|
"""
|
|
58
58
|
[{"id":"AC-1","answer":"yes","p":0.9}]
|
|
59
59
|
"""
|
|
60
|
-
And step "build.review.
|
|
60
|
+
And step "build.review.composing" writes ".gtd/REVIEW.md" with:
|
|
61
61
|
"""
|
|
62
62
|
# Review: abc1234
|
|
63
63
|
|
|
@@ -78,8 +78,8 @@ Feature: a feature process ends at the human review
|
|
|
78
78
|
And the commit subjects end with:
|
|
79
79
|
"""
|
|
80
80
|
gtd(judge): implement.coverage → implement.closing
|
|
81
|
-
gtd(check): implement.closing → build.review.
|
|
82
|
-
gtd(
|
|
81
|
+
gtd(check): implement.closing → build.review.composing
|
|
82
|
+
gtd(check): build.review.composing → build.review.await-review
|
|
83
83
|
"""
|
|
84
84
|
|
|
85
85
|
Scenario: a sign-off ends the process at idle
|
|
@@ -102,7 +102,7 @@ Feature: a feature process ends at the human review
|
|
|
102
102
|
And ".gtd/REVIEW.md" does not exist
|
|
103
103
|
And the commit subjects end with:
|
|
104
104
|
"""
|
|
105
|
-
gtd(
|
|
105
|
+
gtd(check): build.review.composing → build.review.await-review
|
|
106
106
|
gtd(human): build.review.await-review → build.review.closing
|
|
107
107
|
gtd(check): build.review.closing → idle
|
|
108
108
|
"""
|
|
@@ -214,8 +214,8 @@ Feature: a feature process ends at the human review
|
|
|
214
214
|
gtd(agent): implement.building → implement.health.check
|
|
215
215
|
gtd(check): implement.health.check → implement.coverage
|
|
216
216
|
gtd(judge): implement.coverage → implement.closing
|
|
217
|
-
gtd(check): implement.closing → build.review.
|
|
218
|
-
gtd(
|
|
217
|
+
gtd(check): implement.closing → build.review.composing
|
|
218
|
+
gtd(check): build.review.composing → build.review.await-review
|
|
219
219
|
"""
|
|
220
220
|
|
|
221
221
|
Scenario: a design numbering new behaviour at or below an earlier ID is refused
|