@pmelab/gtd 55.0.0 → 56.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 (61) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +60 -61
  3. package/dist/chunks/{reserved-DHafcW7t.mjs → reserved-B8EC-WE8.mjs} +77 -203
  4. package/dist/chunks/{review-BJGKwlYv.mjs → review-HdrX0FJ7.mjs} +30 -125
  5. package/dist/chunks/{steering-CLhu8C7q.mjs → steering-CCNvngSH.mjs} +256 -65
  6. package/dist/chunks/{tail-B9Hw2AFB.mjs → tail-BSLah2mA.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 +14 -16
  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 +522 -453
  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 -6
  36. package/src/workflows/feature/feature.test.ts +1 -1
  37. package/src/workflows/feature/feature.ts +12 -20
  38. package/src/workflows/feature/lens-review.feature +323 -171
  39. package/src/workflows/feature/refactor-absorbs.feature +1 -7
  40. package/src/workflows/feature/refactor-first.feature +2 -10
  41. package/src/workflows/feature/refactor-rebuild.feature +4 -24
  42. package/src/workflows/feature/refactor-review.feature +33 -117
  43. package/src/workflows/feature/refactor.test.ts +0 -2
  44. package/src/workflows/feature/refactor.ts +0 -1
  45. package/src/workflows/feature/review-gate.feature +6 -22
  46. package/src/workflows/feature/reviewer-walkthrough.feature +16 -103
  47. package/src/workflows/feature/standards.feature +75 -34
  48. package/src/workflows/fix/fix-lens-origin.feature +20 -7
  49. package/src/workflows/fix/fix-quality.feature +102 -23
  50. package/src/workflows/review/review-door.feature +62 -59
  51. package/src/workflows/shared/learn.test.ts +0 -14
  52. package/src/workflows/shared/learn.ts +1 -6
  53. package/src/workflows/shared/lenses.ts +149 -43
  54. package/src/workflows/shared/review.test.ts +27 -26
  55. package/src/workflows/shared/review.ts +29 -196
  56. package/src/workflows/shared/tail.ts +18 -9
  57. package/src/workflows/shared/text.test.ts +103 -288
  58. package/src/workflows/shared/text.ts +131 -329
  59. package/src/workflows/feature/review-answers.feature +0 -324
  60. package/src/workflows/feature/severity-budget.feature +0 -116
  61. package/src/workflows/feature/severity-sorted-review.feature +0 -198
@@ -3,16 +3,15 @@ Feature: a reviewer walks the human through the feature's code
3
3
 
4
4
  The feature's final review is written by a reviewer turn
5
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.
6
+ code, so the phone shows it. The quality lap's findings were decided at the
7
+ finding gate: the reviewer is told nothing of them, and gtd only appends
8
+ the lap's summary (`build.review.carrying`). A chunk pointing at no code is
9
+ refused.
11
10
 
12
11
  Background:
13
12
  Given the shipped workflows, as gtd install scaffolds them
14
13
  And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
15
- And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
14
+ And an environment variable "GTD_QUALITYREVIEWS" set to ""
16
15
  And an environment variable "GTD_FLAGMODE" set to "false"
17
16
  And a file "src/calc.ts" with:
18
17
  """
@@ -53,30 +52,9 @@ Feature: a reviewer walks the human through the feature's code
53
52
  And step "implement.applying" runs its script
54
53
  And step "implement.health.check" changes nothing
55
54
  And step "implement.closing" runs its script
56
- And step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
57
- """
58
- # Quality
59
-
60
- ## AC-1 ignores floating point
61
-
62
- Should subtract round? The criterion does not say.
63
- """
64
- And judge step "build.quality.triage" answers:
65
- """
66
- [{"id":"Q1","answer":"design","p":0.9}]
67
- """
68
- And step "build.quality.sorting" runs its script
69
- And step "build.quality.closing" runs its script
70
- And step "build.review.carrying" runs its script
71
- And judge step "build.review.ranking" answers:
72
- """
73
- []
74
- """
75
55
 
76
- Scenario: the finding gets its text and answer boxes under the reviewer's pointers
77
- Given step "build.review.reviewing" is prompted with "- `## AC-1 ignores floating point`:"
78
- And step "build.review.reviewing" is prompted with "> Should subtract round? The criterion does not say."
79
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
56
+ Scenario: the review is the reviewer's walkthrough, as it wrote it
57
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
80
58
  """
81
59
  # Review: abc1234
82
60
 
@@ -87,47 +65,24 @@ Feature: a reviewer walks the human through the feature's code
87
65
  The new export.
88
66
 
89
67
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
90
-
91
- ## AC-1 ignores floating point
92
-
93
- - [ ] ./src/calc.ts#2-2 — returns the raw difference
94
68
  """
95
69
  When the process is driven
96
70
  Then the process rests at "build.review.await-review"
71
+ And the resting step's content does not contain "Tick exactly one"
97
72
  And ".gtd/REVIEW.md" contains:
98
73
  """
99
- ## Findings
100
-
101
- ### AC-1 ignores floating point
102
-
103
- _critical: judge unsure_
104
-
105
- Should subtract round? The criterion does not say.
106
-
107
- In the code:
108
-
109
- - [ ] ./src/calc.ts#2-2 — returns the raw difference
110
-
111
- Tick exactly one:
112
-
113
- - [ ] fix as suggested
114
- - [ ] won't fix
115
- - [ ] _your answer_
116
-
117
- ## Walkthrough
74
+ <!-- base: 0000000 -->
118
75
 
119
- ### Subtract
76
+ ## Subtract
120
77
 
121
78
  The new export.
122
79
 
123
80
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
124
81
  """
125
- And no commit body contains "build.review.composing"
126
82
  And the commit subjects end with:
127
83
  """
128
- gtd(agent): build.review.reviewing → build.review.ranking
129
- gtd(judge): build.review.ranking → build.review.carrying
130
- gtd(check): build.review.carrying → build.review.await-review
84
+ gtd(check): implement.closing → build.review.reviewing
85
+ gtd(agent): build.review.reviewing → build.review.await-review
131
86
  """
132
87
 
133
88
  Scenario: a chunk pointing at no code is refused
@@ -140,10 +95,6 @@ Feature: a reviewer walks the human through the feature's code
140
95
  ## Subtract
141
96
 
142
97
  The new export, with no pointer.
143
-
144
- ## AC-1 ignores floating point
145
-
146
- - [ ] ./src/calc.ts#2-2 — returns the raw difference
147
98
  """
148
99
  Then driving the process is refused with "Subtract — points at no code"
149
100
 
@@ -158,26 +109,9 @@ Feature: a reviewer walks the human through the feature's code
158
109
 
159
110
  ### Subtract
160
111
 
161
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
162
-
163
- ### AC-1 ignores floating point
164
-
165
- - [ ] ./src/calc.ts#2-2 — returns the raw difference
166
- """
167
- Then driving the process is refused with "Walkthrough — gtd sorts the chunks into sections; write `## ` chunks only"
168
-
169
- Scenario: a finding the reviewer left out is refused
170
- Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
171
- """
172
- # Review: abc1234
173
-
174
- <!-- base: 0000000 -->
175
-
176
- ## Subtract
177
-
178
112
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
179
113
  """
180
- Then driving the process is refused with "AC-1 ignores floating point — no chunk of its own"
114
+ Then driving the process is refused with "Walkthrough — write `## ` chunks only"
181
115
 
182
116
  Scenario: a standard conflict the reviewer writes itself is refused
183
117
  Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
@@ -189,31 +123,10 @@ Feature: a reviewer walks the human through the feature's code
189
123
  ## Standard conflict 0123abcd
190
124
 
191
125
  - [ ] ./src/calc.ts#2-2 — copied over
192
-
193
- ## AC-1 ignores floating point
194
-
195
- - [ ] ./src/calc.ts#2-2 — returns the raw difference
196
126
  """
197
127
  Then driving the process is refused with "Standard conflict 0123abcd — gtd writes conflicts"
198
128
 
199
129
  Scenario: two chunks with one title are refused
200
- Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
201
- """
202
- # Review: abc1234
203
-
204
- <!-- base: 0000000 -->
205
-
206
- ## AC-1 ignores floating point
207
-
208
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
209
-
210
- ## AC-1 ignores floating point
211
-
212
- - [ ] ./src/calc.ts#2-2 — returns the raw difference
213
- """
214
- Then driving the process is refused with "AC-1 ignores floating point — a second chunk with this title"
215
-
216
- Scenario: a risk marked in a finding's chunk is refused, never fixed
217
130
  Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
218
131
  """
219
132
  # Review: abc1234
@@ -224,8 +137,8 @@ Feature: a reviewer walks the human through the feature's code
224
137
 
225
138
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
226
139
 
227
- ## AC-1 ignores floating point
140
+ ## Subtract
228
141
 
229
- - [ ] ./src/calc.ts#2-2 — Risk: no rounding
142
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
230
143
  """
231
- Then driving the process is refused with "no `Risk:` in a quality finding's chunk"
144
+ Then driving the process is refused with "Subtract — a second chunk with this title"
@@ -1,8 +1,8 @@
1
1
  @inmem
2
2
  Feature: the review learns standards from the human's answers
3
3
 
4
- A won't-fix tick or an own answer at the review gate is a candidate
5
- standard. A judge asks whether it is reusable; above `standardMinP` it is
4
+ A won't-fix tick or an own answer at the review gate — on a note the human
5
+ added with its own answer boxes — is a candidate standard. A judge asks whether it is reusable; above `standardMinP` it is
6
6
  kept in `.gtd/STANDARDS.md` with no further question, and every later agent
7
7
  turn — lenses and coder alike — is told to follow it. One that contradicts
8
8
  a standard already kept becomes a note in `.gtd/REVIEW.md` the review cannot
@@ -12,7 +12,7 @@ Feature: the review learns standards from the human's answers
12
12
  Background:
13
13
  Given the shipped workflows, as gtd install scaffolds them
14
14
  And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
15
- And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
15
+ And an environment variable "GTD_QUALITYREVIEWS" set to ""
16
16
  And an environment variable "GTD_FLAGMODE" set to "false"
17
17
  And a file "src/calc.ts" with:
18
18
  """
@@ -59,15 +59,6 @@ Feature: the review learns standards from the human's answers
59
59
  And step "implement.applying" runs its script
60
60
  And step "implement.health.check" changes nothing
61
61
  And step "implement.closing" runs its script
62
- And step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
63
- """
64
- # Quality
65
-
66
- ## subtract has no class
67
-
68
- Calculators read better as classes.
69
- """
70
- And step "build.quality.sorting" runs its script
71
62
  And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
72
63
  """
73
64
  # Review: abc1234
@@ -78,29 +69,7 @@ Feature: the review learns standards from the human's answers
78
69
 
79
70
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
80
71
  """
81
- And step "build.review.reviewing", when prompted with "- `## subtract has no class`", writes ".gtd/REVIEW.md" with:
82
- """
83
- # Review: abc1234
84
-
85
- <!-- base: 0000000 -->
86
-
87
- ## Subtract
88
-
89
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
90
-
91
- ## subtract has no class
92
-
93
- - [ ] ./src/calc.ts#2-2 — a plain function
94
- """
95
72
  And step "build.review.carrying" runs its script
96
- And judge step "build.review.ranking" answers:
97
- """
98
- []
99
- """
100
- And judge step "build.quality.triage" answers:
101
- """
102
- [{"id":"Q1","answer":"design","p":0.9}]
103
- """
104
73
  And step "build.review.closing" runs its script
105
74
  And step "build.review.standards.recording" runs its script
106
75
  And step "build.review.standards.raising" runs its script
@@ -111,6 +80,18 @@ Feature: the review learns standards from the human's answers
111
80
  [{"id":"standard-1","answer":"yes","p":0.9}]
112
81
  """
113
82
  When the process is driven
83
+ And ".gtd/REVIEW.md" gets appended:
84
+ """
85
+ ## subtract has no class
86
+
87
+ Calculators read better as classes.
88
+
89
+ Tick exactly one:
90
+
91
+ - [ ] fix as suggested
92
+ - [ ] won't fix
93
+ - [ ] _your answer_
94
+ """
114
95
  And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
115
96
  And gtd lands
116
97
  And the process is driven
@@ -143,6 +124,18 @@ Feature: the review learns standards from the human's answers
143
124
  """
144
125
  And step "build.health.check" changes nothing
145
126
  When the process is driven
127
+ And ".gtd/REVIEW.md" gets appended:
128
+ """
129
+ ## subtract has no class
130
+
131
+ Calculators read better as classes.
132
+
133
+ Tick exactly one:
134
+
135
+ - [ ] fix as suggested
136
+ - [ ] won't fix
137
+ - [ ] _your answer_
138
+ """
146
139
  And the text "- [ ] _your answer_" in ".gtd/REVIEW.md" is replaced with "- [x] Calculators are plain functions."
147
140
  And gtd lands
148
141
  And the process is driven
@@ -162,6 +155,18 @@ Feature: the review learns standards from the human's answers
162
155
  [{"id":"standard-1","answer":"yes","p":0.6}]
163
156
  """
164
157
  When the process is driven
158
+ And ".gtd/REVIEW.md" gets appended:
159
+ """
160
+ ## subtract has no class
161
+
162
+ Calculators read better as classes.
163
+
164
+ Tick exactly one:
165
+
166
+ - [ ] fix as suggested
167
+ - [ ] won't fix
168
+ - [ ] _your answer_
169
+ """
165
170
  And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
166
171
  And gtd lands
167
172
  And the process is driven
@@ -210,6 +215,18 @@ Feature: the review learns standards from the human's answers
210
215
  [{"id":"answer-1","answer":"praise","p":0.9}]
211
216
  """
212
217
  When the process is driven
218
+ And ".gtd/REVIEW.md" gets appended:
219
+ """
220
+ ## subtract has no class
221
+
222
+ Calculators read better as classes.
223
+
224
+ Tick exactly one:
225
+
226
+ - [ ] fix as suggested
227
+ - [ ] won't fix
228
+ - [ ] _your answer_
229
+ """
213
230
  And the text "- [ ] _your answer_" in ".gtd/REVIEW.md" is replaced with "- [x] Calculators are plain functions."
214
231
  And gtd lands
215
232
  And the process is driven
@@ -267,6 +284,18 @@ Feature: the review learns standards from the human's answers
267
284
  [{"id":"standard-1","answer":"yes","p":0.9},{"id":"standard-1.contradicts-1","answer":"yes","p":0.8}]
268
285
  """
269
286
  When the process is driven
287
+ And ".gtd/REVIEW.md" gets appended:
288
+ """
289
+ ## subtract has no class
290
+
291
+ Calculators read better as classes.
292
+
293
+ Tick exactly one:
294
+
295
+ - [ ] fix as suggested
296
+ - [ ] won't fix
297
+ - [ ] _your answer_
298
+ """
270
299
  And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
271
300
  And gtd lands
272
301
  And the process is driven
@@ -303,6 +332,18 @@ Feature: the review learns standards from the human's answers
303
332
  [{"id":"standard-1","answer":"yes","p":0.9},{"id":"standard-1.contradicts-1","answer":"yes","p":0.8}]
304
333
  """
305
334
  When the process is driven
335
+ And ".gtd/REVIEW.md" gets appended:
336
+ """
337
+ ## subtract has no class
338
+
339
+ Calculators read better as classes.
340
+
341
+ Tick exactly one:
342
+
343
+ - [ ] fix as suggested
344
+ - [ ] won't fix
345
+ - [ ] _your answer_
346
+ """
306
347
  And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
307
348
  And gtd lands
308
349
  And the process is driven
@@ -1,9 +1,8 @@
1
1
  @inmem
2
- Feature: each finding the reviewer is handed names the lens that wrote it
2
+ Feature: each finding at the finding gate names the lens that wrote it
3
3
 
4
4
  Lenses append to `.gtd/QUALITY.md` in turn, so a finding belongs to the lens
5
- whose turn added it — even when two lenses give findings the same title,
6
- which the review then tells apart by a numbered suffix.
5
+ whose turn added it — even when two lenses give findings the same title.
7
6
 
8
7
  Background:
9
8
  Given the shipped workflows, as gtd install scaffolds them
@@ -62,7 +61,7 @@ Feature: each finding the reviewer is handed names the lens that wrote it
62
61
 
63
62
  From tests.
64
63
  """
65
- And step "build.quality.sorting" runs its script
64
+ And step "build.quality.gating" runs its script
66
65
  And step "build.quality.closing" runs its script
67
66
  And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
68
67
  """
@@ -84,8 +83,8 @@ Feature: each finding the reviewer is handed names the lens that wrote it
84
83
  """
85
84
  When gtd opens door "fix"
86
85
  And the process is driven
87
- Then the process rests at "build.review.await-review"
88
- And ".gtd/REVIEW.md" contains:
86
+ Then the process rests at "build.quality.gate"
87
+ And ".gtd/QUALITY.md" contains:
89
88
  """
90
89
  ## sum is untested
91
90
 
@@ -93,9 +92,23 @@ Feature: each finding the reviewer is handed names the lens that wrote it
93
92
 
94
93
  From correctness.
95
94
 
96
- ## sum is untested (2)
95
+ - [ ] fix
96
+
97
+ ## sum is untested
97
98
 
98
99
  _From lens tests._
99
100
 
100
101
  From tests.
102
+
103
+ - [ ] fix
104
+ """
105
+ When gtd lands
106
+ And the process is driven
107
+ Then the process rests at "build.review.await-review"
108
+ And ".gtd/REVIEW.md" contains:
109
+ """
110
+ Dropped at the finding gate:
111
+
112
+ - sum is untested (lens correctness)
113
+ - sum is untested (lens tests)
101
114
  """
@@ -1,11 +1,12 @@
1
1
  @inmem
2
- Feature: fix's quality lap is triaged, and its leftovers go to the hand-off review
2
+ Feature: fix's quality lap is triaged, and its leftovers are decided at the finding gate
3
3
 
4
4
  A judge sorts the lap's findings: mechanical ones are fixed for up to three
5
- turns, noise is dropped, and design ones — with whatever the fix turns left —
6
- are added to the reviewer's `.gtd/REVIEW.md` by gtd, never to a person's
7
- gate before the review. With no requirements to check against, the
8
- `criteria-coverage` lens runs no turn.
5
+ turns, and the design ones — with whatever the fix turns left, and the
6
+ noise — wait at the finding gate, never at an escalation. A ticked one is
7
+ fixed on the spot; the hand-off review lists what became of each in its
8
+ summary and carries no finding on to the next `fix`. With no requirements
9
+ to check against, the `criteria-coverage` lens runs no turn.
9
10
 
10
11
  Background:
11
12
  Given the shipped workflows, as gtd install scaffolds them
@@ -57,6 +58,8 @@ Feature: fix's quality lap is triaged, and its leftovers go to the hand-off revi
57
58
  The glossary says plus.
58
59
  """
59
60
  And step "build.quality.sorting" runs its script
61
+ And step "build.quality.gating" runs its script
62
+ And step "build.quality.picking" runs its script
60
63
  And step "build.quality.closing" runs its script
61
64
  And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
62
65
  """
@@ -71,7 +74,7 @@ Feature: fix's quality lap is triaged, and its leftovers go to the hand-off revi
71
74
  """
72
75
  And step "build.review.carrying" runs its script
73
76
 
74
- Scenario: a design finding and one the fix cap left reach the reviewer, never an escalation
77
+ Scenario: a design finding and one the fix cap left reach the finding gate, and a ticked one is fixed there
75
78
  Given judge step "build.quality.triage" answers:
76
79
  """
77
80
  [{"id":"Q1","answer":"mechanical","p":0.9},{"id":"Q2","answer":"design","p":0.9}]
@@ -79,36 +82,72 @@ Feature: fix's quality lap is triaged, and its leftovers go to the hand-off revi
79
82
  And step "build.fix.quality.fixing" changes nothing
80
83
  When gtd opens door "fix"
81
84
  And the process is driven
82
- Then the process rests at "build.review.await-review"
83
- And ".gtd/QUALITY.md" does not exist
85
+ Then the process rests at "build.quality.gate"
84
86
  And no commit body contains "build.health.describe"
85
87
  And no commit body contains "build.quality.criteria-coverage"
86
- And ".gtd/REVIEW.md" contains:
88
+ And ".gtd/QUALITY.md" contains:
87
89
  """
88
- ## sum has no negative test
90
+ ## sum should be named plus
89
91
 
90
92
  _From lens correctness._
91
93
 
92
- _The fixer left this unresolved._
94
+ The glossary says plus.
95
+
96
+ - [ ] fix
97
+
98
+ ## sum has no negative test
99
+
100
+ _From lens correctness. The fixer left it unresolved._
101
+
102
+ Add a test summing negative numbers.
103
+
104
+ - [ ] fix
93
105
  """
94
- And ".gtd/REVIEW.md" contains:
106
+ Given a file ".gtd/QUALITY.md" with:
95
107
  """
96
- ## sum should be named plus
108
+ # Quality
97
109
 
98
- _From lens correctness._
110
+ ## sum should be named plus
99
111
 
100
112
  The glossary says plus.
113
+
114
+ - [x] fix
115
+
116
+ ## sum has no negative test
117
+
118
+ Add a test summing negative numbers.
119
+
120
+ - [ ] fix
121
+ """
122
+ And step "build.fix.quality.fixing" is no longer scripted
123
+ And step "build.fix.quality.fixing" writes "src/calc.ts" with:
124
+ """
125
+ export const plus = (a: number, b: number) => a + b
126
+ """
127
+ And step "build.fix.quality.fixing" deletes ".gtd/QUALITY.md"
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
132
+ And ".gtd/REVIEW.md" contains:
101
133
  """
134
+ Fixed at the finding gate:
135
+
136
+ - sum should be named plus (
137
+ """
138
+ And ".gtd/REVIEW.md" contains:
139
+ """
140
+ Dropped at the finding gate:
141
+
142
+ - sum has no negative test (lens correctness)
143
+ """
144
+ And ".gtd/REVIEW.md" does not contain "Tick exactly one:"
102
145
  And the commit subjects end with:
103
146
  """
104
- gtd(agent): build.quality.correctness.reviewing → build.quality.triage
105
- gtd(judge): build.quality.triage → build.quality.sorting
106
- gtd(check): build.quality.sorting → build.fix.quality.fixing
107
- gtd(agent): build.fix.quality.fixing
108
- gtd(agent): build.fix.quality.fixing
147
+ gtd(human): build.quality.gate → build.quality.picking
148
+ gtd(check): build.quality.picking → build.fix.quality.fixing
109
149
  gtd(agent): build.fix.quality.fixing → build.health.check
110
- gtd(check): build.health.check → build.quality.closing
111
- gtd(check): build.quality.closing → build.review.reviewing
150
+ gtd(check): build.health.check → build.review.reviewing
112
151
  gtd(agent): build.review.reviewing → build.review.carrying
113
152
  gtd(check): build.review.carrying → build.review.await-review
114
153
  """
@@ -123,11 +162,51 @@ Feature: fix's quality lap is triaged, and its leftovers go to the hand-off revi
123
162
  it("sums negative numbers", () => {})
124
163
  """
125
164
  And step "build.fix.quality.fixing" deletes ".gtd/QUALITY.md"
165
+ And step "build.quality.gate" changes nothing
126
166
  When gtd opens door "fix"
127
167
  And the process is driven
128
168
  Then the process rests at "build.review.await-review"
129
- And no commit body contains "build.quality.closing"
130
- And ".gtd/REVIEW.md" contains "## Fixed automatically"
169
+ And ".gtd/REVIEW.md" contains "Fixed automatically:"
131
170
  And ".gtd/REVIEW.md" contains "- sum has no negative test ("
132
171
  And ".gtd/REVIEW.md" contains the short hash of the commit "gtd(agent): build.fix.quality.fixing → build.health.check"
133
172
  And ".gtd/REVIEW.md" contains "- sum should be named plus (p=0.9, lens correctness)"
173
+
174
+ Scenario: a risk the hand-off reviewer marks is fixed and re-reviewed in its own draft, the summary added once
175
+ Given judge step "build.quality.triage" answers:
176
+ """
177
+ [{"id":"Q1","answer":"mechanical","p":0.9},{"id":"Q2","answer":"noise","p":0.9}]
178
+ """
179
+ And step "build.fix.quality.fixing" deletes ".gtd/QUALITY.md"
180
+ And step "build.quality.gate" changes nothing
181
+ And step "build.review.reviewing" is no longer scripted
182
+ And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
183
+ """
184
+ # Review: abc1234
185
+
186
+ <!-- base: 0000000 -->
187
+
188
+ ## calc
189
+
190
+ - [ ] ./src/calc.ts#1-1 — Risk: overflows on large numbers
191
+ """
192
+ When gtd opens door "fix"
193
+ And the process is driven
194
+ Then the process rests at "build.review.fix.risks.fixing"
195
+ And ".gtd/REVIEW.md" does not contain "## Quality lap"
196
+ Given step "build.review.reviewing" is no longer scripted
197
+ And step "build.review.reviewing" replaces the text "Risk: overflows on large numbers" in ".gtd/REVIEW.md" with "sum, now guarded"
198
+ And step "build.review.fix.risks.fixing" changes nothing
199
+ When the process is driven
200
+ Then the process rests at "build.review.await-review"
201
+ And ".gtd/REVIEW.md" contains "sum, now guarded"
202
+ And ".gtd/REVIEW.md" contains "## Quality lap" exactly once
203
+ And ".gtd/REVIEW.md" contains "## calc" exactly once
204
+ And the commit subjects end with:
205
+ """
206
+ gtd(check): build.quality.closing → build.review.reviewing
207
+ gtd(agent): build.review.reviewing → build.review.fix.risks.fixing
208
+ gtd(agent): build.review.fix.risks.fixing → build.health.check
209
+ gtd(check): build.health.check → build.review.reviewing
210
+ gtd(agent): build.review.reviewing → build.review.carrying
211
+ gtd(check): build.review.carrying → build.review.await-review
212
+ """