@pmelab/gtd 55.0.0 → 57.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +72 -80
  3. package/dist/chunks/{reserved-DHafcW7t.mjs → reserved-X2RkNHin.mjs} +110 -318
  4. package/dist/chunks/{review-BJGKwlYv.mjs → review-v7sh5GF4.mjs} +30 -125
  5. package/dist/chunks/{steering-CLhu8C7q.mjs → steering-CCNvngSH.mjs} +256 -65
  6. package/dist/chunks/{tail-B9Hw2AFB.mjs → tail-S04KEewi.mjs} +144 -56
  7. package/dist/gtd.bundle.mjs +259 -22
  8. package/dist/steering.mjs +2 -2
  9. package/dist/testkit.mjs +6 -6
  10. package/dist/web/main.css +1 -1
  11. package/dist/web/main.js +551 -66
  12. package/dist/workflow-kit.mjs +1 -1
  13. package/dist/workflows/cleanup.mjs +2 -2
  14. package/dist/workflows/feature.mjs +63 -175
  15. package/dist/workflows/fix.mjs +3 -3
  16. package/dist/workflows/review.mjs +3 -3
  17. package/dist/workflows/rollout.mjs +1 -1
  18. package/dist/workflows.mjs +603 -727
  19. package/package.json +1 -1
  20. package/skills/authoring/SKILL.md +3 -3
  21. package/src/cli/Cli.ts +5 -5
  22. package/src/edge/Edge.test.ts +1 -1
  23. package/src/steering/FORMATS.md +5 -1
  24. package/src/steering/SteeringFormats.test.ts +2 -2
  25. package/src/steering/contract.test.ts +1 -0
  26. package/src/steering/findings.test.ts +47 -0
  27. package/src/steering/findings.ts +350 -0
  28. package/src/steering/fixtures/findings/gate.md +34 -0
  29. package/src/steering/fixtures/findings/gate.read.json +87 -0
  30. package/src/steering/index.test.ts +2 -2
  31. package/src/steering/index.ts +4 -3
  32. package/src/steering/review.test.ts +1 -75
  33. package/src/steering/review.ts +1 -74
  34. package/src/workflow/compile.test.ts +1 -0
  35. package/src/workflows/feature/criteria-coverage.feature +1 -7
  36. package/src/workflows/feature/criteria.test.ts +1 -41
  37. package/src/workflows/feature/criteria.ts +2 -14
  38. package/src/workflows/feature/fast-path.feature +0 -1
  39. package/src/workflows/feature/feature.test.ts +1 -1
  40. package/src/workflows/feature/feature.ts +16 -25
  41. package/src/workflows/feature/flag-mode.feature +1 -1
  42. package/src/workflows/feature/lens-models.feature +0 -1
  43. package/src/workflows/feature/lens-review.feature +323 -172
  44. package/src/workflows/feature/naive-test.feature +258 -0
  45. package/src/workflows/feature/one-step-land.feature +0 -1
  46. package/src/workflows/feature/refactor-absorbs.feature +1 -8
  47. package/src/workflows/feature/refactor-first.feature +2 -11
  48. package/src/workflows/feature/refactor-rebuild.feature +4 -25
  49. package/src/workflows/feature/refactor-review.feature +33 -118
  50. package/src/workflows/feature/refactor.test.ts +0 -2
  51. package/src/workflows/feature/refactor.ts +0 -1
  52. package/src/workflows/feature/review-gate.feature +7 -24
  53. package/src/workflows/feature/reviewer-walkthrough.feature +16 -104
  54. package/src/workflows/feature/seam-rejection.feature +0 -1
  55. package/src/workflows/feature/seam.feature +0 -1
  56. package/src/workflows/feature/seam.test.ts +1 -2
  57. package/src/workflows/feature/seam.ts +56 -10
  58. package/src/workflows/feature/standards.feature +75 -35
  59. package/src/workflows/fix/fix-lens-origin.feature +20 -7
  60. package/src/workflows/fix/fix-quality.feature +102 -23
  61. package/src/workflows/review/review-door.feature +62 -59
  62. package/src/workflows/shared/learn.test.ts +0 -14
  63. package/src/workflows/shared/learn.ts +1 -6
  64. package/src/workflows/shared/lenses.ts +149 -43
  65. package/src/workflows/shared/options.ts +9 -1
  66. package/src/workflows/shared/prose.ts +0 -6
  67. package/src/workflows/shared/review.test.ts +27 -26
  68. package/src/workflows/shared/review.ts +29 -196
  69. package/src/workflows/shared/skills.test.ts +0 -4
  70. package/src/workflows/shared/skills.ts +0 -5
  71. package/src/workflows/shared/steps.ts +1 -1
  72. package/src/workflows/shared/tail.ts +18 -9
  73. package/src/workflows/shared/text.test.ts +125 -329
  74. package/src/workflows/shared/text.ts +173 -471
  75. package/src/workflows/shared/vars.ts +2 -3
  76. package/src/workflows/feature/hands-on-skip.feature +0 -316
  77. package/src/workflows/feature/prototype-rounds.feature +0 -156
  78. package/src/workflows/feature/prototype.feature +0 -428
  79. package/src/workflows/feature/prototype.test.ts +0 -43
  80. package/src/workflows/feature/prototype.ts +0 -198
  81. package/src/workflows/feature/review-answers.feature +0 -324
  82. package/src/workflows/feature/severity-budget.feature +0 -116
  83. package/src/workflows/feature/severity-sorted-review.feature +0 -198
@@ -3,16 +3,14 @@ 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
- And an environment variable "GTD_PROTOTYPEROUNDS" set to "0"
15
- And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
13
+ And an environment variable "GTD_QUALITYREVIEWS" set to ""
16
14
  And an environment variable "GTD_FLAGMODE" set to "false"
17
15
  And a file "src/calc.ts" with:
18
16
  """
@@ -53,30 +51,9 @@ Feature: a reviewer walks the human through the feature's code
53
51
  And step "implement.applying" runs its script
54
52
  And step "implement.health.check" changes nothing
55
53
  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
54
 
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:
55
+ Scenario: the review is the reviewer's walkthrough, as it wrote it
56
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
80
57
  """
81
58
  # Review: abc1234
82
59
 
@@ -87,47 +64,24 @@ Feature: a reviewer walks the human through the feature's code
87
64
  The new export.
88
65
 
89
66
  - [ ] ./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
67
  """
95
68
  When the process is driven
96
69
  Then the process rests at "build.review.await-review"
70
+ And the resting step's content does not contain "Tick exactly one"
97
71
  And ".gtd/REVIEW.md" contains:
98
72
  """
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
73
+ <!-- base: 0000000 -->
118
74
 
119
- ### Subtract
75
+ ## Subtract
120
76
 
121
77
  The new export.
122
78
 
123
79
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
124
80
  """
125
- And no commit body contains "build.review.composing"
126
81
  And the commit subjects end with:
127
82
  """
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
83
+ gtd(check): implement.closing → build.review.reviewing
84
+ gtd(agent): build.review.reviewing → build.review.await-review
131
85
  """
132
86
 
133
87
  Scenario: a chunk pointing at no code is refused
@@ -140,10 +94,6 @@ Feature: a reviewer walks the human through the feature's code
140
94
  ## Subtract
141
95
 
142
96
  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
97
  """
148
98
  Then driving the process is refused with "Subtract — points at no code"
149
99
 
@@ -158,26 +108,9 @@ Feature: a reviewer walks the human through the feature's code
158
108
 
159
109
  ### Subtract
160
110
 
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
111
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
179
112
  """
180
- Then driving the process is refused with "AC-1 ignores floating point — no chunk of its own"
113
+ Then driving the process is refused with "Walkthrough — write `## ` chunks only"
181
114
 
182
115
  Scenario: a standard conflict the reviewer writes itself is refused
183
116
  Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
@@ -189,31 +122,10 @@ Feature: a reviewer walks the human through the feature's code
189
122
  ## Standard conflict 0123abcd
190
123
 
191
124
  - [ ] ./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
125
  """
197
126
  Then driving the process is refused with "Standard conflict 0123abcd — gtd writes conflicts"
198
127
 
199
128
  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
129
  Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
218
130
  """
219
131
  # Review: abc1234
@@ -224,8 +136,8 @@ Feature: a reviewer walks the human through the feature's code
224
136
 
225
137
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
226
138
 
227
- ## AC-1 ignores floating point
139
+ ## Subtract
228
140
 
229
- - [ ] ./src/calc.ts#2-2 — Risk: no rounding
141
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
230
142
  """
231
- Then driving the process is refused with "no `Risk:` in a quality finding's chunk"
143
+ Then driving the process is refused with "Subtract — a second chunk with this title"
@@ -9,7 +9,6 @@ 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"
13
12
  And an environment variable "GTD_QUALITYREVIEWS" set to ""
14
13
  And an environment variable "GTD_FLAG_RISK_TIER" set to "0"
15
14
  And a file "src/calc.ts" with:
@@ -7,7 +7,6 @@ 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"
11
10
  And the gtd config ends with:
12
11
  """
13
12
  export const config = {
@@ -403,8 +403,7 @@ describe("implement", () => {
403
403
  lastOptions = undefined
404
404
  installContext(
405
405
  fixtureContext(
406
- // The hands-on test has its own scenarios.
407
- { vars: { prototypeRounds: "0" } },
406
+ {},
408
407
  {
409
408
  step: (request: StepRequest) => {
410
409
  requests.push(request)
@@ -3,6 +3,7 @@ import {
3
3
  agent,
4
4
  applyScript,
5
5
  changes,
6
+ changesSince,
6
7
  check,
7
8
  codeChanges,
8
9
  env,
@@ -14,6 +15,7 @@ import {
14
15
  read,
15
16
  refuse,
16
17
  removeScript,
18
+ restoreScript,
17
19
  run,
18
20
  scope,
19
21
  vars,
@@ -22,11 +24,10 @@ import {
22
24
  type DiffShapeResult,
23
25
  type KeptTip,
24
26
  } from "../../flows/index.js"
25
- import { coder, FEEDBACK, PROTOTYPE, REFACTOR_NOTE, REQUIREMENTS } from "../shared/steps.js"
27
+ import { coder, FEEDBACK, NAIVE_TEST, REFACTOR_NOTE, REQUIREMENTS } from "../shared/steps.js"
26
28
  import * as t from "../shared/text.js"
27
29
  import { defaults } from "../shared/vars.js"
28
30
  import { green } from "./green.js"
29
- import { prototypeTest } from "./prototype.js"
30
31
  import { criterionIds, requireCriteria, requireCriteriaFrozen } from "./criteria.js"
31
32
  import {
32
33
  COMMENT,
@@ -36,7 +37,7 @@ import {
36
37
  reviewedRefactor,
37
38
  } from "./refactor.js"
38
39
  import { isCode } from "../shared/review.js"
39
- import { flagModeOn } from "../shared/options.js"
40
+ import { flagModeOn, naiveTestOn } from "../shared/options.js"
40
41
  import type { RiskTier } from "./tier.js"
41
42
 
42
43
  /** Naive-pass retries after a `reject` or a red suite; the next one rests at `seam.steer`. */
@@ -53,7 +54,7 @@ export const judgeSeam = (tip: KeptTip): Promise<DiffShapeResult> =>
53
54
  exempt: tip.changes.filter((c) => c.status === "added").map((c) => c.path),
54
55
  })
55
56
 
56
- export const naivePass = (retry?: t.NaiveRetry): Promise<void> =>
57
+ export const naivePass = (retry?: t.NaiveRetry | t.NaiveTested): Promise<void> =>
57
58
  t.agentWithSkills("naive", t.naivePassPrompt(retry), {
58
59
  label: retry === undefined ? "Writing the naive pass" : "Rewriting the naive pass",
59
60
  keep: true,
@@ -226,9 +227,8 @@ export const implementing = (options: ImplementOptions): Promise<readonly string
226
227
  if (built) await build(options)
227
228
  else requireCriteriaFrozen(REQUIREMENTS)
228
229
  await green()
229
- await prototypeTest()
230
230
  const ids = criterionIds(read(REQUIREMENTS) ?? "")
231
- await run("closing", removeScript([REQUIREMENTS, REFACTOR_NOTE, PROTOTYPE]), {
231
+ await run("closing", removeScript([REQUIREMENTS, REFACTOR_NOTE]), {
232
232
  label: "Closing out the implementation",
233
233
  })
234
234
  return ids
@@ -277,7 +277,7 @@ const budget = (): ((next: t.NaiveRetry) => Promise<Verdict>) => {
277
277
  }
278
278
 
279
279
  interface Vetting {
280
- readonly again: ReturnType<typeof budget>
280
+ again: ReturnType<typeof budget>
281
281
  /** Set once a human overrules a test fault: the rule does not fit this change, so later passes skip it. */
282
282
  waived: boolean
283
283
  }
@@ -304,16 +304,62 @@ const ruled = async (tip: KeptTip, again: Vetting["again"]): Promise<Decision |
304
304
  return next.kind === "overruled" ? { reference: tip.hash, tip } : next
305
305
  }
306
306
 
307
+ /** Back to `before`: every code path, and the notes file. `.gtd/` edits (the requirements) stay. */
308
+ const untryScript = (before: string): string => {
309
+ const code = changesSince(before).filter((c) => isCode(c.path))
310
+ return restoreScript(
311
+ head(),
312
+ {
313
+ restore: code.filter((c) => c.status !== "added").map((c) => c.path),
314
+ remove: [...code.filter((c) => c.status === "added").map((c) => c.path), NAIVE_TEST],
315
+ },
316
+ before,
317
+ )
318
+ }
319
+
320
+ /**
321
+ * A person tries the green pass `tip` in the working tree. Resolves
322
+ * `undefined` on a clean landing (signed off), else what they sent back;
323
+ * either way the pass, their code edits and the notes file leave the tree.
324
+ */
325
+ const tried = async (tip: KeptTip): Promise<t.NaiveTested | undefined> => {
326
+ const before = head()
327
+ await run("applying", applyScript(tip.hash, FEEDBACK, t.naiveApplyFailure(tip.hash), [".gtd"]), {
328
+ label: "Applying the naive pass to try it",
329
+ })
330
+ await human("try", {
331
+ message: t.naiveTryMessage(flagModeOn()),
332
+ label: "Try the naive pass",
333
+ file: NAIVE_TEST,
334
+ acceptClean: true,
335
+ })
336
+ const landed = changes()
337
+ const edits = landed.some((c) => isCode(c.path)) ? head() : undefined
338
+ const notes = read(NAIVE_TEST)?.trim() || undefined
339
+ if (landed.some((c) => c.path === REQUIREMENTS)) requireCriteria(REQUIREMENTS)
340
+ await run("restoring", untryScript(before), { label: "Taking the naive pass out again" })
341
+ return landed.length === 0 ? undefined : { tested: tip.hash, notes, edits }
342
+ }
343
+
307
344
  const decide = (): Promise<Decision> =>
308
345
  scope("seam", async () => {
309
346
  const vetting: Vetting = { again: budget(), waived: false }
310
- let retry: t.NaiveRetry | undefined
347
+ let retry: t.NaiveRetry | t.NaiveTested | undefined
311
348
  for (;;) {
312
349
  await naivePass(retry)
313
350
  const tip = kept("naive")!
351
+ const verdict = await vetted(tip, vetting)
352
+ if (verdict === undefined && naiveTestOn()) {
353
+ const sentBack = await tried(tip)
354
+ if (sentBack !== undefined) {
355
+ // A person's feedback is no failed attempt: the next pass gets a full retry budget.
356
+ vetting.again = budget()
357
+ retry = sentBack
358
+ continue
359
+ }
360
+ }
314
361
  const outcome =
315
- (await vetted(tip, vetting)) ??
316
- (flagModeOn() ? await ruled(tip, vetting.again) : { reference: tip.hash, tip })
362
+ verdict ?? (flagModeOn() ? await ruled(tip, vetting.again) : { reference: tip.hash, tip })
317
363
  if (!("kind" in outcome)) return outcome
318
364
  retry = outcome.kind === "retry" ? outcome.retry : undefined
319
365
  }
@@ -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
@@ -11,8 +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"
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
  """
@@ -59,15 +58,6 @@ Feature: the review learns standards from the human's answers
59
58
  And step "implement.applying" runs its script
60
59
  And step "implement.health.check" changes nothing
61
60
  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
61
  And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
72
62
  """
73
63
  # Review: abc1234
@@ -78,29 +68,7 @@ Feature: the review learns standards from the human's answers
78
68
 
79
69
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
80
70
  """
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
71
  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
72
  And step "build.review.closing" runs its script
105
73
  And step "build.review.standards.recording" runs its script
106
74
  And step "build.review.standards.raising" runs its script
@@ -111,6 +79,18 @@ Feature: the review learns standards from the human's answers
111
79
  [{"id":"standard-1","answer":"yes","p":0.9}]
112
80
  """
113
81
  When the process is driven
82
+ And ".gtd/REVIEW.md" gets appended:
83
+ """
84
+ ## subtract has no class
85
+
86
+ Calculators read better as classes.
87
+
88
+ Tick exactly one:
89
+
90
+ - [ ] fix as suggested
91
+ - [ ] won't fix
92
+ - [ ] _your answer_
93
+ """
114
94
  And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
115
95
  And gtd lands
116
96
  And the process is driven
@@ -143,6 +123,18 @@ Feature: the review learns standards from the human's answers
143
123
  """
144
124
  And step "build.health.check" changes nothing
145
125
  When the process is driven
126
+ And ".gtd/REVIEW.md" gets appended:
127
+ """
128
+ ## subtract has no class
129
+
130
+ Calculators read better as classes.
131
+
132
+ Tick exactly one:
133
+
134
+ - [ ] fix as suggested
135
+ - [ ] won't fix
136
+ - [ ] _your answer_
137
+ """
146
138
  And the text "- [ ] _your answer_" in ".gtd/REVIEW.md" is replaced with "- [x] Calculators are plain functions."
147
139
  And gtd lands
148
140
  And the process is driven
@@ -162,6 +154,18 @@ Feature: the review learns standards from the human's answers
162
154
  [{"id":"standard-1","answer":"yes","p":0.6}]
163
155
  """
164
156
  When the process is driven
157
+ And ".gtd/REVIEW.md" gets appended:
158
+ """
159
+ ## subtract has no class
160
+
161
+ Calculators read better as classes.
162
+
163
+ Tick exactly one:
164
+
165
+ - [ ] fix as suggested
166
+ - [ ] won't fix
167
+ - [ ] _your answer_
168
+ """
165
169
  And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
166
170
  And gtd lands
167
171
  And the process is driven
@@ -210,6 +214,18 @@ Feature: the review learns standards from the human's answers
210
214
  [{"id":"answer-1","answer":"praise","p":0.9}]
211
215
  """
212
216
  When the process is driven
217
+ And ".gtd/REVIEW.md" gets appended:
218
+ """
219
+ ## subtract has no class
220
+
221
+ Calculators read better as classes.
222
+
223
+ Tick exactly one:
224
+
225
+ - [ ] fix as suggested
226
+ - [ ] won't fix
227
+ - [ ] _your answer_
228
+ """
213
229
  And the text "- [ ] _your answer_" in ".gtd/REVIEW.md" is replaced with "- [x] Calculators are plain functions."
214
230
  And gtd lands
215
231
  And the process is driven
@@ -267,6 +283,18 @@ Feature: the review learns standards from the human's answers
267
283
  [{"id":"standard-1","answer":"yes","p":0.9},{"id":"standard-1.contradicts-1","answer":"yes","p":0.8}]
268
284
  """
269
285
  When the process is driven
286
+ And ".gtd/REVIEW.md" gets appended:
287
+ """
288
+ ## subtract has no class
289
+
290
+ Calculators read better as classes.
291
+
292
+ Tick exactly one:
293
+
294
+ - [ ] fix as suggested
295
+ - [ ] won't fix
296
+ - [ ] _your answer_
297
+ """
270
298
  And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
271
299
  And gtd lands
272
300
  And the process is driven
@@ -303,6 +331,18 @@ Feature: the review learns standards from the human's answers
303
331
  [{"id":"standard-1","answer":"yes","p":0.9},{"id":"standard-1.contradicts-1","answer":"yes","p":0.8}]
304
332
  """
305
333
  When the process is driven
334
+ And ".gtd/REVIEW.md" gets appended:
335
+ """
336
+ ## subtract has no class
337
+
338
+ Calculators read better as classes.
339
+
340
+ Tick exactly one:
341
+
342
+ - [ ] fix as suggested
343
+ - [ ] won't fix
344
+ - [ ] _your answer_
345
+ """
306
346
  And the text "- [ ] won't fix" in ".gtd/REVIEW.md" is replaced with "- [x] won't fix"
307
347
  And gtd lands
308
348
  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
  """