@pmelab/gtd 47.0.0 → 49.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 (50) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +53 -45
  3. package/dist/chunks/{reserved-DF1HD6jL.mjs → reserved-CYZ1bSBy.mjs} +93 -24
  4. package/dist/chunks/{review-Bv40kZu9.mjs → review-BewyJflS.mjs} +58 -14
  5. package/dist/chunks/{steering-D7hWeMgE.mjs → steering-BXwjmocB.mjs} +7 -1
  6. package/dist/chunks/{tail-D89fU_wf.mjs → tail-C1Oi2YEy.mjs} +1 -1
  7. package/dist/gtd.bundle.mjs +203 -867
  8. package/dist/steering.mjs +2 -2
  9. package/dist/testkit.mjs +90 -54
  10. package/dist/workflow-kit.mjs +1 -1
  11. package/dist/workflows/cleanup.mjs +2 -2
  12. package/dist/workflows/feature.mjs +16 -9
  13. package/dist/workflows/fix.mjs +3 -3
  14. package/dist/workflows/review.mjs +3 -3
  15. package/dist/workflows/rollout.mjs +1 -1
  16. package/dist/workflows.mjs +164 -39
  17. package/package.json +1 -1
  18. package/src/cli/Cli.test.ts +0 -2
  19. package/src/cli/Cli.ts +0 -15
  20. package/src/cli/Program.test.ts +0 -1
  21. package/src/cli/Program.ts +0 -8
  22. package/src/cli/ToolCommands.ts +1 -2
  23. package/src/install/Install.ts +89 -35
  24. package/src/steering/index.ts +1 -0
  25. package/src/steering/review.test.ts +29 -0
  26. package/src/steering/review.ts +10 -0
  27. package/src/testkit/Layers.ts +0 -1
  28. package/src/wire/ContextLimit.ts +1 -1
  29. package/src/workflows/feature/coverage.feature +3 -3
  30. package/src/workflows/feature/fast-path.feature +2 -2
  31. package/src/workflows/feature/feature.ts +10 -3
  32. package/src/workflows/feature/flag-mode.feature +2 -2
  33. package/src/workflows/feature/lens-review.feature +116 -13
  34. package/src/workflows/feature/one-step-land.feature +2 -2
  35. package/src/workflows/feature/refactor-absorbs.feature +2 -2
  36. package/src/workflows/feature/refactor-first.feature +2 -2
  37. package/src/workflows/feature/refactor-rebuild.feature +2 -2
  38. package/src/workflows/feature/refactor-review.feature +6 -6
  39. package/src/workflows/feature/review-answers.feature +44 -5
  40. package/src/workflows/feature/review-gate.feature +6 -6
  41. package/src/workflows/feature/reviewer-walkthrough.feature +229 -0
  42. package/src/workflows/feature/seam-rejection.feature +2 -2
  43. package/src/workflows/feature/seam.feature +2 -2
  44. package/src/workflows/feature/slice-findings.feature +56 -5
  45. package/src/workflows/feature/slicing.feature +6 -6
  46. package/src/workflows/feature/standards.feature +25 -1
  47. package/src/workflows/shared/review.ts +108 -13
  48. package/src/workflows/shared/steps.ts +3 -2
  49. package/src/workflows/shared/text.test.ts +126 -0
  50. package/src/workflows/shared/text.ts +125 -19
@@ -1338,3 +1338,13 @@ export const reviewDecisions = (before: string, after: string): readonly ReviewD
1338
1338
  return old?.choice === decision.choice && old.text === decision.text ? [] : [decision]
1339
1339
  })
1340
1340
  }
1341
+
1342
+ /** Each `##` chunk in document order: its title, 0-based heading line and how many hunk pointers it holds. */
1343
+ export const reviewChunks = (
1344
+ content: string,
1345
+ ): readonly { title: string; line: number; pointers: number }[] =>
1346
+ parseReviewDoc(content).changesets.map((c) => ({
1347
+ title: c.title,
1348
+ line: c.headingLine,
1349
+ pointers: c.files.length,
1350
+ }))
@@ -205,7 +205,6 @@ const missingTool = (name: string) => () =>
205
205
  const missingToolCommands: ToolCommands["Type"] = {
206
206
  ui: missingTool("ui"),
207
207
  lsp: missingTool("lsp"),
208
- loop: missingTool("loop"),
209
208
  contextHook: missingTool("context-hook"),
210
209
  judge: () =>
211
210
  Promise.reject(
@@ -1,4 +1,4 @@
1
- // The context-limit decision every driver shares: the loop's `gtd context-hook`
1
+ // The context-limit decision every driver shares: `gtd context-hook`
2
2
  // and the Claude Code mod both answer a hook event through `contextHook`, so
3
3
  // the two cannot drift on thresholds, wording or which tokens count.
4
4
 
@@ -61,13 +61,13 @@ Feature: a feature is done only when every acceptance criterion has a passing te
61
61
  [{"id":"AC-1","answer":"yes","p":0.9},{"id":"AC-2","answer":"yes","p":0.9}]
62
62
  """
63
63
  When the process is driven
64
- Then the process rests at "build.review.composing"
64
+ Then the process rests at "build.review.reviewing"
65
65
  And the commit subjects end with:
66
66
  """
67
67
  gtd(check): implement.applying → implement.health.check
68
68
  gtd(check): implement.health.check → implement.coverage
69
69
  gtd(judge): implement.coverage → implement.closing
70
- gtd(check): implement.closing → build.review.composing
70
+ gtd(check): implement.closing → build.review.reviewing
71
71
  """
72
72
  And the commit "gtd(judge): implement.coverage → implement.closing" has a body containing "Gtd-Mark: covers=AC-1"
73
73
  And the commit "gtd(judge): implement.coverage → implement.closing" has a body containing "Gtd-Mark: covers=AC-2"
@@ -144,7 +144,7 @@ Feature: a feature is done only when every acceptance criterion has a passing te
144
144
  """
145
145
  And step "implement.uncovered" changes nothing
146
146
  When the process is driven
147
- Then the process rests at "build.review.composing"
147
+ Then the process rests at "build.review.reviewing"
148
148
  And the commit "gtd(human): implement.uncovered → implement.closing" has a body containing "Gtd-Mark: covers=AC-1"
149
149
  And the commit "gtd(human): implement.uncovered → implement.closing" has a body containing "Gtd-Mark: uncovered=AC-2"
150
150
 
@@ -64,7 +64,7 @@ Feature: a trivial change takes the same few beats at either risk tier
64
64
  """
65
65
  And step "implement.applying" runs its script
66
66
  When the process is driven
67
- Then the process rests at "build.review.composing"
67
+ Then the process rests at "build.review.reviewing"
68
68
  And "src/greeting.ts" contains "Hello, world"
69
69
  And the commit subjects end with:
70
70
  """
@@ -80,7 +80,7 @@ Feature: a trivial change takes the same few beats at either risk tier
80
80
  gtd(check): implement.health.check → implement.coverage
81
81
  gtd(judge): implement.coverage → implement.closing
82
82
  gtd(check): implement.closing → build.quality.correctness.reviewing
83
- gtd(agent): build.quality.correctness.reviewing → build.review.composing
83
+ gtd(agent): build.quality.correctness.reviewing → build.review.reviewing
84
84
  """
85
85
  And the output of gtd "summary" <summary> "needs a human reviewer"
86
86
 
@@ -38,7 +38,8 @@ import { recordRisk, riskTierOn, type RiskTier } from "./tier.js"
38
38
  // judged with `flagMode` on: it lands as the implementation, or (refactoring
39
39
  // first when the judge asks) is built fresh from → the health loop → the
40
40
  // triaged quality lap, whose leftovers are carried on → after the last slice,
41
- // human review of the whole change and every slice's findings, which
41
+ // a reviewer's walkthrough of the whole change, every slice's findings
42
+ // among its chunks, for the human, which
42
43
  // signs off (the episode ends back at `idle`) or sends a design → implement
43
44
  // lap.
44
45
 
@@ -152,11 +153,15 @@ const buildSlice = async (sliceBase: string, build: SliceBuild): Promise<void> =
152
153
  })
153
154
  }
154
155
 
155
- /** The quality lap of slice `last.slice`, then the human review since `base`, listing what earlier slices' `laps` left too. */
156
+ /**
157
+ * The quality lap of slice `last.slice`, then a reviewer's walkthrough since
158
+ * `base` for the human, carrying what earlier slices' `laps` left too.
159
+ */
156
160
  const reviewedTail = (
157
161
  base: string,
158
162
  lensBase: string,
159
163
  last: { readonly slice: string; readonly laps: SliceBuild["laps"] } = { slice: "", laps: [] },
164
+ lap: "first" | "feedback" = "first",
160
165
  ): Promise<ReviewOutcome> =>
161
166
  tail(
162
167
  (escalations, report) =>
@@ -165,6 +170,8 @@ const reviewedTail = (
165
170
  last.laps.length === 0
166
171
  ? report
167
172
  : joinReports([...last.laps, { slice: last.slice, report }]),
173
+ walkthrough: true,
174
+ lap,
168
175
  }),
169
176
  { green: true, lensBase },
170
177
  )
@@ -189,7 +196,7 @@ const featureFeedback = async (
189
196
  })
190
197
  const tier = riskTierOn() ? recordRisk() : undefined
191
198
  closed = await implementing({ tier, amend: true })
192
- outcome = await reviewedTail(outcome.base, lensBase)
199
+ outcome = await reviewedTail(outcome.base, lensBase, undefined, "feedback")
193
200
  }
194
201
  }
195
202
 
@@ -67,7 +67,7 @@ Feature: flag mode off lands the naive pass with no release flag, seam judge or
67
67
  """
68
68
  And step "build.quality.correctness.reviewing" changes nothing
69
69
  When the process is driven
70
- Then the process rests at "build.review.composing"
70
+ Then the process rests at "build.review.reviewing"
71
71
  And "src/calc.ts" contains "subtract"
72
72
  And "src/calc.test.ts" contains "[AC-1] subtracts"
73
73
  And the commit subjects end with:
@@ -85,5 +85,5 @@ Feature: flag mode off lands the naive pass with no release flag, seam judge or
85
85
  gtd(check): implement.health.check → implement.coverage
86
86
  gtd(judge): implement.coverage → implement.closing
87
87
  gtd(check): implement.closing → build.quality.correctness.reviewing
88
- gtd(agent): build.quality.correctness.reviewing → build.review.composing
88
+ gtd(agent): build.quality.correctness.reviewing → build.review.reviewing
89
89
  """
@@ -1,12 +1,11 @@
1
1
  @inmem
2
- Feature: the quality lenses are the only agentic review
2
+ Feature: the quality lap's findings are triaged before the review
3
3
 
4
4
  A judge classifies each `## ` finding the lenses wrote to `.gtd/QUALITY.md`:
5
5
  a mechanical one is fixed by the fixer, noise is dropped with its `p` kept in
6
6
  a trailer, and a design one becomes a note in `.gtd/REVIEW.md`, with answer
7
- boxes. gtd writes that file itself — no reviewer turn runs — and lists,
8
- without tick boxes, what was fixed automatically and what was dropped as
9
- noise.
7
+ boxes, in the chunk the reviewer gave it. gtd lists, without tick boxes,
8
+ what was fixed automatically and what was dropped as noise.
10
9
 
11
10
  Background:
12
11
  Given the shipped workflows, as gtd install scaffolds them
@@ -75,7 +74,7 @@ Feature: the quality lenses are the only agentic review
75
74
  """
76
75
  And step "build.quality.sorting" runs its script
77
76
  And step "build.quality.closing" runs its script
78
- And step "build.review.composing" runs its script
77
+ And step "build.review.carrying" runs its script
79
78
 
80
79
  Scenario: a mechanical finding is fixed and listed, noise dropped and listed, a design one noted
81
80
  Given judge step "build.quality.triage" answers:
@@ -89,6 +88,20 @@ Feature: the quality lenses are the only agentic review
89
88
  """
90
89
  And step "build.fix.quality.fixing" deletes ".gtd/QUALITY.md"
91
90
  And step "build.health.check" changes nothing
91
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
92
+ """
93
+ # Review: abc1234
94
+
95
+ <!-- base: 0000000 -->
96
+
97
+ ## Subtract
98
+
99
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
100
+
101
+ ## AC-1 ignores floating point
102
+
103
+ - [ ] ./src/calc.ts#2-2 — where it applies
104
+ """
92
105
  When the process is driven
93
106
  Then the process rests at "build.review.await-review"
94
107
  And ".gtd/QUALITY.md" does not exist
@@ -99,6 +112,10 @@ Feature: the quality lenses are the only agentic review
99
112
 
100
113
  Should subtract round? The criterion does not say.
101
114
 
115
+ In the code:
116
+
117
+ - [ ] ./src/calc.ts#2-2 — where it applies
118
+
102
119
  Tick exactly one:
103
120
 
104
121
  - [ ] fix as suggested
@@ -129,8 +146,9 @@ Feature: the quality lenses are the only agentic review
129
146
  gtd(judge): build.quality.triage → build.quality.sorting
130
147
  gtd(check): build.quality.sorting → build.fix.quality.fixing
131
148
  gtd(agent): build.fix.quality.fixing → build.health.check
132
- gtd(check): build.health.check → build.review.composing
133
- gtd(check): build.review.composing → build.review.await-review
149
+ gtd(check): build.health.check → build.review.reviewing
150
+ gtd(agent): build.review.reviewing → build.review.carrying
151
+ gtd(check): build.review.carrying → build.review.await-review
134
152
  """
135
153
 
136
154
  Scenario: an unsure verdict makes a finding a note, never a fix or a drop
@@ -138,6 +156,28 @@ Feature: the quality lenses are the only agentic review
138
156
  """
139
157
  [{"id":"Q1","answer":"mechanical","p":0.5},{"id":"Q2","answer":"noise","p":0.6}]
140
158
  """
159
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
160
+ """
161
+ # Review: abc1234
162
+
163
+ <!-- base: 0000000 -->
164
+
165
+ ## Subtract
166
+
167
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
168
+
169
+ ## subtract has no negative test
170
+
171
+ - [ ] ./src/calc.ts#2-2 — where it applies
172
+
173
+ ## add could be a method
174
+
175
+ - [ ] ./src/calc.ts#2-2 — where it applies
176
+
177
+ ## AC-1 ignores floating point
178
+
179
+ - [ ] ./src/calc.ts#2-2 — where it applies
180
+ """
141
181
  When the process is driven
142
182
  Then the process rests at "build.review.await-review"
143
183
  And ".gtd/REVIEW.md" contains "## subtract has no negative test"
@@ -148,8 +188,9 @@ Feature: the quality lenses are the only agentic review
148
188
  And the commit subjects end with:
149
189
  """
150
190
  gtd(judge): build.quality.triage → build.quality.sorting
151
- gtd(check): build.quality.sorting → build.review.composing
152
- gtd(check): build.review.composing → build.review.await-review
191
+ gtd(check): build.quality.sorting → build.review.reviewing
192
+ gtd(agent): build.review.reviewing → build.review.carrying
193
+ gtd(check): build.review.carrying → build.review.await-review
153
194
  """
154
195
 
155
196
  Scenario: a mechanical finding the fix cap leaves becomes a note
@@ -166,6 +207,20 @@ Feature: the quality lenses are the only agentic review
166
207
  A class would read better.
167
208
  """
168
209
  And step "build.health.check" changes nothing
210
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
211
+ """
212
+ # Review: abc1234
213
+
214
+ <!-- base: 0000000 -->
215
+
216
+ ## Subtract
217
+
218
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
219
+
220
+ ## add could be a method
221
+
222
+ - [ ] ./src/calc.ts#2-2 — where it applies
223
+ """
169
224
  When the process is driven
170
225
  Then the process rests at "build.review.await-review"
171
226
  And ".gtd/QUALITY.md" does not exist
@@ -186,8 +241,9 @@ Feature: the quality lenses are the only agentic review
186
241
  gtd(agent): build.fix.quality.fixing
187
242
  gtd(agent): build.fix.quality.fixing → build.health.check
188
243
  gtd(check): build.health.check → build.quality.closing
189
- gtd(check): build.quality.closing → build.review.composing
190
- gtd(check): build.review.composing → build.review.await-review
244
+ gtd(check): build.quality.closing → build.review.reviewing
245
+ gtd(agent): build.review.reviewing → build.review.carrying
246
+ gtd(check): build.review.carrying → build.review.await-review
191
247
  """
192
248
 
193
249
  Scenario: a fixer that renames a chunk it leaves counts nothing fixed
@@ -204,6 +260,32 @@ Feature: the quality lenses are the only agentic review
204
260
  Still open.
205
261
  """
206
262
  And step "build.health.check" changes nothing
263
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
264
+ """
265
+ # Review: abc1234
266
+
267
+ <!-- base: 0000000 -->
268
+
269
+ ## Subtract
270
+
271
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
272
+
273
+ ## subtract has no negative test
274
+
275
+ - [ ] ./src/calc.ts#2-2 — where it applies
276
+
277
+ ## add could be a method
278
+
279
+ - [ ] ./src/calc.ts#2-2 — where it applies
280
+
281
+ ## AC-1 ignores floating point
282
+
283
+ - [ ] ./src/calc.ts#2-2 — where it applies
284
+
285
+ ## null check in parse()
286
+
287
+ - [ ] ./src/calc.ts#2-2 — where it applies
288
+ """
207
289
  When the process is driven
208
290
  Then the process rests at "build.review.await-review"
209
291
  And ".gtd/REVIEW.md" contains "## null check in parse()"
@@ -223,17 +305,37 @@ Feature: the quality lenses are the only agentic review
223
305
  All fixed.
224
306
  """
225
307
  And step "build.health.check" changes nothing
308
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
309
+ """
310
+ # Review: abc1234
311
+
312
+ <!-- base: 0000000 -->
313
+
314
+ ## Subtract
315
+
316
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
317
+ """
226
318
  When the process is driven
227
319
  Then the process rests at "build.review.await-review"
228
320
  And ".gtd/REVIEW.md" contains "- subtract has no negative test ("
229
321
  And ".gtd/REVIEW.md" does not contain "check whether it was fixed"
230
322
 
231
- Scenario: signing off a composed review ends the process
323
+ Scenario: signing off a review with no notes ends the process
232
324
  Given judge step "build.quality.triage" answers:
233
325
  """
234
326
  [{"id":"Q1","answer":"noise","p":0.9},{"id":"Q2","answer":"noise","p":0.9},{"id":"Q3","answer":"noise","p":0.9}]
235
327
  """
236
328
  And step "build.review.closing" runs its script
329
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
330
+ """
331
+ # Review: abc1234
332
+
333
+ <!-- base: 0000000 -->
334
+
335
+ ## Subtract
336
+
337
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
338
+ """
237
339
  When the process is driven
238
340
  Then the process rests at "build.review.await-review"
239
341
  When gtd lands
@@ -242,7 +344,8 @@ Feature: the quality lenses are the only agentic review
242
344
  And ".gtd/REVIEW.md" does not exist
243
345
  And the commit subjects end with:
244
346
  """
245
- gtd(check): build.review.composing → build.review.await-review
347
+ gtd(agent): build.review.reviewing → build.review.carrying
348
+ gtd(check): build.review.carrying → build.review.await-review
246
349
  gtd(human): build.review.await-review → build.review.closing
247
350
  gtd(check): build.review.closing → idle
248
351
  """
@@ -64,7 +64,7 @@ Feature: a naive pass the judge rules land is itself the implementation
64
64
 
65
65
  Scenario: a land judgment applies the naive pass and runs from idle to the review gate with no rebuild
66
66
  When the process is driven
67
- Then the process rests at "build.review.composing"
67
+ Then the process rests at "build.review.reviewing"
68
68
  And "src/greeting.ts" contains "Hello, world"
69
69
  And "src/acceptance.test.ts" contains "[AC-1] holds"
70
70
  And the commit subjects end with:
@@ -81,7 +81,7 @@ Feature: a naive pass the judge rules land is itself the implementation
81
81
  gtd(check): implement.health.check → implement.coverage
82
82
  gtd(judge): implement.coverage → implement.closing
83
83
  gtd(check): implement.closing → build.quality.correctness.reviewing
84
- gtd(agent): build.quality.correctness.reviewing → build.review.composing
84
+ gtd(agent): build.quality.correctness.reviewing → build.review.reviewing
85
85
  """
86
86
  And the commit "gtd(human): idle → unwind" has a body containing "Gtd-Var: flag_risk_tier=0"
87
87
  And the commit "gtd(agent): seam.naive → seam.check" has a body containing "Gtd-Kept:"
@@ -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.composing"
116
+ Then the process rests at "build.review.reviewing"
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.composing
126
+ gtd(agent): build.quality.correctness.reviewing → build.review.reviewing
127
127
  """
128
128
  And the output lines of gtd "slices" start with:
129
129
  """
@@ -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,41 @@ 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
78
112
  And judge step "build.quality.triage" answers:
79
113
  """
80
114
  [{"id":"Q1","answer":"noise","p":0.9},{"id":"Q2","answer":"noise","p":0.9},{"id":"Q3","answer":"design","p":0.9}]
@@ -90,6 +124,10 @@ Feature: every note in the review is answered with one tick
90
124
 
91
125
  Should subtract round? The criterion does not say.
92
126
 
127
+ In the code:
128
+
129
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
130
+
93
131
  Tick exactly one:
94
132
 
95
133
  - [ ] fix as suggested
@@ -141,7 +179,7 @@ Feature: every note in the review is answered with one tick
141
179
  And the process is driven
142
180
  Then the process rests at "build.review.await-review"
143
181
  And no commit body contains "build.review.triage"
144
- And ".gtd/REVIEW.md" contains "## Fixed from your notes"
182
+ And ".gtd/REVIEW.md" contains "now rounds the difference"
145
183
  And ".gtd/REVIEW.md" does not contain "AC-1 ignores floating point"
146
184
  And ".gtd/TODO.md" does not exist
147
185
  When gtd lands
@@ -176,8 +214,9 @@ Feature: every note in the review is answered with one tick
176
214
  gtd(judge): build.review.triage → build.review.fix.nits.fixing
177
215
  gtd(agent): build.review.fix.nits.fixing → build.health.check
178
216
  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
217
+ gtd(check): build.review.closing → build.review.reviewing
218
+ gtd(agent): build.review.reviewing → build.review.carrying
219
+ gtd(check): build.review.carrying → build.review.await-review
181
220
  """
182
221
  And ".gtd/REVIEW.md" does not contain "AC-1 ignores floating point"
183
222
 
@@ -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
 
@@ -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.composing
82
- gtd(check): build.review.composing → build.review.await-review
81
+ gtd(check): implement.closing → build.review.reviewing
82
+ gtd(agent): build.review.reviewing → 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(check): build.review.composing → build.review.await-review
105
+ gtd(agent): build.review.reviewing → 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.composing
218
- gtd(check): build.review.composing → build.review.await-review
217
+ gtd(check): implement.closing → build.review.reviewing
218
+ gtd(agent): build.review.reviewing → build.review.await-review
219
219
  """
220
220
 
221
221
  Scenario: a design numbering new behaviour at or below an earlier ID is refused