@pmelab/gtd 49.0.0 → 51.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 (60) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +16 -3
  3. package/dist/chunks/{reserved-CYZ1bSBy.mjs → reserved-CUkk9XgL.mjs} +151 -5
  4. package/dist/chunks/{review-BewyJflS.mjs → review-BaCXlIT2.mjs} +84 -20
  5. package/dist/chunks/{steering-BXwjmocB.mjs → steering-DtUVUz9l.mjs} +44 -14
  6. package/dist/chunks/{tail-C1Oi2YEy.mjs → tail-CX6Pdsql.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 +144 -11
  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 +415 -42
  18. package/package.json +1 -1
  19. package/src/steering/index.ts +1 -0
  20. package/src/steering/review.test.ts +60 -2
  21. package/src/steering/review.ts +66 -9
  22. package/src/workflows/feature/coverage.feature +1 -0
  23. package/src/workflows/feature/fast-path.feature +1 -0
  24. package/src/workflows/feature/feature.ts +4 -1
  25. package/src/workflows/feature/flag-mode.feature +1 -1
  26. package/src/workflows/feature/lens-models.feature +1 -0
  27. package/src/workflows/feature/lens-review.feature +17 -4
  28. package/src/workflows/feature/one-step-land.feature +1 -0
  29. package/src/workflows/feature/prototype-rounds.feature +152 -0
  30. package/src/workflows/feature/prototype.feature +419 -0
  31. package/src/workflows/feature/prototype.test.ts +43 -0
  32. package/src/workflows/feature/prototype.ts +181 -0
  33. package/src/workflows/feature/refactor-absorbs.feature +9 -1
  34. package/src/workflows/feature/refactor-first.feature +13 -3
  35. package/src/workflows/feature/refactor-rebuild.feature +29 -5
  36. package/src/workflows/feature/refactor-review.feature +111 -13
  37. package/src/workflows/feature/refactor.test.ts +14 -4
  38. package/src/workflows/feature/refactor.ts +2 -0
  39. package/src/workflows/feature/review-answers.feature +9 -1
  40. package/src/workflows/feature/review-gate.feature +21 -3
  41. package/src/workflows/feature/reviewer-walkthrough.feature +15 -3
  42. package/src/workflows/feature/seam-rejection.feature +1 -0
  43. package/src/workflows/feature/seam.feature +1 -0
  44. package/src/workflows/feature/seam.test.ts +3 -2
  45. package/src/workflows/feature/seam.ts +19 -5
  46. package/src/workflows/feature/severity-budget.feature +112 -0
  47. package/src/workflows/feature/severity-sorted-review.feature +198 -0
  48. package/src/workflows/feature/slice-findings.feature +15 -2
  49. package/src/workflows/feature/slicing-cap.feature +9 -0
  50. package/src/workflows/feature/slicing.feature +1 -0
  51. package/src/workflows/feature/standards.feature +5 -0
  52. package/src/workflows/shared/options.ts +1 -0
  53. package/src/workflows/shared/prose.ts +6 -0
  54. package/src/workflows/shared/review.ts +124 -18
  55. package/src/workflows/shared/skills.test.ts +4 -0
  56. package/src/workflows/shared/skills.ts +5 -0
  57. package/src/workflows/shared/steps.ts +1 -0
  58. package/src/workflows/shared/text.test.ts +90 -0
  59. package/src/workflows/shared/text.ts +181 -4
  60. package/src/workflows/shared/vars.ts +3 -0
@@ -11,6 +11,7 @@ Feature: a reviewer walks the human through the feature's code
11
11
 
12
12
  Background:
13
13
  Given the shipped workflows, as gtd install scaffolds them
14
+ And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
14
15
  And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
15
16
  And an environment variable "GTD_FLAGMODE" set to "false"
16
17
  And a file "src/calc.ts" with:
@@ -67,6 +68,10 @@ Feature: a reviewer walks the human through the feature's code
67
68
  And step "build.quality.sorting" runs its script
68
69
  And step "build.quality.closing" runs its script
69
70
  And step "build.review.carrying" runs its script
71
+ And judge step "build.review.ranking" answers:
72
+ """
73
+ []
74
+ """
70
75
 
71
76
  Scenario: the finding gets its text and answer boxes under the reviewer's pointers
72
77
  Given step "build.review.reviewing" is prompted with "- `## AC-1 ignores floating point`:"
@@ -93,12 +98,16 @@ Feature: a reviewer walks the human through the feature's code
93
98
  """
94
99
  ## Subtract
95
100
 
101
+ _critical: judge unsure_
102
+
96
103
  The new export.
97
104
 
98
105
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
99
106
 
100
107
  ## AC-1 ignores floating point
101
108
 
109
+ _critical: judge unsure_
110
+
102
111
  Should subtract round? The criterion does not say.
103
112
 
104
113
  In the code:
@@ -114,7 +123,8 @@ Feature: a reviewer walks the human through the feature's code
114
123
  And no commit body contains "build.review.composing"
115
124
  And the commit subjects end with:
116
125
  """
117
- gtd(agent): build.review.reviewing → build.review.carrying
126
+ gtd(agent): build.review.reviewing → build.review.ranking
127
+ gtd(judge): build.review.ranking → build.review.carrying
118
128
  gtd(check): build.review.carrying → build.review.await-review
119
129
  """
120
130
 
@@ -169,11 +179,13 @@ Feature: a reviewer walks the human through the feature's code
169
179
  Then the process rests at "build.review.await-review"
170
180
  And the commit subjects end with:
171
181
  """
172
- gtd(agent): build.review.reviewing → build.review.carrying
182
+ gtd(agent): build.review.reviewing → build.review.ranking
183
+ gtd(judge): build.review.ranking → build.review.carrying
173
184
  gtd(check): build.review.carrying → build.review.fix.risks.fixing
174
185
  gtd(agent): build.review.fix.risks.fixing → build.health.check
175
186
  gtd(check): build.health.check → build.review.reviewing
176
- gtd(agent): build.review.reviewing → build.review.carrying
187
+ gtd(agent): build.review.reviewing → build.review.ranking
188
+ gtd(judge): build.review.ranking → build.review.carrying
177
189
  gtd(check): build.review.carrying → build.review.await-review
178
190
  """
179
191
 
@@ -9,6 +9,7 @@ Feature: rejected naive passes walk one fixed path through the steer gate to the
9
9
 
10
10
  Background:
11
11
  Given the shipped workflows, as gtd install scaffolds them
12
+ And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
12
13
  And an environment variable "GTD_QUALITYREVIEWS" set to ""
13
14
  And an environment variable "GTD_FLAG_RISK_TIER" set to "0"
14
15
  And a file "src/calc.ts" with:
@@ -7,6 +7,7 @@ Feature: the naive pass and seam judge decide how a feature is built
7
7
 
8
8
  Background:
9
9
  Given the shipped workflows, as gtd install scaffolds them
10
+ And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
10
11
  And the gtd config ends with:
11
12
  """
12
13
  export const config = {
@@ -335,7 +335,7 @@ const driveSeam = async (
335
335
  note: () => void files.set(NOTE, "Seam: a shared op"),
336
336
  deriving: () => void files.set(REFACTOR, "package"),
337
337
  closing: () => void files.delete(REFACTOR),
338
- "review.composing": () => void files.set(REVIEW, reviewDoc),
338
+ "review.reviewing": () => void files.set(REVIEW, reviewDoc),
339
339
  "review.closing": () => {
340
340
  files.delete(REVIEW)
341
341
  current = "after-refactor"
@@ -500,7 +500,8 @@ describe("implement", () => {
500
500
  lastOptions = undefined
501
501
  installContext(
502
502
  fixtureContext(
503
- {},
503
+ // The hands-on test after coverage has its own scenarios.
504
+ { vars: { prototypeRounds: "0" } },
504
505
  {
505
506
  step: (request: StepRequest) => {
506
507
  requests.push(request)
@@ -26,10 +26,19 @@ import {
26
26
  type KeptTip,
27
27
  } from "../../flows/index.js"
28
28
  import { continuing, phase, type Handoff, type Phase } from "../shared/continuation.js"
29
- import { coder, FEEDBACK, HANDOFF, REFACTOR_NOTE, REQUIREMENTS, SLICES } from "../shared/steps.js"
29
+ import {
30
+ coder,
31
+ FEEDBACK,
32
+ HANDOFF,
33
+ PROTOTYPE,
34
+ REFACTOR_NOTE,
35
+ REQUIREMENTS,
36
+ SLICES,
37
+ } from "../shared/steps.js"
30
38
  import * as t from "../shared/text.js"
31
39
  import { defaults } from "../shared/vars.js"
32
40
  import { green, requireCoverage } from "./coverage.js"
41
+ import { prototypeTest } from "./prototype.js"
33
42
  import {
34
43
  criterionIds,
35
44
  requireCriteria,
@@ -373,10 +382,11 @@ export const implementing = (options: ImplementOptions): Promise<readonly string
373
382
  if (built && acceptance !== undefined)
374
383
  requireAcceptance({ ...acceptance, ids: settled(acceptance.ids, options.slice) }, since)
375
384
  // Fix turns are held to the carried tests too: deleting a red one must not buy a green suite.
376
- await green(
377
- built && acceptance !== undefined ? () => requireAcceptanceKept(acceptance) : undefined,
378
- )
385
+ const keepsTests =
386
+ built && acceptance !== undefined ? () => requireAcceptanceKept(acceptance) : undefined
387
+ await green(keepsTests)
379
388
  await requireCoverage(options.base, options.slice)
389
+ await prototypeTest(options.slice, keepsTests)
380
390
  const ids = criterionIds(read(REQUIREMENTS) ?? "")
381
391
  await closing(moreToBuild(options.more))
382
392
  return ids
@@ -393,7 +403,11 @@ export const closeOut = (): Promise<void> => scope("implement", () => closing(fa
393
403
  const closing = (more: boolean): Promise<void> =>
394
404
  run(
395
405
  "closing",
396
- removeScript(more ? [REFACTOR_NOTE, HANDOFF] : [REQUIREMENTS, REFACTOR_NOTE, SLICES, HANDOFF]),
406
+ removeScript(
407
+ more
408
+ ? [REFACTOR_NOTE, HANDOFF, PROTOTYPE]
409
+ : [REQUIREMENTS, REFACTOR_NOTE, SLICES, HANDOFF, PROTOTYPE],
410
+ ),
397
411
  { label: "Closing out the implementation" },
398
412
  )
399
413
 
@@ -0,0 +1,112 @@
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_PROTOTYPEROUNDS" set to "0"
11
+ And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
12
+ And an environment variable "GTD_FLAGMODE" set to "false"
13
+ And an environment variable "GTD_JUDGEBUDGETBYTES" set to "150"
14
+ And a file "src/calc.ts" with:
15
+ """
16
+ export const add = (a: number, b: number) => a + b
17
+ """
18
+ And the working tree is committed as "feat: add calculator"
19
+ And a file "TODO.md" with:
20
+ """
21
+ # Add subtract
22
+
23
+ subtract(a, b) returns the difference.
24
+ """
25
+ And step "unwind" changes nothing
26
+ And step "start-gate.check" changes nothing
27
+ And step "design.triage" writes ".gtd/REQUIREMENTS.md" with:
28
+ """
29
+ # Requirements
30
+
31
+ ## Acceptance Criteria
32
+
33
+ - AC-1: subtract(a, b) returns a - b.
34
+ """
35
+ And step "design.gate.answer" changes nothing
36
+ And step "seam.naive" writes "src/calc.test.ts" with:
37
+ """
38
+ it("[AC-1] subtracts", () => {})
39
+ """
40
+ And step "seam.naive" writes "src/calc.ts" with:
41
+ """
42
+ export const add = (a: number, b: number) => a + b
43
+ export const subtract = (a: number, b: number) => a - b
44
+ """
45
+ And step "seam.check" changes nothing
46
+ And step "implement.applying" runs its script
47
+ And step "implement.health.check" changes nothing
48
+ And step "implement.closing" runs its script
49
+ And judge step "implement.coverage" answers:
50
+ """
51
+ [{"id":"AC-1","answer":"yes","p":0.9}]
52
+ """
53
+ And step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
54
+ """
55
+ # Quality
56
+
57
+ ## AC-1 ignores floating point
58
+
59
+ Should subtract round? The criterion does not say.
60
+ """
61
+ And judge step "build.quality.triage" answers:
62
+ """
63
+ [{"id":"Q1","answer":"design","p":0.9}]
64
+ """
65
+ And step "build.quality.sorting" runs its script
66
+ And step "build.quality.closing" runs its script
67
+ And step "build.review.carrying" runs its script
68
+
69
+ Scenario: a chunk the budget cuts is listed as critical, the others judged in batches of their own
70
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
71
+ """
72
+ # Review: abc1234
73
+
74
+ <!-- base: 0000000 -->
75
+
76
+ ## Subtract
77
+
78
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
79
+
80
+ ## AC-1 ignores floating point
81
+
82
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
83
+ """
84
+ And judge step "build.review.ranking", when its questions contain "C1.security", answers:
85
+ """
86
+ [{"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}]
87
+ """
88
+ And judge step "build.review.ranking", when its questions contain "C2.security", answers:
89
+ """
90
+ [{"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}]
91
+ """
92
+ When the process is driven
93
+ Then the process rests at "build.review.await-review"
94
+ And ".gtd/REVIEW.md" contains:
95
+ """
96
+ ## AC-1 ignores floating point
97
+
98
+ _critical: judge unsure_
99
+ """
100
+ And ".gtd/REVIEW.md" contains:
101
+ """
102
+ ## Subtract
103
+
104
+ _could_
105
+ """
106
+ And the commit subjects end with:
107
+ """
108
+ gtd(agent): build.review.reviewing → build.review.ranking
109
+ gtd(judge): build.review.ranking
110
+ gtd(judge): build.review.ranking → build.review.carrying
111
+ gtd(check): build.review.carrying → build.review.await-review
112
+ """
@@ -0,0 +1,198 @@
1
+ @inmem
2
+ Feature: the final review lists what matters most first
3
+
4
+ Before the review rests, the judge rates every chunk the reviewer wrote — a
5
+ walkthrough chunk or a carried quality finding — on the same four questions
6
+ as a human's note (`build.review.ranking`): critical (security, or a one-way
7
+ door), should (a contract, or a new concept), could. The review lists them
8
+ in that order, security before one-way doors, each led by its tier and
9
+ reason. A chunk the judge cannot rate is critical, so it is shown first.
10
+
11
+ Background:
12
+ Given the shipped workflows, as gtd install scaffolds them
13
+ And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
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
+
71
+ Scenario: security and one-way doors come first, a carried finding sorted among the rest
72
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
73
+ """
74
+ # Review: abc1234
75
+
76
+ <!-- base: 0000000 -->
77
+
78
+ ## Subtract
79
+
80
+ The new export.
81
+
82
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
83
+
84
+ ## Session token
85
+
86
+ - [ ] ./src/calc.ts#1-1 — reads the caller's token
87
+
88
+ ## AC-1 ignores floating point
89
+
90
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
91
+
92
+ ## Saved format
93
+
94
+ - [ ] ./src/calc.ts#1-2 — what callers persist
95
+ """
96
+ And judge step "build.review.ranking" answers:
97
+ """
98
+ [{"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},{"id":"C2.security","answer":"yes","p":0.9},{"id":"C2.reversibility","answer":"two-way","p":0.9},{"id":"C2.blastRadius","answer":"module","p":0.9},{"id":"C2.newConcept","answer":"no","p":0.9},{"id":"C3.security","answer":"no","p":0.9},{"id":"C3.reversibility","answer":"two-way","p":0.9},{"id":"C3.blastRadius","answer":"contract","p":0.9},{"id":"C3.newConcept","answer":"no","p":0.9},{"id":"C4.security","answer":"no","p":0.9},{"id":"C4.reversibility","answer":"one-way","p":0.9},{"id":"C4.blastRadius","answer":"contract","p":0.9},{"id":"C4.newConcept","answer":"no","p":0.9}]
99
+ """
100
+ When the process is driven
101
+ Then the process rests at "build.review.await-review"
102
+ And ".gtd/REVIEW.md" contains:
103
+ """
104
+ ## Session token
105
+
106
+ _critical: security_
107
+
108
+ - [ ] ./src/calc.ts#1-1 — reads the caller's token
109
+
110
+ ## Saved format
111
+
112
+ _critical: one-way door_
113
+
114
+ - [ ] ./src/calc.ts#1-2 — what callers persist
115
+
116
+ ## AC-1 ignores floating point
117
+
118
+ _should: contract_
119
+
120
+ Should subtract round? The criterion does not say.
121
+ """
122
+ And ".gtd/REVIEW.md" contains:
123
+ """
124
+ - [ ] _your answer_
125
+
126
+ ## Subtract
127
+
128
+ _could_
129
+
130
+ The new export.
131
+ """
132
+ And the commit "gtd(judge): build.review.ranking → build.review.carrying" has a body containing "Gtd-Judge:"
133
+ And the commit subjects end with:
134
+ """
135
+ gtd(agent): build.review.reviewing → build.review.ranking
136
+ gtd(judge): build.review.ranking → build.review.carrying
137
+ gtd(check): build.review.carrying → build.review.await-review
138
+ """
139
+
140
+ Scenario: a chunk the judge is unsure about is listed as critical
141
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
142
+ """
143
+ # Review: abc1234
144
+
145
+ <!-- base: 0000000 -->
146
+
147
+ ## Subtract
148
+
149
+ The new export.
150
+
151
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
152
+
153
+ ## Session token
154
+
155
+ - [ ] ./src/calc.ts#1-1 — reads the caller's token
156
+
157
+ ## AC-1 ignores floating point
158
+
159
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
160
+
161
+ ## Saved format
162
+
163
+ - [ ] ./src/calc.ts#1-2 — what callers persist
164
+ """
165
+ And judge step "build.review.ranking" answers:
166
+ """
167
+ [{"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},{"id":"C2.security","answer":"no","p":0.4},{"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},{"id":"C3.security","answer":"no","p":0.9},{"id":"C3.reversibility","answer":"two-way","p":0.9},{"id":"C3.blastRadius","answer":"contract","p":0.9},{"id":"C3.newConcept","answer":"no","p":0.9},{"id":"C4.security","answer":"no","p":0.9},{"id":"C4.reversibility","answer":"two-way","p":0.9},{"id":"C4.blastRadius","answer":"local","p":0.9},{"id":"C4.newConcept","answer":"yes","p":0.9}]
168
+ """
169
+ When the process is driven
170
+ Then the process rests at "build.review.await-review"
171
+ And ".gtd/REVIEW.md" contains:
172
+ """
173
+ # Review: abc1234
174
+
175
+ <!-- base: 0000000 -->
176
+
177
+ ## Session token
178
+
179
+ _critical: judge unsure_
180
+ """
181
+ And ".gtd/REVIEW.md" contains:
182
+ """
183
+ ## AC-1 ignores floating point
184
+
185
+ _should: contract_
186
+ """
187
+ And ".gtd/REVIEW.md" contains:
188
+ """
189
+ ## Saved format
190
+
191
+ _should: new concept_
192
+ """
193
+ And ".gtd/REVIEW.md" contains:
194
+ """
195
+ ## Subtract
196
+
197
+ _could_
198
+ """
@@ -9,6 +9,7 @@ Feature: every slice's quality lap is triaged, and its leftovers wait for the re
9
9
 
10
10
  Background:
11
11
  Given the shipped workflows, as gtd install scaffolds them
12
+ And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
12
13
  And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
13
14
  And an environment variable "GTD_FLAGMODE" set to "false"
14
15
  And an environment variable "GTD_SLICEMAXCRITERIA" set to "1"
@@ -71,6 +72,10 @@ Feature: every slice's quality lap is triaged, and its leftovers wait for the re
71
72
  And step "build.quality.closing" runs its script
72
73
  And step "build.health.check" changes nothing
73
74
  And step "build.review.carrying" runs its script
75
+ And judge step "build.review.ranking" answers:
76
+ """
77
+ []
78
+ """
74
79
 
75
80
  Scenario: a finding questioning a criterion reaches the final review, never the fixer
76
81
  Given step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
@@ -112,6 +117,8 @@ Feature: every slice's quality lap is triaged, and its leftovers wait for the re
112
117
  """
113
118
  ## AC-1 ignores floating point
114
119
 
120
+ _critical: judge unsure_
121
+
115
122
  _From slice 1, lens correctness._
116
123
 
117
124
  Should subtract round? The criterion does not say.
@@ -120,6 +127,8 @@ Feature: every slice's quality lap is triaged, and its leftovers wait for the re
120
127
  """
121
128
  ## AC-1 ignores floating point (2)
122
129
 
130
+ _critical: judge unsure_
131
+
123
132
  _From slice 2, lens correctness._
124
133
  """
125
134
  And the commit subjects end with:
@@ -137,7 +146,8 @@ Feature: every slice's quality lap is triaged, and its leftovers wait for the re
137
146
  gtd(agent): build.quality.correctness.reviewing → build.quality.triage
138
147
  gtd(judge): build.quality.triage → build.quality.sorting
139
148
  gtd(check): build.quality.sorting → build.review.reviewing
140
- gtd(agent): build.review.reviewing → build.review.carrying
149
+ gtd(agent): build.review.reviewing → build.review.ranking
150
+ gtd(judge): build.review.ranking → build.review.carrying
141
151
  gtd(check): build.review.carrying → build.review.await-review
142
152
  """
143
153
 
@@ -181,6 +191,8 @@ Feature: every slice's quality lap is triaged, and its leftovers wait for the re
181
191
  """
182
192
  ## subtract has no negative test
183
193
 
194
+ _critical: judge unsure_
195
+
184
196
  _From slice 1, lens correctness._
185
197
 
186
198
  _The fixer left this unresolved._
@@ -208,7 +220,8 @@ Feature: every slice's quality lap is triaged, and its leftovers wait for the re
208
220
  gtd(agent): build.fix.quality.fixing → build.health.check
209
221
  gtd(check): build.health.check → build.quality.closing
210
222
  gtd(check): build.quality.closing → build.review.reviewing
211
- gtd(agent): build.review.reviewing → build.review.carrying
223
+ gtd(agent): build.review.reviewing → build.review.ranking
224
+ gtd(judge): build.review.ranking → build.review.carrying
212
225
  gtd(check): build.review.carrying → build.review.await-review
213
226
  """
214
227
 
@@ -12,3 +12,12 @@ Feature: a bad sliceMaxCriteria refuses the landing that would pin it
12
12
  # Something
13
13
  """
14
14
  Then driving the process is refused with "sliceMaxCriteria must be a positive integer, got \"0\""
15
+
16
+ Scenario: a prototypeRounds that is not a whole number refuses the idle landing
17
+ Given the shipped workflows, as gtd install scaffolds them
18
+ And an environment variable "GTD_PROTOTYPEROUNDS" set to "-1"
19
+ And a file "TODO.md" with:
20
+ """
21
+ # Something
22
+ """
23
+ Then driving the process is refused with "prototypeRounds must be a non-negative integer, got \"-1\""
@@ -8,6 +8,7 @@ Feature: a change with more criteria than the cap is built in coarse slices
8
8
 
9
9
  Background:
10
10
  Given the shipped workflows, as gtd install scaffolds them
11
+ And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
11
12
  And an environment variable "GTD_QUALITYREVIEWS" set to ""
12
13
  And an environment variable "GTD_FLAGMODE" set to "false"
13
14
  And an environment variable "GTD_SLICEMAXCRITERIA" set to "2"
@@ -11,6 +11,7 @@ Feature: the review learns standards from the human's answers
11
11
 
12
12
  Background:
13
13
  Given the shipped workflows, as gtd install scaffolds them
14
+ And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
14
15
  And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
15
16
  And an environment variable "GTD_FLAGMODE" set to "false"
16
17
  And a file "src/calc.ts" with:
@@ -92,6 +93,10 @@ Feature: the review learns standards from the human's answers
92
93
  - [ ] ./src/calc.ts#2-2 — a plain function
93
94
  """
94
95
  And step "build.review.carrying" runs its script
96
+ And judge step "build.review.ranking" answers:
97
+ """
98
+ []
99
+ """
95
100
  And judge step "build.quality.triage" answers:
96
101
  """
97
102
  [{"id":"Q1","answer":"design","p":0.9}]
@@ -27,6 +27,7 @@ export const ShippedOptions = Schema.Struct({
27
27
  qualityReviews: setting,
28
28
  refactorQualityReviews: setting,
29
29
  continuations: setting,
30
+ prototypeRounds: setting,
30
31
  continuationStall: setting,
31
32
  testCommand: setting,
32
33
  plannerModel: setting,
@@ -88,6 +88,12 @@ things when redirected — a failing check, or reviewer feedback. Stay
88
88
  strictly inside that task; never touch code outside it. Treat feedback as the
89
89
  diagnosis to act on; discard it, with reason, only when simply wrong.`
90
90
 
91
+ export const testerPersona = `You are the hands-on tester in gtd's build pipeline: use what was just
92
+ built the way a person would — run the real program, open the real
93
+ page, call the real endpoint — and report exactly what you did and
94
+ what you saw. Never fix anything yourself, and never pass a criterion
95
+ you did not watch hold.`
96
+
91
97
  export const finisherPersona = `You are the closing identity in gtd's build pipeline — the last coder
92
98
  before it closes. Fix a late-breaking failing check after sign-off,
93
99
  focused and minimal. Every turn lands its own commit — nothing here