@pmelab/gtd 58.2.0 → 59.0.1

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 (150) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +120 -395
  3. package/dist/chunks/{Schema-B3o6eRNU.mjs → testkit-07Z_ENch.mjs} +13503 -3460
  4. package/dist/chunks/{wire-C12dahrH.mjs → wire-BTUhRGXj.mjs} +1 -1
  5. package/dist/flows.mjs +1 -1
  6. package/dist/gtd.bundle.mjs +484 -497
  7. package/dist/testkit/gherkin.mjs +145 -65
  8. package/dist/testkit.mjs +1 -1
  9. package/dist/wire.mjs +1 -1
  10. package/package.json +3 -42
  11. package/skills/authoring/SKILL.md +34 -27
  12. package/src/cli/Cli.test.ts +148 -71
  13. package/src/cli/Cli.ts +384 -463
  14. package/src/cli/Help.test.ts +47 -0
  15. package/src/cli/Help.ts +70 -0
  16. package/src/cli/Program.test.ts +127 -33
  17. package/src/cli/Program.ts +70 -25
  18. package/src/edge/Edge.ts +4 -4
  19. package/src/emit/Emit.test.ts +1 -1
  20. package/src/emit/Emit.ts +1 -1
  21. package/src/flags/index.test.ts +0 -13
  22. package/src/flags/index.ts +1 -3
  23. package/src/flows/factory.ts +3 -1
  24. package/src/gherkin/index.ts +135 -71
  25. package/src/gherkin/messages.test.ts +90 -0
  26. package/src/gherkin/messages.ts +84 -0
  27. package/src/install/Install.test.ts +14 -11
  28. package/src/install/Install.ts +38 -15
  29. package/src/install/index.ts +1 -2
  30. package/src/replay/Replay.test.ts +1 -1
  31. package/src/replay/index.ts +1 -1
  32. package/src/step/planStart.ts +6 -1
  33. package/src/testkit/TestRepo.test.ts +47 -2
  34. package/src/testkit/TestRepo.ts +51 -6
  35. package/src/twins/EmittedScriptRecognizer.ts +5 -8
  36. package/src/twins/FlowScripts.ts +1 -1
  37. package/src/wire/Land.ts +1 -1
  38. package/src/workflow/index.ts +1 -0
  39. package/src/workflow/load.test.ts +138 -113
  40. package/src/workflow/load.ts +7 -7
  41. package/src/workflow/skills.test.ts +5 -5
  42. package/src/workflow/skills.ts +1 -1
  43. package/src/workflow/vars.test.ts +30 -3
  44. package/src/workflow/vars.ts +34 -2
  45. package/src/workflow-kit/index.ts +1 -1
  46. package/dist/chunks/reserved-lMYCaapY.mjs +0 -1990
  47. package/dist/chunks/review-Bfaror38.mjs +0 -427
  48. package/dist/chunks/tail-Bd7L940p.mjs +0 -355
  49. package/dist/chunks/testkit-JDtpNKyi.mjs +0 -10410
  50. package/dist/workflows/cleanup.mjs +0 -36
  51. package/dist/workflows/feature.mjs +0 -1018
  52. package/dist/workflows/fix.mjs +0 -41
  53. package/dist/workflows/review.mjs +0 -45
  54. package/dist/workflows/rollout.mjs +0 -48
  55. package/dist/workflows.mjs +0 -40651
  56. package/src/install/ConfigScaffold.ts +0 -22
  57. package/src/workflows/cleanup/cleanup-path.feature +0 -94
  58. package/src/workflows/cleanup/cleanup.feature +0 -315
  59. package/src/workflows/cleanup/cleanup.test.ts +0 -276
  60. package/src/workflows/cleanup/cleanup.ts +0 -52
  61. package/src/workflows/cleanup/index.ts +0 -6
  62. package/src/workflows/feature/acceptance-criteria-tier.feature +0 -25
  63. package/src/workflows/feature/acceptance-criteria.feature +0 -389
  64. package/src/workflows/feature/criteria-coverage.feature +0 -102
  65. package/src/workflows/feature/criteria.test.ts +0 -147
  66. package/src/workflows/feature/criteria.ts +0 -267
  67. package/src/workflows/feature/fast-path.feature +0 -93
  68. package/src/workflows/feature/feature.test.ts +0 -338
  69. package/src/workflows/feature/feature.ts +0 -156
  70. package/src/workflows/feature/green.ts +0 -19
  71. package/src/workflows/feature/index.ts +0 -18
  72. package/src/workflows/feature/lens-models.feature +0 -69
  73. package/src/workflows/feature/lens-review.feature +0 -566
  74. package/src/workflows/feature/naive-acceptance.feature +0 -147
  75. package/src/workflows/feature/naive-test.feature +0 -263
  76. package/src/workflows/feature/one-step-land.feature +0 -93
  77. package/src/workflows/feature/planning.ts +0 -41
  78. package/src/workflows/feature/refactor-absorbs.feature +0 -131
  79. package/src/workflows/feature/refactor-first.feature +0 -158
  80. package/src/workflows/feature/refactor-lens-models.feature +0 -79
  81. package/src/workflows/feature/refactor-rebuild.feature +0 -273
  82. package/src/workflows/feature/refactor-review.feature +0 -1528
  83. package/src/workflows/feature/refactor.test.ts +0 -1220
  84. package/src/workflows/feature/refactor.ts +0 -368
  85. package/src/workflows/feature/release-flag.feature +0 -167
  86. package/src/workflows/feature/release-flag.test.ts +0 -49
  87. package/src/workflows/feature/release-flag.ts +0 -46
  88. package/src/workflows/feature/review-gate.feature +0 -241
  89. package/src/workflows/feature/reviewer-walkthrough.feature +0 -142
  90. package/src/workflows/feature/risk-tier.feature +0 -351
  91. package/src/workflows/feature/seam-rejection.feature +0 -146
  92. package/src/workflows/feature/seam.feature +0 -297
  93. package/src/workflows/feature/seam.test.ts +0 -527
  94. package/src/workflows/feature/seam.ts +0 -426
  95. package/src/workflows/feature/standards.feature +0 -354
  96. package/src/workflows/feature/steps.test.ts +0 -65
  97. package/src/workflows/feature/steps.ts +0 -45
  98. package/src/workflows/feature/tier-pin.feature +0 -66
  99. package/src/workflows/feature/tier.test.ts +0 -166
  100. package/src/workflows/feature/tier.ts +0 -56
  101. package/src/workflows/fix/fix-lens-origin.feature +0 -114
  102. package/src/workflows/fix/fix-quality.feature +0 -212
  103. package/src/workflows/fix/fix.feature +0 -79
  104. package/src/workflows/fix/fix.test.ts +0 -74
  105. package/src/workflows/fix/fix.ts +0 -52
  106. package/src/workflows/fix/index.ts +0 -6
  107. package/src/workflows/index.ts +0 -47
  108. package/src/workflows/review/index.ts +0 -6
  109. package/src/workflows/review/review-door.feature +0 -199
  110. package/src/workflows/review/review.test.ts +0 -27
  111. package/src/workflows/review/review.ts +0 -60
  112. package/src/workflows/rollout/index.ts +0 -6
  113. package/src/workflows/rollout/rollout.feature +0 -510
  114. package/src/workflows/rollout/rollout.test.ts +0 -263
  115. package/src/workflows/rollout/rollout.ts +0 -82
  116. package/src/workflows/shared/__fixtures__/feature-collecting-prompt.txt +0 -98
  117. package/src/workflows/shared/access.test.ts +0 -62
  118. package/src/workflows/shared/access.ts +0 -24
  119. package/src/workflows/shared/config.fixture.ts +0 -12
  120. package/src/workflows/shared/fences.ts +0 -24
  121. package/src/workflows/shared/health.test.ts +0 -148
  122. package/src/workflows/shared/health.ts +0 -191
  123. package/src/workflows/shared/learn.test.ts +0 -140
  124. package/src/workflows/shared/learn.ts +0 -201
  125. package/src/workflows/shared/lenses.test.ts +0 -39
  126. package/src/workflows/shared/lenses.ts +0 -294
  127. package/src/workflows/shared/options.test.ts +0 -157
  128. package/src/workflows/shared/options.ts +0 -92
  129. package/src/workflows/shared/progress.feature +0 -124
  130. package/src/workflows/shared/prose.ts +0 -263
  131. package/src/workflows/shared/recheck.feature +0 -60
  132. package/src/workflows/shared/registry.test.ts +0 -345
  133. package/src/workflows/shared/registry.ts +0 -183
  134. package/src/workflows/shared/reserved.ts +0 -11
  135. package/src/workflows/shared/review.test.ts +0 -1062
  136. package/src/workflows/shared/review.ts +0 -446
  137. package/src/workflows/shared/skills.test.ts +0 -121
  138. package/src/workflows/shared/skills.ts +0 -49
  139. package/src/workflows/shared/standards.test.ts +0 -90
  140. package/src/workflows/shared/standards.ts +0 -156
  141. package/src/workflows/shared/steps.test.ts +0 -219
  142. package/src/workflows/shared/steps.ts +0 -201
  143. package/src/workflows/shared/tail.test.ts +0 -454
  144. package/src/workflows/shared/tail.ts +0 -264
  145. package/src/workflows/shared/text.fixture.ts +0 -128
  146. package/src/workflows/shared/text.test.ts +0 -1430
  147. package/src/workflows/shared/text.ts +0 -1700
  148. package/src/workflows/shared/threads.test.ts +0 -129
  149. package/src/workflows/shared/vars.ts +0 -47
  150. package/src/workflows/shared/workflows.steps.ts +0 -54
@@ -1,354 +0,0 @@
1
- @inmem
2
- Feature: the review learns standards from the human's answers
3
-
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
- kept in `.gtd/STANDARDS.md` with no further question, and every later agent
7
- turn — lenses and coder alike — is told to follow it. One that contradicts
8
- a standard already kept becomes a note in `.gtd/REVIEW.md` the review cannot
9
- sign off without: keep the new one, keep the old one, or write the merged
10
- wording.
11
-
12
- Background:
13
- Given the shipped workflows, as gtd install scaffolds them
14
- And an environment variable "GTD_QUALITYREVIEWS" set to ""
15
- And a file "src/calc.ts" with:
16
- """
17
- export const add = (a: number, b: number) => a + b
18
- """
19
- And the working tree is committed as "feat: add calculator"
20
- And a file "TODO.md" with:
21
- """
22
- # Add subtract
23
-
24
- subtract(a, b) returns the difference.
25
- """
26
- And step "unwind" changes nothing
27
- And step "start-gate.check" changes nothing
28
- And step "design.triage" writes ".gtd/REQUIREMENTS.md" with:
29
- """
30
- # Requirements
31
-
32
- ## Concerns
33
-
34
- ### Subtract
35
-
36
- - `subtract(a, b)` returns `a - b`.
37
-
38
- ## Impact
39
-
40
- - the greeting module
41
-
42
- ## Acceptance Criteria
43
-
44
- - AC-1: subtract(a, b) returns a - b.
45
- """
46
- And step "design.gate.answer" changes nothing
47
- And step "seam.naive" writes "src/calc.test.ts" with:
48
- """
49
- it("[AC-1] subtracts", () => {})
50
- """
51
- And step "seam.naive" writes "src/calc.ts" with:
52
- """
53
- export const add = (a: number, b: number) => a + b
54
- export const subtract = (a: number, b: number) => a - b
55
- """
56
- And step "seam.check" changes nothing
57
- And step "implement.applying" runs its script
58
- And step "implement.health.check" changes nothing
59
- And step "implement.closing" runs its script
60
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
61
- """
62
- # Review: abc1234
63
-
64
- <!-- base: 0000000 -->
65
-
66
- ## Subtract
67
-
68
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
69
- """
70
- And step "build.review.carrying" runs its script
71
- And step "build.review.closing" runs its script
72
- And step "build.review.standards.recording" runs its script
73
- And step "build.review.standards.raising" runs its script
74
-
75
- Scenario: a won't-fix the judge calls reusable is kept, and the review signs off
76
- Given judge step "build.review.standards.judge" answers:
77
- """
78
- [{"id":"standard-1","answer":"yes","p":0.9}]
79
- """
80
- When the process is driven
81
- And ".gtd/REVIEW.md" gets appended:
82
- """
83
- ## subtract has no class
84
-
85
- Calculators read better as classes.
86
-
87
- Tick exactly one:
88
-
89
- - [ ] fix as suggested
90
- - [ ] won't fix
91
- - [ ] _your answer_
92
- """
93
- And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
94
- And gtd lands
95
- And the process is driven
96
- Then the process rests at "idle"
97
- And ".gtd/STANDARDS.md" contains:
98
- """
99
- - Won't fix: subtract has no class — Calculators read better as classes.
100
- """
101
- And the commit subjects end with:
102
- """
103
- gtd(human): build.review.await-review → build.review.standards.judge
104
- gtd(judge): build.review.standards.judge → build.review.standards.recording
105
- gtd(check): build.review.standards.recording → build.review.closing
106
- gtd(check): build.review.closing → idle
107
- """
108
-
109
- Scenario: the next review lists the standards added
110
- Given judge step "build.review.standards.judge" answers:
111
- """
112
- [{"id":"standard-1","answer":"yes","p":0.9}]
113
- """
114
- And judge step "build.review.triage" answers:
115
- """
116
- [{"id":"answer-1","answer":"nit","p":0.9}]
117
- """
118
- And step "build.review.fix.nits.fixing" writes "src/calc.ts" with:
119
- """
120
- export function add(a: number, b: number) { return a + b }
121
- export function subtract(a: number, b: number) { return a - b }
122
- """
123
- And step "build.health.check" changes nothing
124
- When the process is driven
125
- And ".gtd/REVIEW.md" gets appended:
126
- """
127
- ## subtract has no class
128
-
129
- Calculators read better as classes.
130
-
131
- Tick exactly one:
132
-
133
- - [ ] fix as suggested
134
- - [ ] won't fix
135
- - [ ] _your answer_
136
- """
137
- And the text "- [ ] _your answer_" in ".gtd/REVIEW.md" is replaced with "- [x] Calculators are plain functions."
138
- And gtd lands
139
- And the process is driven
140
- Then the process rests at "build.review.await-review"
141
- And ".gtd/REVIEW.md" contains:
142
- """
143
- ## Standards added
144
-
145
- Learned from your answers and kept in `.gtd/STANDARDS.md`:
146
-
147
- - Calculators are plain functions. (re: subtract has no class)
148
- """
149
-
150
- Scenario: an answer below the threshold is not kept
151
- Given judge step "build.review.standards.judge" answers:
152
- """
153
- [{"id":"standard-1","answer":"yes","p":0.6}]
154
- """
155
- When the process is driven
156
- And ".gtd/REVIEW.md" gets appended:
157
- """
158
- ## subtract has no class
159
-
160
- Calculators read better as classes.
161
-
162
- Tick exactly one:
163
-
164
- - [ ] fix as suggested
165
- - [ ] won't fix
166
- - [ ] _your answer_
167
- """
168
- And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
169
- And gtd lands
170
- And the process is driven
171
- Then the process rests at "idle"
172
- And ".gtd/STANDARDS.md" does not exist
173
-
174
- Scenario: a kept standard reaches the lenses and the coder of a later process
175
- Given a file ".gtd/STANDARDS.md" with:
176
- """
177
- # Standards
178
-
179
- - Won't fix: subtract has no class — Calculators read better as classes.
180
- """
181
- And the working tree is committed as "chore: keep a standard"
182
- And a file "TODO.md" with:
183
- """
184
- # Add subtract
185
-
186
- Please add subtract(a, b).
187
- """
188
- And step "seam.naive" is prompted with "- Won't fix: subtract has no class"
189
- And step "build.quality.correctness.reviewing" is prompted with "- Won't fix: subtract has no class"
190
- When the process is driven
191
- Then the process rests at "build.review.await-review"
192
-
193
- Scenario: a contradicting standard blocks sign-off until the human picks one
194
- Given a file ".gtd/STANDARDS.md" with:
195
- """
196
- # Standards
197
-
198
- - Calculators are classes.
199
- """
200
- And the working tree is committed as "chore: keep a standard"
201
- And a file "TODO.md" with:
202
- """
203
- # Add subtract
204
-
205
- Please add subtract(a, b).
206
- """
207
- And judge step "build.review.standards.judge" answers:
208
- """
209
- [{"id":"standard-1","answer":"yes","p":0.9},{"id":"standard-1.contradicts-1","answer":"yes","p":0.8}]
210
- """
211
- And judge step "build.review.triage" answers:
212
- """
213
- [{"id":"answer-1","answer":"praise","p":0.9}]
214
- """
215
- When the process is driven
216
- And ".gtd/REVIEW.md" gets appended:
217
- """
218
- ## subtract has no class
219
-
220
- Calculators read better as classes.
221
-
222
- Tick exactly one:
223
-
224
- - [ ] fix as suggested
225
- - [ ] won't fix
226
- - [ ] _your answer_
227
- """
228
- And the text "- [ ] _your answer_" in ".gtd/REVIEW.md" is replaced with "- [x] Calculators are plain functions."
229
- And gtd lands
230
- And the process is driven
231
- Then the process rests at "build.review.await-review"
232
- And ".gtd/STANDARDS.md" contains:
233
- """
234
- - Calculators are classes.
235
-
236
- ## Undecided
237
-
238
- - Calculators are plain functions. (re: subtract has no class)
239
- - contradicts: Calculators are classes.
240
- """
241
- And ".gtd/REVIEW.md" contains "## Standard conflict "
242
- And ".gtd/REVIEW.md" contains:
243
- """
244
- New: Calculators are plain functions. (re: subtract has no class)
245
-
246
- Old:
247
-
248
- - Calculators are classes.
249
-
250
- Tick exactly one:
251
-
252
- - [ ] keep the new one (drop the old)
253
- - [ ] keep the old one (discard the new)
254
- - [ ] _your answer_
255
- """
256
- And ".gtd/REVIEW.md" does not contain "## subtract has no class"
257
- And landing is refused with "answer-completeness: 1 note(s) in .gtd/REVIEW.md not answered"
258
- When the text "- [ ] keep the new one (drop the old)" in ".gtd/REVIEW.md" is replaced with "- [x] keep the new one (drop the old)"
259
- And gtd lands
260
- And the process is driven
261
- Then the process rests at "idle"
262
- And ".gtd/STANDARDS.md" contains "- Calculators are plain functions. (re: subtract has no class)"
263
- And ".gtd/STANDARDS.md" does not contain "Calculators are classes."
264
- And ".gtd/STANDARDS.md" does not contain "Undecided"
265
-
266
- Scenario: keeping the old standard discards the new one
267
- Given a file ".gtd/STANDARDS.md" with:
268
- """
269
- # Standards
270
-
271
- - Calculators are classes.
272
- """
273
- And the working tree is committed as "chore: keep a standard"
274
- And a file "TODO.md" with:
275
- """
276
- # Add subtract
277
-
278
- Please add subtract(a, b).
279
- """
280
- And judge step "build.review.standards.judge" answers:
281
- """
282
- [{"id":"standard-1","answer":"yes","p":0.9},{"id":"standard-1.contradicts-1","answer":"yes","p":0.8}]
283
- """
284
- When the process is driven
285
- And ".gtd/REVIEW.md" gets appended:
286
- """
287
- ## subtract has no class
288
-
289
- Calculators read better as classes.
290
-
291
- Tick exactly one:
292
-
293
- - [ ] fix as suggested
294
- - [ ] won't fix
295
- - [ ] _your answer_
296
- """
297
- And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
298
- And gtd lands
299
- And the process is driven
300
- And the text "- [ ] keep the old one (discard the new)" in ".gtd/REVIEW.md" is replaced with "- [x] keep the old one (discard the new)"
301
- And gtd lands
302
- And the process is driven
303
- Then the process rests at "idle"
304
- And ".gtd/STANDARDS.md" contains:
305
- """
306
- # Standards
307
-
308
- Kept from your review answers for every agent turn. One standard per bullet.
309
-
310
- - Calculators are classes.
311
- """
312
- And ".gtd/STANDARDS.md" does not contain "Won't fix"
313
-
314
- Scenario: an own answer to a conflict replaces both with its wording
315
- Given a file ".gtd/STANDARDS.md" with:
316
- """
317
- # Standards
318
-
319
- - Calculators are classes.
320
- """
321
- And the working tree is committed as "chore: keep a standard"
322
- And a file "TODO.md" with:
323
- """
324
- # Add subtract
325
-
326
- Please add subtract(a, b).
327
- """
328
- And judge step "build.review.standards.judge" answers:
329
- """
330
- [{"id":"standard-1","answer":"yes","p":0.9},{"id":"standard-1.contradicts-1","answer":"yes","p":0.8}]
331
- """
332
- When the process is driven
333
- And ".gtd/REVIEW.md" gets appended:
334
- """
335
- ## subtract has no class
336
-
337
- Calculators read better as classes.
338
-
339
- Tick exactly one:
340
-
341
- - [ ] fix as suggested
342
- - [ ] won't fix
343
- - [ ] _your answer_
344
- """
345
- And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
346
- And gtd lands
347
- And the process is driven
348
- And the text "- [ ] _your answer_" in ".gtd/REVIEW.md" is replaced with "- [x] Calculators with state are classes."
349
- And gtd lands
350
- And the process is driven
351
- Then the process rests at "idle"
352
- And ".gtd/STANDARDS.md" contains "- Calculators with state are classes."
353
- And ".gtd/STANDARDS.md" does not contain "- Calculators are classes."
354
- And ".gtd/STANDARDS.md" does not contain "Won't fix"
@@ -1,65 +0,0 @@
1
- import { readFileSync } from "node:fs"
2
- import { describe, expect, it } from "vitest"
3
- import type { StepRequest } from "../../flows/index.js"
4
- import { captureStep } from "../shared/text.fixture.js"
5
- import * as steps from "./steps.js"
6
-
7
- const capture = (
8
- fn: () => Promise<void>,
9
- scope: string,
10
- skills?: Readonly<Record<string, readonly string[]>>,
11
- ): Promise<StepRequest> => captureStep(fn, { scope, ...(skills !== undefined ? { skills } : {}) })
12
-
13
- const agentPrompt = (request: StepRequest): string => {
14
- if (request.kind !== "agent") throw new Error(`expected an agent step, got ${request.kind}`)
15
- return request.prompt
16
- }
17
-
18
- describe("the feature workflow's own steps declare skills — a step's rendered prompt carries its bundled skills.ts preamble", () => {
19
- it("triage carries design.triage's bundled skills", async () => {
20
- const prompt = agentPrompt(await capture(() => steps.triage("base"), "design"))
21
- expect(prompt).toContain("spec-driven-development, planning-and-task-breakdown")
22
- })
23
-
24
- it("collecting carries build.review.collecting's bundled skills", async () => {
25
- const prompt = agentPrompt(await capture(() => steps.collecting("capture"), "build"))
26
- expect(prompt).toContain("code-review-and-quality")
27
- })
28
-
29
- it("collecting's prompt is the pinned feature fixture", async () => {
30
- const prompt = agentPrompt(await capture(() => steps.collecting("capture-text"), "build"))
31
- expect(prompt).toContain(
32
- readFileSync(
33
- new URL("../shared/__fixtures__/feature-collecting-prompt.txt", import.meta.url),
34
- "utf8",
35
- ),
36
- )
37
- })
38
-
39
- it("refactorCollecting renders the open variant for the reply round, the closed one otherwise, whatever .gtd/REVIEW.md holds", async () => {
40
- const at = (round: "reply" | "edits", present: boolean): Promise<StepRequest> =>
41
- captureStep(() => steps.refactorCollecting("capture", round, ["src/a.ts"]), {
42
- scope: "refactor.build",
43
- read: (path) => (present && path === ".gtd/REVIEW.md" ? "# Review" : undefined),
44
- })
45
- const open = agentPrompt(await at("reply", false))
46
- const closed = agentPrompt(await at("edits", true))
47
- expect(open).toContain("exactly one `- A:` reply")
48
- expect(open).not.toContain("already closed")
49
- expect(closed).toContain("already closed")
50
- expect(closed).not.toContain("exactly one `- A:` reply")
51
- })
52
- })
53
-
54
- describe("the feature workflow's planning steps run on the planner model", () => {
55
- it("design triage defaults to smart and follows plannerModel", async () => {
56
- const plain = await captureStep(() => steps.triage("base"), { scope: "design" })
57
- const set = await captureStep(() => steps.triage("base"), {
58
- scope: "design",
59
- env: { plannerModel: "opus" },
60
- })
61
- if (plain.kind !== "agent" || set.kind !== "agent") throw new Error("unreachable")
62
- expect(plain.options.model).toBe("smart")
63
- expect(set.options.model).toBe("opus")
64
- })
65
- })
@@ -1,45 +0,0 @@
1
- import { human } from "../../flows/index.js"
2
- import type { CollectRound } from "../../workflow-kit/index.js"
3
- import * as t from "../shared/text.js"
4
- import { riskTierOn } from "./tier.js"
5
- import { planner, REFACTOR, REQUIREMENTS } from "../shared/steps.js"
6
-
7
- // Kept on the published feature entry.
8
- export { answerReviewQuestions, collecting, fixNits } from "../shared/steps.js"
9
-
10
- /** Turn the sketch since `base` into `.gtd/REQUIREMENTS.md`. */
11
- export const triage = (base: string): Promise<void> =>
12
- t.agentWithSkills("triage", t.designTriagePrompt(base, riskTierOn()), {
13
- label: "Triaging the change",
14
- file: REQUIREMENTS,
15
- mode: "qa",
16
- model: planner(),
17
- system: t.designSystem(),
18
- })
19
-
20
- export const answerProductQuestions = (): Promise<void> =>
21
- human("gate.answer", {
22
- message: t.designGateAnswerMessage(riskTierOn()),
23
- label: "Awaiting your product answers",
24
- file: REQUIREMENTS,
25
- mode: "qa",
26
- acceptClean: true,
27
- })
28
-
29
- /** Turn the refactor review round `capture` describes into `.gtd/REFACTOR.md`, or change nothing. */
30
- export const refactorCollecting = (
31
- capture: string,
32
- round: CollectRound,
33
- strays: readonly string[],
34
- ): Promise<void> =>
35
- t.agentWithSkills(
36
- "review.collecting",
37
- t.buildReviewCollectingPrompt(capture, { strays, round }),
38
- {
39
- label: "Collecting your refactor feedback",
40
- file: REFACTOR,
41
- model: planner(),
42
- system: t.reviewerSystem(),
43
- allowEmpty: true,
44
- },
45
- )
@@ -1,66 +0,0 @@
1
- @inmem
2
- Feature: a process keeps the risk tier setting it started with when GTD_FLAG_RISK_TIER changes
3
-
4
- The flag is recorded in the opening commit, so flipping it mid-process never
5
- changes whether the process asks for and records a risk tier.
6
-
7
- Background:
8
- Given the shipped workflows, as gtd install scaffolds them
9
- And an environment variable "GTD_QUALITYREVIEWS" set to ""
10
- And a file "src/calc.ts" with:
11
- """
12
- export const add = (a: number, b: number) => a + b
13
- """
14
- And the working tree is committed as "feat: add calculator"
15
- And a file "TODO.md" with:
16
- """
17
- # Add subtract
18
-
19
- subtract(a, b) returns the difference.
20
- """
21
- And step "unwind" changes nothing
22
- And step "start-gate.check" changes nothing
23
- And step "design.triage" writes ".gtd/REQUIREMENTS.md" with:
24
- """
25
- # Requirements
26
-
27
- ## Concerns
28
-
29
- ### Subtract
30
-
31
- - `subtract(a, b)` returns `a - b`.
32
-
33
- ## Risk Tier
34
-
35
- low — a new pure function
36
-
37
- ## Impact
38
-
39
- - the greeting module
40
-
41
- ## Acceptance Criteria
42
-
43
- - AC-1: the change behaves as described.
44
- """
45
-
46
- Scenario: a process started with the flag off records no tier after the flag turns on
47
- Given the ambient environment variable "GTD_FLAG_RISK_TIER" is "0"
48
- When the process is driven
49
- Then the process rests at "design.gate.answer"
50
- Given the ambient environment variable "GTD_FLAG_RISK_TIER" is "1"
51
- And step "design.gate.answer" changes nothing
52
- When the process is driven
53
- Then the process rests at "seam.naive"
54
- And the commit "gtd(human): idle → unwind" has a body containing "Gtd-Var: flag_risk_tier=0"
55
- And no commit body contains "Gtd-Mark:"
56
-
57
- Scenario: a process started with the flag on records its tier after the flag turns off
58
- Given the ambient environment variable "GTD_FLAG_RISK_TIER" is "1"
59
- When the process is driven
60
- Then the process rests at "design.gate.answer"
61
- Given the ambient environment variable "GTD_FLAG_RISK_TIER" is "0"
62
- And step "design.gate.answer" changes nothing
63
- When the process is driven
64
- Then the process rests at "seam.naive"
65
- And the commit "gtd(human): idle → unwind" has a body containing "Gtd-Var: flag_risk_tier=1"
66
- And the last commit body contains "Gtd-Mark: risk-tier=low"