@pmelab/gtd 55.0.0 → 57.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 (83) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +72 -80
  3. package/dist/chunks/{reserved-DHafcW7t.mjs → reserved-X2RkNHin.mjs} +110 -318
  4. package/dist/chunks/{review-BJGKwlYv.mjs → review-v7sh5GF4.mjs} +30 -125
  5. package/dist/chunks/{steering-CLhu8C7q.mjs → steering-CCNvngSH.mjs} +256 -65
  6. package/dist/chunks/{tail-B9Hw2AFB.mjs → tail-S04KEewi.mjs} +144 -56
  7. package/dist/gtd.bundle.mjs +259 -22
  8. package/dist/steering.mjs +2 -2
  9. package/dist/testkit.mjs +6 -6
  10. package/dist/web/main.css +1 -1
  11. package/dist/web/main.js +551 -66
  12. package/dist/workflow-kit.mjs +1 -1
  13. package/dist/workflows/cleanup.mjs +2 -2
  14. package/dist/workflows/feature.mjs +63 -175
  15. package/dist/workflows/fix.mjs +3 -3
  16. package/dist/workflows/review.mjs +3 -3
  17. package/dist/workflows/rollout.mjs +1 -1
  18. package/dist/workflows.mjs +603 -727
  19. package/package.json +1 -1
  20. package/skills/authoring/SKILL.md +3 -3
  21. package/src/cli/Cli.ts +5 -5
  22. package/src/edge/Edge.test.ts +1 -1
  23. package/src/steering/FORMATS.md +5 -1
  24. package/src/steering/SteeringFormats.test.ts +2 -2
  25. package/src/steering/contract.test.ts +1 -0
  26. package/src/steering/findings.test.ts +47 -0
  27. package/src/steering/findings.ts +350 -0
  28. package/src/steering/fixtures/findings/gate.md +34 -0
  29. package/src/steering/fixtures/findings/gate.read.json +87 -0
  30. package/src/steering/index.test.ts +2 -2
  31. package/src/steering/index.ts +4 -3
  32. package/src/steering/review.test.ts +1 -75
  33. package/src/steering/review.ts +1 -74
  34. package/src/workflow/compile.test.ts +1 -0
  35. package/src/workflows/feature/criteria-coverage.feature +1 -7
  36. package/src/workflows/feature/criteria.test.ts +1 -41
  37. package/src/workflows/feature/criteria.ts +2 -14
  38. package/src/workflows/feature/fast-path.feature +0 -1
  39. package/src/workflows/feature/feature.test.ts +1 -1
  40. package/src/workflows/feature/feature.ts +16 -25
  41. package/src/workflows/feature/flag-mode.feature +1 -1
  42. package/src/workflows/feature/lens-models.feature +0 -1
  43. package/src/workflows/feature/lens-review.feature +323 -172
  44. package/src/workflows/feature/naive-test.feature +258 -0
  45. package/src/workflows/feature/one-step-land.feature +0 -1
  46. package/src/workflows/feature/refactor-absorbs.feature +1 -8
  47. package/src/workflows/feature/refactor-first.feature +2 -11
  48. package/src/workflows/feature/refactor-rebuild.feature +4 -25
  49. package/src/workflows/feature/refactor-review.feature +33 -118
  50. package/src/workflows/feature/refactor.test.ts +0 -2
  51. package/src/workflows/feature/refactor.ts +0 -1
  52. package/src/workflows/feature/review-gate.feature +7 -24
  53. package/src/workflows/feature/reviewer-walkthrough.feature +16 -104
  54. package/src/workflows/feature/seam-rejection.feature +0 -1
  55. package/src/workflows/feature/seam.feature +0 -1
  56. package/src/workflows/feature/seam.test.ts +1 -2
  57. package/src/workflows/feature/seam.ts +56 -10
  58. package/src/workflows/feature/standards.feature +75 -35
  59. package/src/workflows/fix/fix-lens-origin.feature +20 -7
  60. package/src/workflows/fix/fix-quality.feature +102 -23
  61. package/src/workflows/review/review-door.feature +62 -59
  62. package/src/workflows/shared/learn.test.ts +0 -14
  63. package/src/workflows/shared/learn.ts +1 -6
  64. package/src/workflows/shared/lenses.ts +149 -43
  65. package/src/workflows/shared/options.ts +9 -1
  66. package/src/workflows/shared/prose.ts +0 -6
  67. package/src/workflows/shared/review.test.ts +27 -26
  68. package/src/workflows/shared/review.ts +29 -196
  69. package/src/workflows/shared/skills.test.ts +0 -4
  70. package/src/workflows/shared/skills.ts +0 -5
  71. package/src/workflows/shared/steps.ts +1 -1
  72. package/src/workflows/shared/tail.ts +18 -9
  73. package/src/workflows/shared/text.test.ts +125 -329
  74. package/src/workflows/shared/text.ts +173 -471
  75. package/src/workflows/shared/vars.ts +2 -3
  76. package/src/workflows/feature/hands-on-skip.feature +0 -316
  77. package/src/workflows/feature/prototype-rounds.feature +0 -156
  78. package/src/workflows/feature/prototype.feature +0 -428
  79. package/src/workflows/feature/prototype.test.ts +0 -43
  80. package/src/workflows/feature/prototype.ts +0 -198
  81. package/src/workflows/feature/review-answers.feature +0 -324
  82. package/src/workflows/feature/severity-budget.feature +0 -116
  83. package/src/workflows/feature/severity-sorted-review.feature +0 -198
@@ -1,15 +1,16 @@
1
1
  @inmem
2
- Feature: the quality lap's findings are triaged before the review
2
+ Feature: the quality lap's findings are triaged, then decided at the finding gate
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
- a trailer, and a design one becomes a note in `.gtd/REVIEW.md`, with answer
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.
6
+ a trailer, and a design one is a note. The notes, then the noise under
7
+ `# Dropped as noise`, rest at the finding gate (`build.quality.gate`), each
8
+ with one `- [ ] fix` box: a ticked finding is fixed, an unticked one
9
+ dropped. The review then walks through the code and lists, in one
10
+ `## Quality lap` chunk, what became of every finding.
9
11
 
10
12
  Background:
11
13
  Given the shipped workflows, as gtd install scaffolds them
12
- And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
13
14
  And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
14
15
  And an environment variable "GTD_FLAGMODE" set to "false"
15
16
  And a file "src/calc.ts" with:
@@ -74,14 +75,23 @@ Feature: the quality lap's findings are triaged before the review
74
75
  Should subtract round? The criterion does not say.
75
76
  """
76
77
  And step "build.quality.sorting" runs its script
78
+ And step "build.quality.gating" runs its script
79
+ And step "build.quality.picking" runs its script
77
80
  And step "build.quality.closing" runs its script
78
81
  And step "build.review.carrying" runs its script
79
- And judge step "build.review.ranking" answers:
82
+ And step "build.health.check" changes nothing
83
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
80
84
  """
81
- []
85
+ # Review: abc1234
86
+
87
+ <!-- base: 0000000 -->
88
+
89
+ ## Subtract
90
+
91
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
82
92
  """
83
93
 
84
- Scenario: a mechanical finding is fixed and listed, noise dropped and listed, a design one noted
94
+ Scenario: a mechanical finding is fixed, the rest wait at the finding gate, and an untouched gate drops them
85
95
  Given judge step "build.quality.triage" answers:
86
96
  """
87
97
  [{"id":"Q1","answer":"mechanical","p":0.9},{"id":"Q2","answer":"noise","p":0.85},{"id":"Q3","answer":"design","p":0.8}]
@@ -92,62 +102,56 @@ Feature: the quality lap's findings are triaged before the review
92
102
  it("subtracts a larger number", () => {})
93
103
  """
94
104
  And step "build.fix.quality.fixing" deletes ".gtd/QUALITY.md"
95
- And step "build.health.check" changes nothing
96
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
97
- """
98
- # Review: abc1234
99
-
100
- <!-- base: 0000000 -->
101
-
102
- ## Subtract
103
-
104
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
105
-
106
- ## AC-1 ignores floating point
107
-
108
- - [ ] ./src/calc.ts#2-2 — where it applies
109
- """
110
105
  When the process is driven
111
- Then the process rests at "build.review.await-review"
112
- And ".gtd/QUALITY.md" does not exist
106
+ Then the process rests at "build.quality.gate"
113
107
  And the commit "gtd(judge): build.quality.triage → build.quality.sorting" has a body containing "Gtd-Mark: noise=Q2 p=0.85 add could be a method"
114
- And ".gtd/REVIEW.md" contains:
108
+ And ".gtd/QUALITY.md" contains:
115
109
  """
116
- ## Findings
117
-
118
- ### AC-1 ignores floating point
110
+ ## AC-1 ignores floating point
119
111
 
120
- _critical: judge unsure_
112
+ _From lens correctness._
121
113
 
122
114
  Should subtract round? The criterion does not say.
123
115
 
124
- In the code:
116
+ - [ ] fix
125
117
 
126
- - [ ] ./src/calc.ts#2-2 — where it applies
118
+ # Dropped as noise
127
119
 
128
- Tick exactly one:
120
+ ## add could be a method
129
121
 
130
- - [ ] fix as suggested
131
- - [ ] won't fix
132
- - [ ] _your answer_
122
+ _From lens correctness. The judge called it noise (p=0.85)._
133
123
 
134
- ## Walkthrough
124
+ A class would read better.
135
125
 
136
- ### Subtract
126
+ - [ ] fix
137
127
  """
138
- And ".gtd/REVIEW.md" contains the short hash of the commit "gtd(agent): build.fix.quality.fixing → build.health.check"
128
+ When gtd lands
129
+ And the process is driven
130
+ Then the process rests at "build.review.await-review"
131
+ And ".gtd/QUALITY.md" does not exist
139
132
  And ".gtd/REVIEW.md" contains:
140
133
  """
141
- ## Dropped as noise
134
+ ## Quality lap
135
+
136
+ What the quality lenses found, and what became of it. Write a note under
137
+ a line to reopen it.
142
138
 
143
- - add could be a method (p=0.85)
139
+ Fixed automatically:
140
+
141
+ - subtract has no negative test (
144
142
  """
145
143
  And ".gtd/REVIEW.md" contains:
146
144
  """
147
- ## Fixed automatically
145
+ Dropped at the finding gate:
148
146
 
149
- - subtract has no negative test (
147
+ - AC-1 ignores floating point (lens correctness)
148
+
149
+ Dropped as noise:
150
+
151
+ - add could be a method (p=0.85, lens correctness)
150
152
  """
153
+ And ".gtd/REVIEW.md" contains the short hash of the commit "gtd(agent): build.fix.quality.fixing → build.health.check"
154
+ And ".gtd/REVIEW.md" does not contain "Tick exactly one:"
151
155
  And the commit subjects end with:
152
156
  """
153
157
  gtd(check): implement.closing → build.quality.correctness.reviewing
@@ -155,175 +159,228 @@ Feature: the quality lap's findings are triaged before the review
155
159
  gtd(judge): build.quality.triage → build.quality.sorting
156
160
  gtd(check): build.quality.sorting → build.fix.quality.fixing
157
161
  gtd(agent): build.fix.quality.fixing → build.health.check
158
- gtd(check): build.health.check → build.review.reviewing
159
- gtd(agent): build.review.reviewing → build.review.ranking
160
- gtd(judge): build.review.ranking → build.review.carrying
162
+ gtd(check): build.health.check → build.quality.gating
163
+ gtd(check): build.quality.gating → build.quality.gate
164
+ gtd(human): build.quality.gate → build.quality.closing
165
+ gtd(check): build.quality.closing → build.review.reviewing
166
+ gtd(agent): build.review.reviewing → build.review.carrying
161
167
  gtd(check): build.review.carrying → build.review.await-review
162
168
  """
163
169
 
164
- Scenario: a risk is fixed before the human sees the review, re-reviewed in the reviewer's own draft
170
+ Scenario: a ticked note is fixed with the human's guidance, never re-planned
165
171
  Given judge step "build.quality.triage" answers:
166
172
  """
167
- [{"id":"Q1","answer":"mechanical","p":0.9},{"id":"Q2","answer":"noise","p":0.85},{"id":"Q3","answer":"design","p":0.8}]
168
- """
169
- And step "build.fix.quality.fixing" writes "src/calc.test.ts" with:
173
+ [{"id":"Q1","answer":"noise","p":0.9},{"id":"Q2","answer":"noise","p":0.85},{"id":"Q3","answer":"design","p":0.8}]
170
174
  """
171
- it("[AC-1] subtracts", () => {})
172
- it("subtracts a larger number", () => {})
173
- """
174
- And step "build.fix.quality.fixing" deletes ".gtd/QUALITY.md"
175
- And step "build.health.check" changes nothing
176
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
175
+ When the process is driven
176
+ Then the process rests at "build.quality.gate"
177
+ Given a file ".gtd/QUALITY.md" with:
177
178
  """
178
- # Review: abc1234
179
+ # Quality
179
180
 
180
- <!-- base: 0000000 -->
181
+ ## AC-1 ignores floating point
181
182
 
182
- ## Subtract
183
+ _From lens correctness._
183
184
 
184
- - [ ] ./src/calc.ts#2-2 — Risk: overflows on large numbers
185
+ Should subtract round? The criterion does not say.
186
+
187
+ - [x] fix
188
+
189
+ Round half up.
190
+
191
+ # Dropped as noise
192
+
193
+ ## subtract has no negative test
194
+
195
+ _From lens correctness. The judge called it noise (p=0.9)._
196
+
197
+ Add a test subtracting a larger number.
198
+
199
+ - [ ] fix
200
+
201
+ ## add could be a method
202
+
203
+ _From lens correctness. The judge called it noise (p=0.85)._
204
+
205
+ A class would read better.
185
206
 
207
+ - [ ] fix
208
+ """
209
+ When gtd lands
210
+ And the process is driven
211
+ Then the process rests at "build.fix.quality.fixing"
212
+ And ".gtd/QUALITY.md" contains:
213
+ """
186
214
  ## AC-1 ignores floating point
187
215
 
188
- - [ ] ./src/calc.ts#2-2 — where it applies
216
+ Should subtract round? The criterion does not say.
217
+
218
+ Guidance from the human — follow it:
219
+
220
+ Round half up.
189
221
  """
190
- When the process is driven
191
- Then the process rests at "build.review.fix.risks.fixing"
192
- Given step "build.review.reviewing" is no longer scripted
193
- And step "build.review.reviewing" replaces the text "Risk: overflows on large numbers" in ".gtd/REVIEW.md" with "subtract(a, b), now guarded"
194
- And step "build.review.fix.risks.fixing" changes nothing
222
+ And ".gtd/QUALITY.md" does not contain "add could be a method"
223
+ Given step "build.fix.quality.fixing" writes "src/calc.ts" with:
224
+ """
225
+ export const add = (a: number, b: number) => a + b
226
+ export const subtract = (a: number, b: number) => Math.round(a - b)
227
+ """
228
+ And step "build.fix.quality.fixing" deletes ".gtd/QUALITY.md"
195
229
  When the process is driven
196
230
  Then the process rests at "build.review.await-review"
197
- And ".gtd/REVIEW.md" contains "subtract(a, b), now guarded"
198
- And ".gtd/REVIEW.md" contains "## Fixed automatically" exactly once
199
- And ".gtd/REVIEW.md" contains "## Dropped as noise" exactly once
200
- And ".gtd/REVIEW.md" contains "## Walkthrough" exactly once
201
- And ".gtd/REVIEW.md" contains "Should subtract round? The criterion does not say." exactly once
202
- And ".gtd/REVIEW.md" contains "Tick exactly one:" exactly once
231
+ And ".gtd/REVIEW.md" contains:
232
+ """
233
+ Fixed at the finding gate:
234
+
235
+ - AC-1 ignores floating point (
236
+ """
237
+ And ".gtd/REVIEW.md" contains:
238
+ """
239
+ Dropped as noise:
240
+
241
+ - subtract has no negative test (p=0.9, lens correctness)
242
+ - add could be a method (p=0.85, lens correctness)
243
+ """
203
244
  And the commit subjects end with:
204
245
  """
246
+ gtd(human): build.quality.gate → build.quality.picking
247
+ gtd(check): build.quality.picking → build.fix.quality.fixing
248
+ gtd(agent): build.fix.quality.fixing → build.health.check
205
249
  gtd(check): build.health.check → build.review.reviewing
206
- gtd(agent): build.review.reviewing → build.review.fix.risks.fixing
207
- gtd(agent): build.review.fix.risks.fixing → build.health.check
208
- gtd(check): build.health.check → build.review.reviewing
209
- gtd(agent): build.review.reviewing → build.review.ranking
210
- gtd(judge): build.review.ranking → build.review.carrying
250
+ gtd(agent): build.review.reviewing → build.review.carrying
211
251
  gtd(check): build.review.carrying → build.review.await-review
212
252
  """
213
253
 
214
- Scenario: an unsure verdict makes a finding a note, never a fix or a drop
254
+ Scenario: a finding the judge called noise is rescued by its tick
215
255
  Given judge step "build.quality.triage" answers:
216
256
  """
217
- [{"id":"Q1","answer":"mechanical","p":0.5},{"id":"Q2","answer":"noise","p":0.6}]
257
+ [{"id":"Q1","answer":"noise","p":0.9},{"id":"Q2","answer":"noise","p":0.85},{"id":"Q3","answer":"noise","p":0.8}]
218
258
  """
219
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
259
+ And step "build.fix.quality.fixing" deletes ".gtd/QUALITY.md"
260
+ When the process is driven
261
+ Then the process rests at "build.quality.gate"
262
+ Given a file ".gtd/QUALITY.md" with:
220
263
  """
221
- # Review: abc1234
222
-
223
- <!-- base: 0000000 -->
224
-
225
- ## Subtract
264
+ # Quality
226
265
 
227
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
266
+ # Dropped as noise
228
267
 
229
268
  ## subtract has no negative test
230
269
 
231
- - [ ] ./src/calc.ts#2-2 — where it applies
270
+ Add a test subtracting a larger number.
271
+
272
+ - [ ] fix
232
273
 
233
274
  ## add could be a method
234
275
 
235
- - [ ] ./src/calc.ts#2-2 — where it applies
276
+ A class would read better.
277
+
278
+ - [x] fix
236
279
 
237
280
  ## AC-1 ignores floating point
238
281
 
239
- - [ ] ./src/calc.ts#2-2 — where it applies
282
+ Should subtract round? The criterion does not say.
283
+
284
+ - [ ] fix
240
285
  """
241
- When the process is driven
286
+ When gtd lands
287
+ And the process is driven
242
288
  Then the process rests at "build.review.await-review"
243
- And ".gtd/REVIEW.md" contains "## subtract has no negative test"
244
- And ".gtd/REVIEW.md" contains "## add could be a method"
245
- And ".gtd/REVIEW.md" contains "## AC-1 ignores floating point"
246
- And ".gtd/REVIEW.md" does not contain "Fixed automatically"
247
- And no commit body contains "Gtd-Mark: noise="
248
- And the commit subjects end with:
289
+ And ".gtd/REVIEW.md" contains:
249
290
  """
250
- gtd(judge): build.quality.triage → build.quality.sorting
251
- gtd(check): build.quality.sorting → build.review.reviewing
252
- gtd(agent): build.review.reviewing → build.review.ranking
253
- gtd(judge): build.review.ranking → build.review.carrying
254
- gtd(check): build.review.carrying → build.review.await-review
291
+ Fixed at the finding gate:
292
+
293
+ - add could be a method (
294
+ """
295
+ And ".gtd/REVIEW.md" contains:
296
+ """
297
+ Dropped as noise:
298
+
299
+ - subtract has no negative test (p=0.9, lens correctness)
300
+ - AC-1 ignores floating point (p=0.8, lens correctness)
255
301
  """
256
302
 
257
- Scenario: a mechanical finding the fix cap leaves becomes a note
303
+ Scenario: guidance under an unticked box is refused
258
304
  Given judge step "build.quality.triage" answers:
259
305
  """
260
- [{"id":"Q1","answer":"mechanical","p":0.9},{"id":"Q2","answer":"mechanical","p":0.9},{"id":"Q3","answer":"mechanical","p":0.9}]
306
+ [{"id":"Q1","answer":"noise","p":0.9},{"id":"Q2","answer":"noise","p":0.85},{"id":"Q3","answer":"design","p":0.8}]
261
307
  """
262
- And step "build.fix.quality.fixing" writes ".gtd/QUALITY.md" with:
308
+ When the process is driven
309
+ Then the process rests at "build.quality.gate"
310
+ Given a file ".gtd/QUALITY.md" with:
263
311
  """
264
312
  # Quality
265
313
 
266
- ## add could be a method
314
+ ## AC-1 ignores floating point
267
315
 
268
- A class would read better.
269
- """
270
- And step "build.health.check" changes nothing
271
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
272
- """
273
- # Review: abc1234
316
+ Should subtract round? The criterion does not say.
274
317
 
275
- <!-- base: 0000000 -->
318
+ - [ ] fix
276
319
 
277
- ## Subtract
320
+ Round half up.
321
+ """
322
+ Then landing is refused with "finding-gate: 1 problem(s) in .gtd/QUALITY.md"
323
+ And landing is refused with "has guidance under an unticked box — tick it to fix the finding, or delete the text to drop it"
278
324
 
279
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
325
+ Scenario: a ticked finding the fix cap leaves is listed unresolved, with no second gate
326
+ Given judge step "build.quality.triage" answers:
327
+ """
328
+ [{"id":"Q1","answer":"noise","p":0.9},{"id":"Q2","answer":"noise","p":0.85},{"id":"Q3","answer":"design","p":0.8}]
329
+ """
330
+ And step "build.fix.quality.fixing" changes nothing
331
+ When the process is driven
332
+ Then the process rests at "build.quality.gate"
333
+ Given a file ".gtd/QUALITY.md" with:
334
+ """
335
+ # Quality
280
336
 
281
- ## add could be a method
337
+ ## AC-1 ignores floating point
338
+
339
+ Should subtract round? The criterion does not say.
282
340
 
283
- - [ ] ./src/calc.ts#2-2 — where it applies
341
+ - [x] fix
284
342
  """
285
- When the process is driven
343
+ When gtd lands
344
+ And the process is driven
286
345
  Then the process rests at "build.review.await-review"
287
346
  And ".gtd/QUALITY.md" does not exist
288
347
  And ".gtd/REVIEW.md" contains:
289
348
  """
290
- ### add could be a method
291
-
292
- _critical: judge unsure_
293
-
294
- _The fixer left this unresolved._
349
+ Unresolved after the finding gate:
295
350
 
296
- A class would read better.
351
+ - AC-1 ignores floating point (lens correctness)
297
352
  """
298
- And ".gtd/REVIEW.md" contains "- subtract has no negative test ("
299
- And ".gtd/REVIEW.md" contains "- AC-1 ignores floating point ("
300
353
  And the commit subjects end with:
301
354
  """
302
- gtd(judge): build.quality.triage → build.fix.quality.fixing
355
+ gtd(human): build.quality.gate → build.quality.picking
356
+ gtd(check): build.quality.picking → build.fix.quality.fixing
303
357
  gtd(agent): build.fix.quality.fixing
304
358
  gtd(agent): build.fix.quality.fixing
305
359
  gtd(agent): build.fix.quality.fixing → build.health.check
306
360
  gtd(check): build.health.check → build.quality.closing
307
361
  gtd(check): build.quality.closing → build.review.reviewing
308
- gtd(agent): build.review.reviewing → build.review.ranking
309
- gtd(judge): build.review.ranking → build.review.carrying
362
+ gtd(agent): build.review.reviewing → build.review.carrying
310
363
  gtd(check): build.review.carrying → build.review.await-review
311
364
  """
312
365
 
313
- Scenario: a fixer that renames a chunk it leaves counts nothing fixed
366
+ Scenario: a lap whose every finding was fixed has no gate
314
367
  Given judge step "build.quality.triage" answers:
315
368
  """
316
369
  [{"id":"Q1","answer":"mechanical","p":0.9},{"id":"Q2","answer":"mechanical","p":0.9},{"id":"Q3","answer":"mechanical","p":0.9}]
317
370
  """
318
- And step "build.fix.quality.fixing" writes ".gtd/QUALITY.md" with:
319
- """
320
- # Quality
321
-
322
- ## null check in parse()
371
+ And step "build.fix.quality.fixing" deletes ".gtd/QUALITY.md"
372
+ When the process is driven
373
+ Then the process rests at "build.review.await-review"
374
+ And no commit body contains "build.quality.gate"
375
+ And ".gtd/REVIEW.md" contains "- AC-1 ignores floating point ("
323
376
 
324
- Still open.
377
+ Scenario: a risk is fixed before the human sees the review, re-reviewed in the reviewer's own draft
378
+ Given judge step "build.quality.triage" answers:
325
379
  """
326
- And step "build.health.check" changes nothing
380
+ [{"id":"Q1","answer":"mechanical","p":0.9},{"id":"Q2","answer":"noise","p":0.85},{"id":"Q3","answer":"design","p":0.8}]
381
+ """
382
+ And step "build.fix.quality.fixing" deletes ".gtd/QUALITY.md"
383
+ And step "build.quality.gate" changes nothing
327
384
  And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
328
385
  """
329
386
  # Review: abc1234
@@ -332,30 +389,111 @@ Feature: the quality lap's findings are triaged before the review
332
389
 
333
390
  ## Subtract
334
391
 
335
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
392
+ - [ ] ./src/calc.ts#2-2 — Risk: overflows on large numbers
393
+ """
394
+ When the process is driven
395
+ Then the process rests at "build.review.fix.risks.fixing"
396
+ And ".gtd/REVIEW.md" does not contain "## Quality lap"
397
+ Given step "build.review.reviewing" is no longer scripted
398
+ And step "build.review.reviewing" replaces the text "Risk: overflows on large numbers" in ".gtd/REVIEW.md" with "subtract(a, b), now guarded"
399
+ And step "build.review.fix.risks.fixing" changes nothing
400
+ When the process is driven
401
+ Then the process rests at "build.review.await-review"
402
+ And ".gtd/REVIEW.md" contains "subtract(a, b), now guarded"
403
+ And ".gtd/REVIEW.md" contains "## Quality lap" exactly once
404
+ And ".gtd/REVIEW.md" contains "Fixed automatically:" exactly once
405
+ And the commit subjects end with:
406
+ """
407
+ gtd(check): build.quality.closing → build.review.reviewing
408
+ gtd(agent): build.review.reviewing → build.review.fix.risks.fixing
409
+ gtd(agent): build.review.fix.risks.fixing → build.health.check
410
+ gtd(check): build.health.check → build.review.reviewing
411
+ gtd(agent): build.review.reviewing → build.review.carrying
412
+ gtd(check): build.review.carrying → build.review.await-review
413
+ """
336
414
 
337
- ## subtract has no negative test
415
+ Scenario: an unsure verdict makes a finding a note, never a fix or a drop
416
+ Given judge step "build.quality.triage" answers:
417
+ """
418
+ [{"id":"Q1","answer":"mechanical","p":0.5},{"id":"Q2","answer":"noise","p":0.6}]
419
+ """
420
+ When the process is driven
421
+ Then the process rests at "build.quality.gate"
422
+ And ".gtd/QUALITY.md" contains "## subtract has no negative test"
423
+ And ".gtd/QUALITY.md" contains "## add could be a method"
424
+ And ".gtd/QUALITY.md" contains "## AC-1 ignores floating point"
425
+ And ".gtd/QUALITY.md" does not contain "# Dropped as noise"
426
+ And no commit body contains "Gtd-Mark: noise="
427
+ And the commit subjects end with:
428
+ """
429
+ gtd(agent): build.quality.correctness.reviewing → build.quality.triage
430
+ gtd(judge): build.quality.triage → build.quality.gating
431
+ gtd(check): build.quality.gating → build.quality.gate
432
+ """
338
433
 
339
- - [ ] ./src/calc.ts#2-2 — where it applies
434
+ Scenario: a mechanical finding the fix cap leaves reaches the gate as unresolved
435
+ Given judge step "build.quality.triage" answers:
436
+ """
437
+ [{"id":"Q1","answer":"mechanical","p":0.9},{"id":"Q2","answer":"mechanical","p":0.9},{"id":"Q3","answer":"mechanical","p":0.9}]
438
+ """
439
+ And step "build.fix.quality.fixing" writes ".gtd/QUALITY.md" with:
440
+ """
441
+ # Quality
340
442
 
341
443
  ## add could be a method
342
444
 
343
- - [ ] ./src/calc.ts#2-2 — where it applies
445
+ A class would read better.
446
+ """
447
+ When the process is driven
448
+ Then the process rests at "build.quality.gate"
449
+ And ".gtd/QUALITY.md" contains:
450
+ """
451
+ ## add could be a method
344
452
 
345
- ## AC-1 ignores floating point
453
+ _From lens correctness. The fixer left it unresolved._
454
+
455
+ A class would read better.
456
+
457
+ - [ ] fix
458
+ """
459
+ And the commit subjects end with:
460
+ """
461
+ gtd(judge): build.quality.triage → build.fix.quality.fixing
462
+ gtd(agent): build.fix.quality.fixing
463
+ gtd(agent): build.fix.quality.fixing
464
+ gtd(agent): build.fix.quality.fixing → build.health.check
465
+ gtd(check): build.health.check → build.quality.gating
466
+ gtd(check): build.quality.gating → build.quality.gate
467
+ """
468
+ When gtd lands
469
+ And the process is driven
470
+ Then the process rests at "build.review.await-review"
471
+ And ".gtd/REVIEW.md" contains "- subtract has no negative test ("
472
+ And ".gtd/REVIEW.md" contains:
473
+ """
474
+ Dropped at the finding gate:
346
475
 
347
- - [ ] ./src/calc.ts#2-2 — where it applies
476
+ - add could be a method (lens correctness)
477
+ """
478
+
479
+ Scenario: a fixer that renames a chunk it leaves counts nothing fixed
480
+ Given judge step "build.quality.triage" answers:
481
+ """
482
+ [{"id":"Q1","answer":"mechanical","p":0.9},{"id":"Q2","answer":"mechanical","p":0.9},{"id":"Q3","answer":"mechanical","p":0.9}]
483
+ """
484
+ And step "build.fix.quality.fixing" writes ".gtd/QUALITY.md" with:
485
+ """
486
+ # Quality
348
487
 
349
488
  ## null check in parse()
350
489
 
351
- - [ ] ./src/calc.ts#2-2 — where it applies
490
+ Still open.
352
491
  """
353
492
  When the process is driven
354
- Then the process rests at "build.review.await-review"
355
- And ".gtd/REVIEW.md" contains "## null check in parse()"
356
- And ".gtd/REVIEW.md" contains "## subtract has no negative test"
357
- And ".gtd/REVIEW.md" contains "check whether it was fixed"
358
- And ".gtd/REVIEW.md" does not contain "Fixed automatically"
493
+ Then the process rests at "build.quality.gate"
494
+ And ".gtd/QUALITY.md" contains "## null check in parse()"
495
+ And ".gtd/QUALITY.md" contains "## subtract has no negative test"
496
+ And ".gtd/QUALITY.md" contains "check whether it was fixed"
359
497
 
360
498
  Scenario: prose the fixer leaves outside every chunk does not hide its fixes
361
499
  Given judge step "build.quality.triage" answers:
@@ -368,38 +506,18 @@ Feature: the quality lap's findings are triaged before the review
368
506
 
369
507
  All fixed.
370
508
  """
371
- And step "build.health.check" changes nothing
372
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
373
- """
374
- # Review: abc1234
375
-
376
- <!-- base: 0000000 -->
377
-
378
- ## Subtract
379
-
380
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
381
- """
382
509
  When the process is driven
383
510
  Then the process rests at "build.review.await-review"
384
511
  And ".gtd/REVIEW.md" contains "- subtract has no negative test ("
385
512
  And ".gtd/REVIEW.md" does not contain "check whether it was fixed"
386
513
 
387
- Scenario: signing off a review with no notes ends the process
514
+ Scenario: signing off the review ends the process
388
515
  Given judge step "build.quality.triage" answers:
389
516
  """
390
517
  [{"id":"Q1","answer":"noise","p":0.9},{"id":"Q2","answer":"noise","p":0.9},{"id":"Q3","answer":"noise","p":0.9}]
391
518
  """
519
+ And step "build.quality.gate" changes nothing
392
520
  And step "build.review.closing" runs its script
393
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
394
- """
395
- # Review: abc1234
396
-
397
- <!-- base: 0000000 -->
398
-
399
- ## Subtract
400
-
401
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
402
- """
403
521
  When the process is driven
404
522
  Then the process rests at "build.review.await-review"
405
523
  When gtd lands
@@ -408,9 +526,42 @@ Feature: the quality lap's findings are triaged before the review
408
526
  And ".gtd/REVIEW.md" does not exist
409
527
  And the commit subjects end with:
410
528
  """
411
- gtd(agent): build.review.reviewing → build.review.ranking
412
- gtd(judge): build.review.ranking → build.review.carrying
529
+ gtd(agent): build.review.reviewing → build.review.carrying
413
530
  gtd(check): build.review.carrying → build.review.await-review
414
531
  gtd(human): build.review.await-review → build.review.closing
415
532
  gtd(check): build.review.closing → idle
416
533
  """
534
+
535
+ Scenario: a finding whose entry the human deleted is listed as dropped
536
+ Given judge step "build.quality.triage" answers:
537
+ """
538
+ [{"id":"Q1","answer":"noise","p":0.9},{"id":"Q2","answer":"noise","p":0.85},{"id":"Q3","answer":"design","p":0.8}]
539
+ """
540
+ When the process is driven
541
+ Then the process rests at "build.quality.gate"
542
+ Given a file ".gtd/QUALITY.md" with:
543
+ """
544
+ # Quality
545
+
546
+ # Dropped as noise
547
+
548
+ ## add could be a method
549
+
550
+ A class would read better.
551
+
552
+ - [ ] fix
553
+ """
554
+ When gtd lands
555
+ And the process is driven
556
+ Then the process rests at "build.review.await-review"
557
+ And ".gtd/REVIEW.md" contains:
558
+ """
559
+ Dropped at the finding gate:
560
+
561
+ - AC-1 ignores floating point (lens correctness)
562
+
563
+ Dropped as noise:
564
+
565
+ - add could be a method (p=0.85, lens correctness)
566
+ - subtract has no negative test (p=0.9, lens correctness)
567
+ """