@pmelab/gtd 58.1.0 → 59.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 (142) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +115 -390
  3. package/dist/chunks/{Schema-B3o6eRNU.mjs → testkit-CMBAAyRK.mjs} +13409 -3351
  4. package/dist/gtd.bundle.mjs +76 -59
  5. package/dist/testkit/gherkin.mjs +30 -2
  6. package/dist/testkit.mjs +1 -1
  7. package/package.json +3 -42
  8. package/skills/authoring/SKILL.md +31 -25
  9. package/src/cli/Cli.test.ts +15 -19
  10. package/src/cli/Cli.ts +2 -4
  11. package/src/cli/Program.test.ts +60 -29
  12. package/src/cli/Program.ts +5 -7
  13. package/src/edge/Edge.ts +3 -3
  14. package/src/flags/index.test.ts +0 -13
  15. package/src/flags/index.ts +1 -3
  16. package/src/gherkin/git-control.feature +78 -0
  17. package/src/gherkin/index.ts +35 -1
  18. package/src/install/Install.test.ts +14 -11
  19. package/src/install/Install.ts +38 -15
  20. package/src/install/index.ts +1 -2
  21. package/src/replay/Replay.test.ts +1 -1
  22. package/src/replay/index.ts +1 -1
  23. package/src/step/planStart.ts +6 -1
  24. package/src/testkit/TestRepo.test.ts +118 -2
  25. package/src/testkit/TestRepo.ts +57 -6
  26. package/src/testkit/index.ts +1 -0
  27. package/src/twins/EmittedScriptRecognizer.ts +12 -14
  28. package/src/twins/FlowScripts.ts +10 -9
  29. package/src/twins/InMemRepo.ts +26 -1
  30. package/src/twins/Layers.ts +12 -1
  31. package/src/twins/index.ts +6 -1
  32. package/src/workflow/index.ts +1 -0
  33. package/src/workflow/load.test.ts +138 -113
  34. package/src/workflow/load.ts +1 -1
  35. package/src/workflow/vars.test.ts +30 -3
  36. package/src/workflow/vars.ts +34 -2
  37. package/src/workflow-kit/index.ts +1 -1
  38. package/dist/chunks/reserved-lMYCaapY.mjs +0 -1990
  39. package/dist/chunks/review-Bfaror38.mjs +0 -427
  40. package/dist/chunks/tail-Bd7L940p.mjs +0 -355
  41. package/dist/chunks/testkit-D1-auYau.mjs +0 -10362
  42. package/dist/workflows/cleanup.mjs +0 -36
  43. package/dist/workflows/feature.mjs +0 -1018
  44. package/dist/workflows/fix.mjs +0 -41
  45. package/dist/workflows/review.mjs +0 -45
  46. package/dist/workflows/rollout.mjs +0 -48
  47. package/dist/workflows.mjs +0 -40651
  48. package/src/install/ConfigScaffold.ts +0 -22
  49. package/src/workflows/cleanup/cleanup-path.feature +0 -94
  50. package/src/workflows/cleanup/cleanup.feature +0 -315
  51. package/src/workflows/cleanup/cleanup.test.ts +0 -276
  52. package/src/workflows/cleanup/cleanup.ts +0 -52
  53. package/src/workflows/cleanup/index.ts +0 -6
  54. package/src/workflows/feature/acceptance-criteria-tier.feature +0 -25
  55. package/src/workflows/feature/acceptance-criteria.feature +0 -389
  56. package/src/workflows/feature/criteria-coverage.feature +0 -102
  57. package/src/workflows/feature/criteria.test.ts +0 -147
  58. package/src/workflows/feature/criteria.ts +0 -267
  59. package/src/workflows/feature/fast-path.feature +0 -93
  60. package/src/workflows/feature/feature.test.ts +0 -338
  61. package/src/workflows/feature/feature.ts +0 -156
  62. package/src/workflows/feature/green.ts +0 -19
  63. package/src/workflows/feature/index.ts +0 -18
  64. package/src/workflows/feature/lens-models.feature +0 -69
  65. package/src/workflows/feature/lens-review.feature +0 -566
  66. package/src/workflows/feature/naive-acceptance.feature +0 -147
  67. package/src/workflows/feature/naive-test.feature +0 -263
  68. package/src/workflows/feature/one-step-land.feature +0 -93
  69. package/src/workflows/feature/planning.ts +0 -41
  70. package/src/workflows/feature/refactor-absorbs.feature +0 -131
  71. package/src/workflows/feature/refactor-first.feature +0 -158
  72. package/src/workflows/feature/refactor-lens-models.feature +0 -79
  73. package/src/workflows/feature/refactor-rebuild.feature +0 -273
  74. package/src/workflows/feature/refactor-review.feature +0 -1528
  75. package/src/workflows/feature/refactor.test.ts +0 -1220
  76. package/src/workflows/feature/refactor.ts +0 -368
  77. package/src/workflows/feature/release-flag.feature +0 -167
  78. package/src/workflows/feature/release-flag.test.ts +0 -49
  79. package/src/workflows/feature/release-flag.ts +0 -46
  80. package/src/workflows/feature/review-gate.feature +0 -241
  81. package/src/workflows/feature/reviewer-walkthrough.feature +0 -142
  82. package/src/workflows/feature/risk-tier.feature +0 -351
  83. package/src/workflows/feature/seam-rejection.feature +0 -146
  84. package/src/workflows/feature/seam.feature +0 -297
  85. package/src/workflows/feature/seam.test.ts +0 -527
  86. package/src/workflows/feature/seam.ts +0 -426
  87. package/src/workflows/feature/standards.feature +0 -354
  88. package/src/workflows/feature/steps.test.ts +0 -65
  89. package/src/workflows/feature/steps.ts +0 -45
  90. package/src/workflows/feature/tier-pin.feature +0 -66
  91. package/src/workflows/feature/tier.test.ts +0 -166
  92. package/src/workflows/feature/tier.ts +0 -56
  93. package/src/workflows/fix/fix-lens-origin.feature +0 -114
  94. package/src/workflows/fix/fix-quality.feature +0 -212
  95. package/src/workflows/fix/fix.feature +0 -79
  96. package/src/workflows/fix/fix.test.ts +0 -74
  97. package/src/workflows/fix/fix.ts +0 -52
  98. package/src/workflows/fix/index.ts +0 -6
  99. package/src/workflows/index.ts +0 -47
  100. package/src/workflows/review/index.ts +0 -6
  101. package/src/workflows/review/review-door.feature +0 -199
  102. package/src/workflows/review/review.test.ts +0 -27
  103. package/src/workflows/review/review.ts +0 -60
  104. package/src/workflows/rollout/index.ts +0 -6
  105. package/src/workflows/rollout/rollout.feature +0 -510
  106. package/src/workflows/rollout/rollout.test.ts +0 -263
  107. package/src/workflows/rollout/rollout.ts +0 -82
  108. package/src/workflows/shared/__fixtures__/feature-collecting-prompt.txt +0 -98
  109. package/src/workflows/shared/access.test.ts +0 -62
  110. package/src/workflows/shared/access.ts +0 -24
  111. package/src/workflows/shared/config.fixture.ts +0 -12
  112. package/src/workflows/shared/fences.ts +0 -24
  113. package/src/workflows/shared/health.test.ts +0 -148
  114. package/src/workflows/shared/health.ts +0 -191
  115. package/src/workflows/shared/learn.test.ts +0 -140
  116. package/src/workflows/shared/learn.ts +0 -201
  117. package/src/workflows/shared/lenses.test.ts +0 -39
  118. package/src/workflows/shared/lenses.ts +0 -294
  119. package/src/workflows/shared/options.test.ts +0 -157
  120. package/src/workflows/shared/options.ts +0 -92
  121. package/src/workflows/shared/progress.feature +0 -124
  122. package/src/workflows/shared/prose.ts +0 -263
  123. package/src/workflows/shared/recheck.feature +0 -60
  124. package/src/workflows/shared/registry.test.ts +0 -345
  125. package/src/workflows/shared/registry.ts +0 -183
  126. package/src/workflows/shared/reserved.ts +0 -11
  127. package/src/workflows/shared/review.test.ts +0 -1062
  128. package/src/workflows/shared/review.ts +0 -446
  129. package/src/workflows/shared/skills.test.ts +0 -121
  130. package/src/workflows/shared/skills.ts +0 -49
  131. package/src/workflows/shared/standards.test.ts +0 -90
  132. package/src/workflows/shared/standards.ts +0 -156
  133. package/src/workflows/shared/steps.test.ts +0 -219
  134. package/src/workflows/shared/steps.ts +0 -201
  135. package/src/workflows/shared/tail.test.ts +0 -454
  136. package/src/workflows/shared/tail.ts +0 -264
  137. package/src/workflows/shared/text.fixture.ts +0 -128
  138. package/src/workflows/shared/text.test.ts +0 -1430
  139. package/src/workflows/shared/text.ts +0 -1700
  140. package/src/workflows/shared/threads.test.ts +0 -129
  141. package/src/workflows/shared/vars.ts +0 -47
  142. 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"