@pmelab/gtd 48.0.0 → 50.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.
Files changed (45) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +31 -20
  3. package/dist/chunks/{reserved-DF1HD6jL.mjs → reserved-CdOzKFVX.mjs} +150 -24
  4. package/dist/chunks/{review-Bv40kZu9.mjs → review-BChXEl2Y.mjs} +132 -24
  5. package/dist/chunks/{steering-D7hWeMgE.mjs → steering-DtUVUz9l.mjs} +49 -13
  6. package/dist/chunks/{tail-D89fU_wf.mjs → tail-DRM2eC1z.mjs} +1 -1
  7. package/dist/gtd.bundle.mjs +22 -5
  8. package/dist/steering.mjs +2 -2
  9. package/dist/testkit.mjs +1 -1
  10. package/dist/web/main.js +27 -3
  11. package/dist/workflow-kit.mjs +1 -1
  12. package/dist/workflows/cleanup.mjs +2 -2
  13. package/dist/workflows/feature.mjs +16 -9
  14. package/dist/workflows/fix.mjs +3 -3
  15. package/dist/workflows/review.mjs +3 -3
  16. package/dist/workflows/rollout.mjs +1 -1
  17. package/dist/workflows.mjs +338 -62
  18. package/package.json +1 -1
  19. package/src/steering/index.ts +2 -0
  20. package/src/steering/review.test.ts +87 -0
  21. package/src/steering/review.ts +75 -8
  22. package/src/workflows/feature/coverage.feature +3 -3
  23. package/src/workflows/feature/fast-path.feature +2 -2
  24. package/src/workflows/feature/feature.ts +10 -3
  25. package/src/workflows/feature/flag-mode.feature +2 -2
  26. package/src/workflows/feature/lens-review.feature +128 -13
  27. package/src/workflows/feature/one-step-land.feature +2 -2
  28. package/src/workflows/feature/refactor-absorbs.feature +2 -2
  29. package/src/workflows/feature/refactor-first.feature +2 -2
  30. package/src/workflows/feature/refactor-rebuild.feature +2 -2
  31. package/src/workflows/feature/refactor-review.feature +6 -6
  32. package/src/workflows/feature/review-answers.feature +51 -5
  33. package/src/workflows/feature/review-gate.feature +23 -6
  34. package/src/workflows/feature/reviewer-walkthrough.feature +240 -0
  35. package/src/workflows/feature/seam-rejection.feature +2 -2
  36. package/src/workflows/feature/seam.feature +2 -2
  37. package/src/workflows/feature/severity-budget.feature +111 -0
  38. package/src/workflows/feature/severity-sorted-review.feature +197 -0
  39. package/src/workflows/feature/slice-findings.feature +68 -5
  40. package/src/workflows/feature/slicing.feature +6 -6
  41. package/src/workflows/feature/standards.feature +29 -1
  42. package/src/workflows/shared/review.ts +226 -25
  43. package/src/workflows/shared/steps.ts +3 -2
  44. package/src/workflows/shared/text.test.ts +216 -0
  45. package/src/workflows/shared/text.ts +201 -19
@@ -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.composing"
124
+ Then the process rests at "build.review.reviewing"
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:
@@ -145,7 +145,7 @@ Feature: a refactor-first judgment walks one fixed path to the review gate
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.composing
148
+ gtd(check): implement.closing → build.review.reviewing
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:"
@@ -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.composing"
245
+ Then the process rests at "build.review.reviewing"
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
@@ -260,7 +260,7 @@ Feature: refactor-first writes a refactor note, refactors on its own, then rebui
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.composing
263
+ gtd(check): implement.closing → build.review.reviewing
264
264
  """
265
265
  And the output lines of gtd "slices" start with:
266
266
  """
@@ -646,7 +646,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
646
646
  """
647
647
  When gtd lands
648
648
  And the process is driven
649
- Then the process rests at "build.review.composing"
649
+ Then the process rests at "build.review.reviewing"
650
650
  And "src/calc.ts" contains "subtract"
651
651
 
652
652
  Scenario: a praise-only one-shot footnote signs off and the feature slice follows
@@ -688,7 +688,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
688
688
  """
689
689
  When gtd lands
690
690
  And the process is driven
691
- Then the process rests at "build.review.composing"
691
+ Then the process rests at "build.review.reviewing"
692
692
  And "src/calc.ts" contains "subtract"
693
693
 
694
694
  Scenario: a one-shot footnote judged edit that collecting leaves out refuses naming its anchor
@@ -1003,7 +1003,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1003
1003
  """
1004
1004
  When gtd lands
1005
1005
  And the process is driven
1006
- Then the process rests at "build.review.composing"
1006
+ Then the process rests at "build.review.reviewing"
1007
1007
  And "src/calc.ts" contains "subtract"
1008
1008
 
1009
1009
  Scenario: a praise-only refactor review still signs off and the feature slice follows
@@ -1038,7 +1038,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1038
1038
  """
1039
1039
  When gtd lands
1040
1040
  And the process is driven
1041
- Then the process rests at "build.review.composing"
1041
+ Then the process rests at "build.review.reviewing"
1042
1042
  And "src/calc.ts" contains "subtract"
1043
1043
 
1044
1044
  Scenario: a nit fix in the refactor slice that changes a non-stray is refused, though a glob stray widens the write access
@@ -1228,11 +1228,11 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1228
1228
  And the resting step's content contains the hash of the commit "gtd(check): refactor.build.review.closing → implement.building"
1229
1229
  Given step "build.quality.correctness.reviewing" changes nothing
1230
1230
  When the process is driven
1231
- Then the process rests at "build.review.composing"
1231
+ Then the process rests at "build.review.reviewing"
1232
1232
  And the commit subjects end with:
1233
1233
  """
1234
1234
  gtd(check): implement.closing → build.quality.correctness.reviewing
1235
- gtd(agent): build.quality.correctness.reviewing → build.review.composing
1235
+ gtd(agent): build.quality.correctness.reviewing → build.review.reviewing
1236
1236
  """
1237
1237
 
1238
1238
  Rule: a refactor package never carries a test file, and demoted headings stop at ######
@@ -1,7 +1,7 @@
1
1
  @inmem
2
2
  Feature: every note in the review is answered with one tick
3
3
 
4
- Each note gtd writes to `.gtd/REVIEW.md` ends in three boxes — fix as
4
+ Each quality note in `.gtd/REVIEW.md` ends in three boxes — fix as
5
5
  suggested, won't fix, or the human's own answer written over the
6
6
  placeholder. The gate refuses to land until every note holds exactly one
7
7
  tick. A fix goes to the nit batch, a won't-fix is dropped and recorded in
@@ -74,7 +74,45 @@ Feature: every note in the review is answered with one tick
74
74
  Should subtract round? The criterion does not say.
75
75
  """
76
76
  And step "build.quality.sorting" runs its script
77
- And step "build.review.composing" runs its script
77
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
78
+ """
79
+ # Review: abc1234
80
+
81
+ <!-- base: 0000000 -->
82
+
83
+ ## Subtract
84
+
85
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
86
+ """
87
+ And step "build.review.reviewing", when prompted with "- `## AC-1 ignores floating point`", writes ".gtd/REVIEW.md" with:
88
+ """
89
+ # Review: abc1234
90
+
91
+ <!-- base: 0000000 -->
92
+
93
+ ## Subtract
94
+
95
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
96
+
97
+ ## AC-1 ignores floating point
98
+
99
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
100
+ """
101
+ And step "build.review.reviewing", when prompted with "worked on the human's nits", writes ".gtd/REVIEW.md" with:
102
+ """
103
+ # Review: abc1234
104
+
105
+ <!-- base: 0000000 -->
106
+
107
+ ## Subtract
108
+
109
+ - [ ] ./src/calc.ts#2-2 — now rounds the difference
110
+ """
111
+ And step "build.review.carrying" runs its script
112
+ And judge step "build.review.ranking" answers:
113
+ """
114
+ []
115
+ """
78
116
  And judge step "build.quality.triage" answers:
79
117
  """
80
118
  [{"id":"Q1","answer":"noise","p":0.9},{"id":"Q2","answer":"noise","p":0.9},{"id":"Q3","answer":"design","p":0.9}]
@@ -88,8 +126,14 @@ Feature: every note in the review is answered with one tick
88
126
  """
89
127
  ## AC-1 ignores floating point
90
128
 
129
+ _critical: judge unsure_
130
+
91
131
  Should subtract round? The criterion does not say.
92
132
 
133
+ In the code:
134
+
135
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
136
+
93
137
  Tick exactly one:
94
138
 
95
139
  - [ ] fix as suggested
@@ -141,7 +185,7 @@ Feature: every note in the review is answered with one tick
141
185
  And the process is driven
142
186
  Then the process rests at "build.review.await-review"
143
187
  And no commit body contains "build.review.triage"
144
- And ".gtd/REVIEW.md" contains "## Fixed from your notes"
188
+ And ".gtd/REVIEW.md" contains "now rounds the difference"
145
189
  And ".gtd/REVIEW.md" does not contain "AC-1 ignores floating point"
146
190
  And ".gtd/TODO.md" does not exist
147
191
  When gtd lands
@@ -176,8 +220,10 @@ Feature: every note in the review is answered with one tick
176
220
  gtd(judge): build.review.triage → build.review.fix.nits.fixing
177
221
  gtd(agent): build.review.fix.nits.fixing → build.health.check
178
222
  gtd(check): build.health.check → build.review.closing
179
- gtd(check): build.review.closing → build.review.composing
180
- gtd(check): build.review.composing → build.review.await-review
223
+ gtd(check): build.review.closing → build.review.reviewing
224
+ gtd(agent): build.review.reviewing → build.review.ranking
225
+ gtd(judge): build.review.ranking → build.review.carrying
226
+ gtd(check): build.review.carrying → build.review.await-review
181
227
  """
182
228
  And ".gtd/REVIEW.md" does not contain "AC-1 ignores floating point"
183
229
 
@@ -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.composing" writes ".gtd/REVIEW.md" with:
60
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
61
61
  """
62
62
  # Review: abc1234
63
63
 
@@ -69,6 +69,11 @@ Feature: a feature process ends at the human review
69
69
  new subtract function
70
70
  """
71
71
  And step "build.review.closing" runs its script
72
+ And step "build.review.carrying" runs its script
73
+ And judge step "build.review.ranking" answers:
74
+ """
75
+ []
76
+ """
72
77
 
73
78
  Scenario: a feature process ends at the review gate
74
79
  When the process is driven
@@ -78,8 +83,10 @@ Feature: a feature process ends at the human review
78
83
  And the commit subjects end with:
79
84
  """
80
85
  gtd(judge): implement.coverage → implement.closing
81
- gtd(check): implement.closing → build.review.composing
82
- gtd(check): build.review.composing → build.review.await-review
86
+ gtd(check): implement.closing → build.review.reviewing
87
+ gtd(agent): build.review.reviewing → build.review.ranking
88
+ gtd(judge): build.review.ranking → build.review.carrying
89
+ gtd(check): build.review.carrying → build.review.await-review
83
90
  """
84
91
 
85
92
  Scenario: a sign-off ends the process at idle
@@ -93,6 +100,8 @@ Feature: a feature process ends at the human review
93
100
 
94
101
  ## calc
95
102
 
103
+ _critical: judge unsure_
104
+
96
105
  - [x] ./src/calc.ts#2-2
97
106
  new subtract function
98
107
  """
@@ -102,7 +111,9 @@ Feature: a feature process ends at the human review
102
111
  And ".gtd/REVIEW.md" does not exist
103
112
  And the commit subjects end with:
104
113
  """
105
- gtd(check): build.review.composing → build.review.await-review
114
+ gtd(agent): build.review.reviewing → build.review.ranking
115
+ gtd(judge): build.review.ranking → build.review.carrying
116
+ gtd(check): build.review.carrying → build.review.await-review
106
117
  gtd(human): build.review.await-review → build.review.closing
107
118
  gtd(check): build.review.closing → idle
108
119
  """
@@ -146,6 +157,8 @@ Feature: a feature process ends at the human review
146
157
 
147
158
  ## calc
148
159
 
160
+ _critical: judge unsure_
161
+
149
162
  - [ ] ./src/calc.ts#2-2
150
163
  new subtract function[^why]
151
164
 
@@ -164,6 +177,8 @@ Feature: a feature process ends at the human review
164
177
 
165
178
  ## calc
166
179
 
180
+ _critical: judge unsure_
181
+
167
182
  - [ ] ./src/calc.ts#2-2
168
183
  new subtract function
169
184
  """
@@ -214,8 +229,10 @@ Feature: a feature process ends at the human review
214
229
  gtd(agent): implement.building → implement.health.check
215
230
  gtd(check): implement.health.check → implement.coverage
216
231
  gtd(judge): implement.coverage → implement.closing
217
- gtd(check): implement.closing → build.review.composing
218
- gtd(check): build.review.composing → build.review.await-review
232
+ gtd(check): implement.closing → build.review.reviewing
233
+ gtd(agent): build.review.reviewing → build.review.ranking
234
+ gtd(judge): build.review.ranking → build.review.carrying
235
+ gtd(check): build.review.carrying → build.review.await-review
219
236
  """
220
237
 
221
238
  Scenario: a design numbering new behaviour at or below an earlier ID is refused
@@ -0,0 +1,240 @@
1
+ @inmem
2
+ Feature: a reviewer walks the human through the feature's code
3
+
4
+ The feature's final review is written by a reviewer turn
5
+ (`build.review.reviewing`): chunks grouped by concern, each pointing at its
6
+ code, so the phone shows it. Every finding the quality laps left gets a chunk
7
+ of its own, headed exactly as the prompt gives it, holding the pointers to the
8
+ code it cites; gtd then adds the finding's text and the answer boxes
9
+ (`build.review.carrying`). A chunk pointing at no code, or a finding left out,
10
+ is refused.
11
+
12
+ Background:
13
+ Given the shipped workflows, as gtd install scaffolds them
14
+ And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
15
+ And an environment variable "GTD_FLAGMODE" set to "false"
16
+ And a file "src/calc.ts" with:
17
+ """
18
+ export const add = (a: number, b: number) => a + b
19
+ """
20
+ And the working tree is committed as "feat: add calculator"
21
+ And a file "TODO.md" with:
22
+ """
23
+ # Add subtract
24
+
25
+ subtract(a, b) returns the difference.
26
+ """
27
+ And step "unwind" changes nothing
28
+ And step "start-gate.check" changes nothing
29
+ And step "design.triage" writes ".gtd/REQUIREMENTS.md" with:
30
+ """
31
+ # Requirements
32
+
33
+ ## Acceptance Criteria
34
+
35
+ - AC-1: subtract(a, b) returns a - b.
36
+ """
37
+ And step "design.gate.answer" changes nothing
38
+ And step "seam.naive" writes "src/calc.test.ts" with:
39
+ """
40
+ it("[AC-1] subtracts", () => {})
41
+ """
42
+ And step "seam.naive" writes "src/calc.ts" with:
43
+ """
44
+ export const add = (a: number, b: number) => a + b
45
+ export const subtract = (a: number, b: number) => a - b
46
+ """
47
+ And step "seam.check" changes nothing
48
+ And step "implement.applying" runs its script
49
+ And step "implement.health.check" changes nothing
50
+ And step "implement.closing" runs its script
51
+ And judge step "implement.coverage" answers:
52
+ """
53
+ [{"id":"AC-1","answer":"yes","p":0.9}]
54
+ """
55
+ And step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
56
+ """
57
+ # Quality
58
+
59
+ ## AC-1 ignores floating point
60
+
61
+ Should subtract round? The criterion does not say.
62
+ """
63
+ And judge step "build.quality.triage" answers:
64
+ """
65
+ [{"id":"Q1","answer":"design","p":0.9}]
66
+ """
67
+ And step "build.quality.sorting" runs its script
68
+ And step "build.quality.closing" runs its script
69
+ And step "build.review.carrying" runs its script
70
+ And judge step "build.review.ranking" answers:
71
+ """
72
+ []
73
+ """
74
+
75
+ Scenario: the finding gets its text and answer boxes under the reviewer's pointers
76
+ Given step "build.review.reviewing" is prompted with "- `## AC-1 ignores floating point`:"
77
+ And step "build.review.reviewing" is prompted with "> Should subtract round? The criterion does not say."
78
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
79
+ """
80
+ # Review: abc1234
81
+
82
+ <!-- base: 0000000 -->
83
+
84
+ ## Subtract
85
+
86
+ The new export.
87
+
88
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
89
+
90
+ ## AC-1 ignores floating point
91
+
92
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
93
+ """
94
+ When the process is driven
95
+ Then the process rests at "build.review.await-review"
96
+ And ".gtd/REVIEW.md" contains:
97
+ """
98
+ ## Subtract
99
+
100
+ _critical: judge unsure_
101
+
102
+ The new export.
103
+
104
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
105
+
106
+ ## AC-1 ignores floating point
107
+
108
+ _critical: judge unsure_
109
+
110
+ Should subtract round? The criterion does not say.
111
+
112
+ In the code:
113
+
114
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
115
+
116
+ Tick exactly one:
117
+
118
+ - [ ] fix as suggested
119
+ - [ ] won't fix
120
+ - [ ] _your answer_
121
+ """
122
+ And no commit body contains "build.review.composing"
123
+ And the commit subjects end with:
124
+ """
125
+ gtd(agent): build.review.reviewing → build.review.ranking
126
+ gtd(judge): build.review.ranking → build.review.carrying
127
+ gtd(check): build.review.carrying → build.review.await-review
128
+ """
129
+
130
+ Scenario: a chunk pointing at no code is refused
131
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
132
+ """
133
+ # Review: abc1234
134
+
135
+ <!-- base: 0000000 -->
136
+
137
+ ## Subtract
138
+
139
+ The new export, with no pointer.
140
+
141
+ ## AC-1 ignores floating point
142
+
143
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
144
+ """
145
+ Then driving the process is refused with "Subtract — points at no code"
146
+
147
+ Scenario: a finding the reviewer left out is refused
148
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
149
+ """
150
+ # Review: abc1234
151
+
152
+ <!-- base: 0000000 -->
153
+
154
+ ## Subtract
155
+
156
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
157
+ """
158
+ Then driving the process is refused with "AC-1 ignores floating point — no chunk of its own"
159
+
160
+ Scenario: a risk the reviewer marks is fixed before the human sees the review
161
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
162
+ """
163
+ # Review: abc1234
164
+
165
+ <!-- base: 0000000 -->
166
+
167
+ ## Subtract
168
+
169
+ - [ ] ./src/calc.ts#2-2 — Risk: overflows on large numbers
170
+
171
+ ## AC-1 ignores floating point
172
+
173
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
174
+ """
175
+ And step "build.review.fix.risks.fixing" changes nothing
176
+ And step "build.health.check" changes nothing
177
+ When the process is driven
178
+ Then the process rests at "build.review.await-review"
179
+ And the commit subjects end with:
180
+ """
181
+ gtd(agent): build.review.reviewing → build.review.ranking
182
+ gtd(judge): build.review.ranking → build.review.carrying
183
+ gtd(check): build.review.carrying → build.review.fix.risks.fixing
184
+ gtd(agent): build.review.fix.risks.fixing → build.health.check
185
+ gtd(check): build.health.check → build.review.reviewing
186
+ gtd(agent): build.review.reviewing → build.review.ranking
187
+ gtd(judge): build.review.ranking → build.review.carrying
188
+ gtd(check): build.review.carrying → build.review.await-review
189
+ """
190
+
191
+ Scenario: a standard conflict the reviewer writes itself is refused
192
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
193
+ """
194
+ # Review: abc1234
195
+
196
+ <!-- base: 0000000 -->
197
+
198
+ ## Standard conflict 0123abcd
199
+
200
+ - [ ] ./src/calc.ts#2-2 — copied over
201
+
202
+ ## AC-1 ignores floating point
203
+
204
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
205
+ """
206
+ Then driving the process is refused with "Standard conflict 0123abcd — gtd writes conflicts"
207
+
208
+ Scenario: two chunks with one title are refused
209
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
210
+ """
211
+ # Review: abc1234
212
+
213
+ <!-- base: 0000000 -->
214
+
215
+ ## AC-1 ignores floating point
216
+
217
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
218
+
219
+ ## AC-1 ignores floating point
220
+
221
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
222
+ """
223
+ Then driving the process is refused with "AC-1 ignores floating point — a second chunk with this title"
224
+
225
+ Scenario: a risk marked in a finding's chunk is refused, never fixed
226
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
227
+ """
228
+ # Review: abc1234
229
+
230
+ <!-- base: 0000000 -->
231
+
232
+ ## Subtract
233
+
234
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
235
+
236
+ ## AC-1 ignores floating point
237
+
238
+ - [ ] ./src/calc.ts#2-2 — Risk: no rounding
239
+ """
240
+ Then driving the process is refused with "no `Risk:` in a quality finding's chunk"
@@ -100,7 +100,7 @@ Feature: rejected naive passes walk one fixed path through the steer gate to the
100
100
  And step "implement.applying" runs its script
101
101
  When gtd lands
102
102
  And the process is driven
103
- Then the process rests at "build.review.composing"
103
+ Then the process rests at "build.review.reviewing"
104
104
  And the commit subjects end with:
105
105
  """
106
106
  gtd(human): idle → unwind
@@ -124,7 +124,7 @@ Feature: rejected naive passes walk one fixed path through the steer gate to the
124
124
  gtd(check): implement.applying → implement.health.check
125
125
  gtd(check): implement.health.check → implement.coverage
126
126
  gtd(judge): implement.coverage → implement.closing
127
- gtd(check): implement.closing → build.review.composing
127
+ gtd(check): implement.closing → build.review.reviewing
128
128
  """
129
129
  And the commit "gtd(human): idle → unwind" has a body containing "Gtd-Var: flag_risk_tier=0"
130
130
  And the commit "gtd(agent): seam.naive → seam.check" has a body containing "Gtd-Kept:"
@@ -152,7 +152,7 @@ Feature: the naive pass and seam judge decide how a feature is built
152
152
  [{"id":"AC-1","answer":"yes","p":0.9}]
153
153
  """
154
154
  When the process is driven
155
- Then the process rests at "build.review.composing"
155
+ Then the process rests at "build.review.reviewing"
156
156
  And "src/calc.ts" contains "subtract"
157
157
  And the commit subjects end with:
158
158
  """
@@ -160,7 +160,7 @@ Feature: the naive pass and seam judge decide how a feature is built
160
160
  gtd(check): implement.applying → implement.health.check
161
161
  gtd(check): implement.health.check → implement.coverage
162
162
  gtd(judge): implement.coverage → implement.closing
163
- gtd(check): implement.closing → build.review.composing
163
+ gtd(check): implement.closing → build.review.reviewing
164
164
  """
165
165
  And ".gtd/REQUIREMENTS.md" does not exist
166
166
 
@@ -0,0 +1,111 @@
1
+ @inmem
2
+ Feature: the review's ranking is batched to the judge's budget
3
+
4
+ `build.review.ranking` puts as many chunks in one judgment as the budget's
5
+ even share still holds whole; the rest go to the next. A chunk too big to
6
+ fit even alone is cut, and a cut chunk is critical.
7
+
8
+ Background:
9
+ Given the shipped workflows, as gtd install scaffolds them
10
+ And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
11
+ And an environment variable "GTD_FLAGMODE" set to "false"
12
+ And an environment variable "GTD_JUDGEBUDGETBYTES" set to "150"
13
+ And a file "src/calc.ts" with:
14
+ """
15
+ export const add = (a: number, b: number) => a + b
16
+ """
17
+ And the working tree is committed as "feat: add calculator"
18
+ And a file "TODO.md" with:
19
+ """
20
+ # Add subtract
21
+
22
+ subtract(a, b) returns the difference.
23
+ """
24
+ And step "unwind" changes nothing
25
+ And step "start-gate.check" changes nothing
26
+ And step "design.triage" writes ".gtd/REQUIREMENTS.md" with:
27
+ """
28
+ # Requirements
29
+
30
+ ## Acceptance Criteria
31
+
32
+ - AC-1: subtract(a, b) returns a - b.
33
+ """
34
+ And step "design.gate.answer" changes nothing
35
+ And step "seam.naive" writes "src/calc.test.ts" with:
36
+ """
37
+ it("[AC-1] subtracts", () => {})
38
+ """
39
+ And step "seam.naive" writes "src/calc.ts" with:
40
+ """
41
+ export const add = (a: number, b: number) => a + b
42
+ export const subtract = (a: number, b: number) => a - b
43
+ """
44
+ And step "seam.check" changes nothing
45
+ And step "implement.applying" runs its script
46
+ And step "implement.health.check" changes nothing
47
+ And step "implement.closing" runs its script
48
+ And judge step "implement.coverage" answers:
49
+ """
50
+ [{"id":"AC-1","answer":"yes","p":0.9}]
51
+ """
52
+ And step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
53
+ """
54
+ # Quality
55
+
56
+ ## AC-1 ignores floating point
57
+
58
+ Should subtract round? The criterion does not say.
59
+ """
60
+ And judge step "build.quality.triage" answers:
61
+ """
62
+ [{"id":"Q1","answer":"design","p":0.9}]
63
+ """
64
+ And step "build.quality.sorting" runs its script
65
+ And step "build.quality.closing" runs its script
66
+ And step "build.review.carrying" runs its script
67
+
68
+ Scenario: a chunk the budget cuts is listed as critical, the others judged in batches of their own
69
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
70
+ """
71
+ # Review: abc1234
72
+
73
+ <!-- base: 0000000 -->
74
+
75
+ ## Subtract
76
+
77
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
78
+
79
+ ## AC-1 ignores floating point
80
+
81
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
82
+ """
83
+ And judge step "build.review.ranking", when its questions contain "C1.security", answers:
84
+ """
85
+ [{"id":"C1.security","answer":"no","p":0.9},{"id":"C1.reversibility","answer":"two-way","p":0.9},{"id":"C1.blastRadius","answer":"local","p":0.9},{"id":"C1.newConcept","answer":"no","p":0.9}]
86
+ """
87
+ And judge step "build.review.ranking", when its questions contain "C2.security", answers:
88
+ """
89
+ [{"id":"C2.security","answer":"no","p":0.9},{"id":"C2.reversibility","answer":"two-way","p":0.9},{"id":"C2.blastRadius","answer":"local","p":0.9},{"id":"C2.newConcept","answer":"no","p":0.9}]
90
+ """
91
+ When the process is driven
92
+ Then the process rests at "build.review.await-review"
93
+ And ".gtd/REVIEW.md" contains:
94
+ """
95
+ ## AC-1 ignores floating point
96
+
97
+ _critical: judge unsure_
98
+ """
99
+ And ".gtd/REVIEW.md" contains:
100
+ """
101
+ ## Subtract
102
+
103
+ _could_
104
+ """
105
+ And the commit subjects end with:
106
+ """
107
+ gtd(agent): build.review.reviewing → build.review.ranking
108
+ gtd(judge): build.review.ranking
109
+ gtd(judge): build.review.ranking → build.review.carrying
110
+ gtd(check): build.review.carrying → build.review.await-review
111
+ """